blacklight 6.14.0 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (422) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.npmignore +23 -0
  4. data/.rubocop.yml +40 -16
  5. data/.rubocop_todo.yml +479 -375
  6. data/.solr_wrapper.yml +9 -2
  7. data/.travis.yml +27 -20
  8. data/Gemfile +3 -1
  9. data/README.md +22 -5
  10. data/Rakefile +3 -2
  11. data/VERSION +1 -1
  12. data/Vagrantfile +2 -0
  13. data/app/assets/images/blacklight/list.svg +1 -0
  14. data/app/assets/images/blacklight/search.svg +1 -0
  15. data/app/assets/javascripts/blacklight/blacklight.js +497 -57
  16. data/app/assets/stylesheets/blacklight/_balanced_list.scss +7 -12
  17. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +18 -15
  18. data/app/assets/stylesheets/blacklight/_bookmark.scss +1 -13
  19. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +27 -0
  20. data/app/assets/stylesheets/blacklight/_constraints.scss +17 -25
  21. data/app/assets/stylesheets/blacklight/_controls.scss +8 -16
  22. data/app/assets/stylesheets/blacklight/_facets.scss +64 -93
  23. data/app/assets/stylesheets/blacklight/_header.scss +35 -48
  24. data/app/assets/stylesheets/blacklight/_icons.scss +35 -0
  25. data/app/assets/stylesheets/blacklight/_layout.scss +0 -10
  26. data/app/assets/stylesheets/blacklight/_mixins.scss +15 -0
  27. data/app/assets/stylesheets/blacklight/_modal.scss +9 -17
  28. data/app/assets/stylesheets/blacklight/_pagination.scss +2 -17
  29. data/app/assets/stylesheets/blacklight/_search_form.scss +7 -0
  30. data/app/assets/stylesheets/blacklight/_search_history.scss +5 -13
  31. data/app/assets/stylesheets/blacklight/_search_results.scss +9 -8
  32. data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +1 -2
  33. data/app/assets/stylesheets/blacklight/blacklight.scss +1 -1
  34. data/app/builders/blacklight/action_builder.rb +57 -0
  35. data/app/controllers/bookmarks_controller.rb +2 -2
  36. data/app/controllers/catalog_controller.rb +2 -2
  37. data/app/controllers/concerns/blacklight/base.rb +0 -33
  38. data/app/controllers/concerns/blacklight/bookmarks.rb +36 -33
  39. data/app/controllers/concerns/blacklight/catalog.rb +266 -210
  40. data/app/controllers/concerns/blacklight/controller.rb +111 -126
  41. data/app/controllers/concerns/blacklight/default_component_configuration.rb +12 -43
  42. data/app/controllers/concerns/blacklight/facet.rb +3 -0
  43. data/app/controllers/concerns/blacklight/search_context.rb +16 -14
  44. data/app/controllers/concerns/blacklight/search_fields.rb +4 -14
  45. data/app/controllers/concerns/blacklight/search_history.rb +1 -6
  46. data/app/controllers/concerns/blacklight/token_based_user.rb +24 -9
  47. data/app/helpers/blacklight/blacklight_helper_behavior.rb +39 -119
  48. data/app/helpers/blacklight/catalog_helper_behavior.rb +94 -88
  49. data/app/helpers/blacklight/component_helper_behavior.rb +21 -19
  50. data/app/helpers/blacklight/configuration_helper_behavior.rb +30 -57
  51. data/app/helpers/blacklight/facets_helper_behavior.rb +55 -51
  52. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +9 -11
  53. data/app/helpers/blacklight/icon_helper_behavior.rb +18 -0
  54. data/app/helpers/blacklight/layout_helper_behavior.rb +3 -3
  55. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +8 -6
  56. data/app/helpers/blacklight/render_partials_helper_behavior.rb +195 -0
  57. data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +19 -11
  58. data/app/helpers/blacklight/suggest_helper_behavior.rb +1 -0
  59. data/app/helpers/blacklight/url_helper_behavior.rb +50 -41
  60. data/app/{assets/javascripts → javascript}/blacklight/autocomplete.js +3 -2
  61. data/app/javascript/blacklight/bookmark_toggle.js +25 -0
  62. data/app/javascript/blacklight/checkbox_submit.js +134 -0
  63. data/app/{assets/javascripts → javascript}/blacklight/collapsable.js +1 -1
  64. data/app/{assets/javascripts → javascript}/blacklight/core.js +10 -8
  65. data/app/{assets/javascripts → javascript}/blacklight/facet_load.js +6 -6
  66. data/app/{assets/javascripts/blacklight/ajax_modal.js → javascript/blacklight/modal.js} +62 -64
  67. data/app/{assets/javascripts → javascript}/blacklight/search_context.js +10 -3
  68. data/app/models/blacklight/facet_paginator.rb +3 -3
  69. data/app/models/blacklight/icon.rb +56 -0
  70. data/app/models/blacklight/solr/facet_paginator.rb +3 -3
  71. data/app/models/blacklight/suggest_search.rb +4 -15
  72. data/app/models/bookmark.rb +5 -10
  73. data/app/models/concerns/blacklight/configurable.rb +13 -13
  74. data/app/models/concerns/blacklight/document/active_model_shim.rb +13 -11
  75. data/app/models/concerns/blacklight/document/cache_key.rb +1 -1
  76. data/app/models/concerns/blacklight/document/dublin_core.rb +2 -2
  77. data/app/models/concerns/blacklight/document/email.rb +1 -1
  78. data/app/models/concerns/blacklight/document/extensions.rb +5 -5
  79. data/app/models/concerns/blacklight/document/semantic_fields.rb +9 -9
  80. data/app/models/concerns/blacklight/document/sms.rb +1 -1
  81. data/app/models/concerns/blacklight/document.rb +26 -40
  82. data/app/models/concerns/blacklight/solr/document.rb +8 -8
  83. data/app/models/concerns/blacklight/suggest/response.rb +5 -3
  84. data/app/models/concerns/blacklight/user.rb +7 -6
  85. data/app/models/record_mailer.rb +5 -6
  86. data/app/models/search.rb +5 -7
  87. data/app/presenters/blacklight/document_presenter.rb +25 -140
  88. data/app/presenters/blacklight/field_presenter.rb +7 -5
  89. data/app/presenters/blacklight/index_presenter.rb +41 -58
  90. data/app/presenters/blacklight/json_presenter.rb +10 -14
  91. data/app/presenters/blacklight/link_alternate_presenter.rb +3 -1
  92. data/app/presenters/blacklight/rendering/abstract_step.rb +7 -5
  93. data/app/presenters/blacklight/rendering/helper_method.rb +10 -8
  94. data/app/presenters/blacklight/rendering/join.rb +5 -3
  95. data/app/presenters/blacklight/rendering/link_to_facet.rb +23 -19
  96. data/app/presenters/blacklight/rendering/microdata.rb +6 -3
  97. data/app/presenters/blacklight/rendering/pipeline.rb +7 -5
  98. data/app/presenters/blacklight/rendering/terminator.rb +2 -0
  99. data/app/presenters/blacklight/search_bar_presenter.rb +39 -0
  100. data/app/presenters/blacklight/show_presenter.rb +26 -63
  101. data/app/presenters/blacklight/thumbnail_presenter.rb +74 -0
  102. data/app/services/blacklight/document_factory.rb +13 -0
  103. data/app/services/blacklight/field_retriever.rb +26 -24
  104. data/app/services/blacklight/search_service.rb +152 -0
  105. data/app/values/blacklight/types.rb +31 -0
  106. data/app/views/blacklight/nav/_bookmark.html.erb +2 -2
  107. data/app/views/blacklight/nav/_search_history.html.erb +1 -1
  108. data/app/views/bookmarks/_tools.html.erb +2 -2
  109. data/app/views/bookmarks/index.html.erb +12 -13
  110. data/app/views/catalog/_bookmark_control.html.erb +26 -10
  111. data/app/views/catalog/_citation.html.erb +4 -4
  112. data/app/views/catalog/_constraints.html.erb +6 -7
  113. data/app/views/catalog/_constraints_element.html.erb +6 -6
  114. data/app/views/catalog/_did_you_mean.html.erb +1 -1
  115. data/app/views/catalog/{_document_default.atom.builder → _document.atom.builder} +19 -18
  116. data/app/views/catalog/_document.html.erb +5 -3
  117. data/app/views/catalog/{_document_default.rss.builder → _document.rss.builder} +2 -0
  118. data/app/views/catalog/_document_action.html.erb +2 -1
  119. data/app/views/catalog/_email_form.html.erb +8 -4
  120. data/app/views/catalog/_facet_index_navigation.html.erb +5 -4
  121. data/app/views/catalog/_facet_layout.html.erb +6 -10
  122. data/app/views/catalog/_facet_limit.html.erb +3 -2
  123. data/app/views/catalog/_facet_pagination.html.erb +8 -8
  124. data/app/views/catalog/_facet_pivot.html.erb +2 -2
  125. data/app/views/catalog/_facets.html.erb +9 -12
  126. data/app/views/catalog/_field.json.jbuilder +10 -0
  127. data/app/views/catalog/{_group_default.html.erb → _group.html.erb} +1 -1
  128. data/app/views/catalog/_home_text.html.erb +32 -36
  129. data/app/views/catalog/_index.html.erb +10 -0
  130. data/app/views/catalog/{_index_header_default.html.erb → _index_header.html.erb} +3 -3
  131. data/app/views/catalog/_per_page_widget.html.erb +6 -7
  132. data/app/views/catalog/_previous_next_doc.html.erb +6 -14
  133. data/app/views/catalog/_results_pagination.html.erb +2 -2
  134. data/app/views/catalog/_search_form.html.erb +12 -8
  135. data/app/views/catalog/_search_header.html.erb +0 -3
  136. data/app/views/catalog/_search_results.html.erb +6 -2
  137. data/app/views/catalog/_show.html.erb +8 -0
  138. data/app/views/catalog/_show_main_content.html.erb +4 -4
  139. data/app/views/catalog/_show_more_like_this.html.erb +1 -1
  140. data/app/views/catalog/_show_sidebar.html.erb +3 -3
  141. data/app/views/catalog/_show_tools.html.erb +10 -12
  142. data/app/views/catalog/_sms_form.html.erb +8 -4
  143. data/app/views/catalog/_sort_and_per_page.html.erb +3 -3
  144. data/app/views/catalog/_sort_widget.html.erb +7 -7
  145. data/app/views/catalog/_thumbnail.html.erb +5 -0
  146. data/app/views/catalog/_view_type_group.html.erb +2 -2
  147. data/app/views/catalog/_zero_results.html.erb +1 -1
  148. data/app/views/catalog/citation.js.erb +4 -2
  149. data/app/views/catalog/email.html.erb +5 -3
  150. data/app/views/catalog/email_success.html.erb +12 -8
  151. data/app/views/catalog/facet.html.erb +10 -8
  152. data/app/views/catalog/facet.json.jbuilder +2 -0
  153. data/app/views/catalog/index.atom.builder +13 -16
  154. data/app/views/catalog/index.html.erb +9 -11
  155. data/app/views/catalog/index.json.jbuilder +84 -3
  156. data/app/views/catalog/index.rss.builder +7 -5
  157. data/app/views/catalog/opensearch.xml.builder +12 -10
  158. data/app/views/catalog/show.html.erb +11 -6
  159. data/app/views/catalog/show.json.jbuilder +21 -0
  160. data/app/views/catalog/sms.html.erb +3 -1
  161. data/app/views/catalog/sms_success.html.erb +12 -8
  162. data/app/views/kaminari/blacklight/_first_page.html.erb +2 -2
  163. data/app/views/kaminari/blacklight/_gap.html.erb +2 -2
  164. data/app/views/kaminari/blacklight/_last_page.html.erb +2 -2
  165. data/app/views/kaminari/blacklight/_next_page.html.erb +5 -5
  166. data/app/views/kaminari/blacklight/_page.html.erb +5 -3
  167. data/app/views/kaminari/blacklight/_prev_page.html.erb +4 -4
  168. data/app/views/kaminari/blacklight_compact/_paginator.html.erb +4 -4
  169. data/app/views/layouts/blacklight/base.html.erb +35 -0
  170. data/app/views/layouts/blacklight.html.erb +14 -41
  171. data/app/views/layouts/catalog_result.html.erb +11 -0
  172. data/app/views/search_history/index.html.erb +16 -21
  173. data/app/views/shared/_header_navbar.html.erb +8 -13
  174. data/app/views/shared/_modal.html.erb +6 -0
  175. data/app/views/shared/_user_util_links.html.erb +22 -0
  176. data/blacklight.gemspec +10 -11
  177. data/config/i18n-tasks.yml +17 -0
  178. data/config/locales/blacklight.de.yml +71 -82
  179. data/config/locales/blacklight.en.yml +15 -27
  180. data/config/locales/blacklight.es.yml +14 -26
  181. data/config/locales/blacklight.fr.yml +16 -33
  182. data/config/locales/blacklight.hu.yml +212 -0
  183. data/config/locales/blacklight.it.yml +15 -26
  184. data/config/locales/blacklight.nl.yml +212 -0
  185. data/config/locales/blacklight.pt-BR.yml +24 -29
  186. data/config/locales/blacklight.sq.yml +4 -28
  187. data/config/locales/blacklight.zh.yml +3 -25
  188. data/config/routes.rb +2 -10
  189. data/db/migrate/20140202020202_create_bookmarks.rb +0 -1
  190. data/db/migrate/20140320000000_add_polymorphic_type_to_bookmarks.rb +1 -1
  191. data/lib/blacklight/abstract_repository.rb +22 -10
  192. data/lib/blacklight/configuration/context.rb +12 -1
  193. data/lib/blacklight/configuration/facet_field.rb +16 -9
  194. data/lib/blacklight/configuration/field.rb +32 -3
  195. data/lib/blacklight/configuration/fields.rb +61 -58
  196. data/lib/blacklight/configuration/null_field.rb +2 -0
  197. data/lib/blacklight/configuration/search_field.rb +2 -2
  198. data/lib/blacklight/configuration/sort_field.rb +2 -2
  199. data/lib/blacklight/configuration/view_config.rb +4 -0
  200. data/lib/blacklight/configuration.rb +101 -88
  201. data/lib/blacklight/engine.rb +11 -7
  202. data/lib/blacklight/exceptions.rb +4 -7
  203. data/lib/blacklight/{utils.rb → nested_open_struct_with_hash_access.rb} +9 -81
  204. data/lib/blacklight/open_struct_with_hash_access.rb +49 -0
  205. data/lib/blacklight/parameters.rb +1 -1
  206. data/lib/blacklight/routes/exportable.rb +1 -3
  207. data/lib/blacklight/routes/searchable.rb +3 -3
  208. data/lib/blacklight/runtime_registry.rb +2 -0
  209. data/lib/blacklight/search_builder.rb +28 -35
  210. data/lib/blacklight/search_state.rb +10 -8
  211. data/lib/blacklight/solr/repository.rb +40 -6
  212. data/lib/blacklight/solr/request.rb +1 -1
  213. data/lib/blacklight/solr/response/facets.rb +29 -31
  214. data/lib/blacklight/solr/response/group.rb +3 -3
  215. data/lib/blacklight/solr/response/group_response.rb +1 -1
  216. data/lib/blacklight/solr/response/more_like_this.rb +2 -2
  217. data/lib/blacklight/solr/response/response.rb +2 -2
  218. data/lib/blacklight/solr/response/spelling.rb +4 -3
  219. data/lib/blacklight/solr/response.rb +29 -30
  220. data/lib/blacklight/solr/search_builder_behavior.rb +25 -29
  221. data/lib/blacklight/version.rb +1 -1
  222. data/lib/blacklight.rb +10 -8
  223. data/lib/generators/blacklight/assets_generator.rb +18 -12
  224. data/lib/generators/blacklight/controller_generator.rb +4 -5
  225. data/lib/generators/blacklight/document_generator.rb +1 -1
  226. data/lib/generators/blacklight/install_generator.rb +18 -28
  227. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  228. data/lib/generators/blacklight/{solr5_generator.rb → solr_generator.rb} +12 -6
  229. data/lib/generators/blacklight/templates/.solr_wrapper.yml +5 -0
  230. data/lib/generators/blacklight/templates/alternate_controller.rb +4 -4
  231. data/lib/generators/blacklight/templates/blacklight.scss +0 -2
  232. data/lib/generators/blacklight/templates/catalog_controller.rb +59 -49
  233. data/lib/generators/blacklight/templates/config/blacklight.yml +1 -13
  234. data/lib/generators/blacklight/templates/solr/conf/schema.xml +388 -0
  235. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +195 -0
  236. data/lib/generators/blacklight/test_support_generator.rb +10 -10
  237. data/lib/generators/blacklight/user_generator.rb +5 -6
  238. data/lib/railties/blacklight.rake +17 -21
  239. data/package-lock.json +2195 -0
  240. data/package.json +29 -0
  241. data/spec/controllers/alternate_controller_spec.rb +5 -4
  242. data/spec/controllers/application_controller_spec.rb +1 -5
  243. data/spec/controllers/blacklight/base_spec.rb +6 -3
  244. data/spec/controllers/blacklight/catalog/component_configuration_spec.rb +11 -7
  245. data/spec/controllers/blacklight/facet_spec.rb +1 -2
  246. data/spec/controllers/blacklight/search_fields_spec.rb +25 -34
  247. data/spec/controllers/bookmarks_controller_spec.rb +46 -11
  248. data/spec/controllers/catalog_controller_spec.rb +334 -161
  249. data/spec/controllers/search_history_controller_spec.rb +6 -6
  250. data/spec/features/alternate_controller_spec.rb +4 -4
  251. data/spec/features/autocomplete_spec.rb +4 -2
  252. data/spec/features/bookmarks_spec.rb +10 -10
  253. data/spec/features/did_you_mean_spec.rb +7 -12
  254. data/spec/features/facets_spec.rb +29 -17
  255. data/spec/features/record_view_spec.rb +12 -18
  256. data/spec/features/search_context_spec.rb +6 -7
  257. data/spec/features/search_crawler_spec.rb +3 -5
  258. data/spec/features/search_filters_spec.rb +80 -80
  259. data/spec/features/search_formats_spec.rb +1 -1
  260. data/spec/features/search_history_spec.rb +6 -29
  261. data/spec/features/search_pagination_spec.rb +4 -2
  262. data/spec/features/search_results_spec.rb +14 -12
  263. data/spec/features/search_sort_spec.rb +2 -2
  264. data/spec/features/search_spec.rb +8 -9
  265. data/spec/features/sitelinks_search_box.rb +4 -4
  266. data/{solr → spec/fixtures}/sample_solr_documents.yml +688 -688
  267. data/spec/helpers/{configuration_helper_spec.rb → blacklight/configuration_helper_behavior_spec.rb} +97 -92
  268. data/spec/helpers/{facets_helper_spec.rb → blacklight/facets_helper_behavior_spec.rb} +72 -67
  269. data/spec/helpers/{hash_as_hidden_fields_spec.rb → blacklight/hash_as_hidden_fields_behavior_spec.rb} +2 -2
  270. data/spec/helpers/blacklight/icon_helper_behavior_spec.rb +10 -0
  271. data/spec/helpers/{layout_helper_spec.rb → blacklight/layout_helper_behavior_spec.rb} +5 -5
  272. data/spec/helpers/{render_constraints_helper_spec.rb → blacklight/render_constraints_helper_behavior_spec.rb} +10 -6
  273. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +92 -0
  274. data/spec/helpers/{search_history_constraints_helper_spec.rb → blacklight/search_history_constraints_helper_behavior_spec.rb} +29 -30
  275. data/spec/helpers/{suggest_helper_spec.rb → blacklight/suggest_helper_behavior_spec.rb} +9 -2
  276. data/spec/helpers/{url_helper_spec.rb → blacklight/url_helper_behavior_spec.rb} +56 -54
  277. data/spec/helpers/blacklight_helper_spec.rb +65 -150
  278. data/spec/helpers/catalog_helper_spec.rb +80 -96
  279. data/spec/i18n_spec.rb +18 -0
  280. data/spec/integration/generators/blacklight/{solr5_generator_spec.rb → solr_generator_spec.rb} +21 -13
  281. data/spec/lib/blacklight/configuration/facet_field_spec.rb +13 -0
  282. data/spec/lib/blacklight/configuration/field_spec.rb +15 -0
  283. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +17 -0
  284. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +148 -0
  285. data/spec/lib/blacklight/parameters_spec.rb +4 -2
  286. data/spec/lib/blacklight/search_state_spec.rb +53 -36
  287. data/spec/lib/blacklight_spec.rb +14 -15
  288. data/spec/lib/tasks/blacklight_task_spec.rb +4 -6
  289. data/spec/models/blacklight/configurable_spec.rb +24 -27
  290. data/spec/models/blacklight/configuration/context_spec.rb +9 -10
  291. data/spec/models/blacklight/configuration_spec.rb +248 -223
  292. data/spec/models/blacklight/document/active_model_shim_spec.rb +15 -6
  293. data/spec/models/blacklight/document/cache_key_spec.rb +9 -2
  294. data/spec/models/blacklight/document/dublin_core_spec.rb +17 -20
  295. data/spec/models/blacklight/document/email_spec.rb +10 -10
  296. data/spec/models/blacklight/document/sms_spec.rb +10 -10
  297. data/spec/models/blacklight/document_spec.rb +10 -22
  298. data/spec/models/blacklight/facet_paginator_spec.rb +40 -30
  299. data/spec/models/blacklight/icon_spec.rb +44 -0
  300. data/spec/models/blacklight/search_builder_spec.rb +41 -26
  301. data/spec/models/blacklight/solr/document_spec.rb +224 -216
  302. data/spec/models/blacklight/solr/facet_paginator_spec.rb +6 -4
  303. data/spec/models/blacklight/solr/repository_spec.rb +61 -46
  304. data/spec/models/blacklight/solr/request_spec.rb +17 -18
  305. data/spec/models/blacklight/solr/response/facets_spec.rb +58 -58
  306. data/spec/models/blacklight/solr/response/group_response_spec.rb +16 -22
  307. data/spec/models/blacklight/solr/response/group_spec.rb +18 -25
  308. data/spec/models/blacklight/solr/response_spec.rb +56 -55
  309. data/spec/models/blacklight/solr/search_builder_spec.rb +150 -164
  310. data/spec/models/blacklight/suggest/response_spec.rb +6 -4
  311. data/spec/models/blacklight/suggest_search_spec.rb +9 -16
  312. data/spec/models/blacklight/user_spec.rb +9 -11
  313. data/spec/models/bookmark_spec.rb +7 -6
  314. data/spec/models/record_mailer_spec.rb +23 -21
  315. data/spec/models/search_spec.rb +19 -18
  316. data/spec/models/solr_document_spec.rb +33 -5
  317. data/spec/presenters/blacklight/document_presenter_spec.rb +86 -0
  318. data/spec/presenters/blacklight/index_presenter_spec.rb +186 -0
  319. data/spec/presenters/blacklight/json_presenter_spec.rb +59 -0
  320. data/spec/presenters/blacklight/link_alternate_presenter_spec.rb +3 -0
  321. data/spec/presenters/blacklight/search_bar_presenter_spec.rb +79 -0
  322. data/spec/presenters/blacklight/show_presenter_spec.rb +333 -0
  323. data/spec/presenters/pipeline_spec.rb +18 -11
  324. data/spec/presenters/thumbnail_presenter_spec.rb +174 -0
  325. data/spec/routing/catalog_routing_spec.rb +13 -15
  326. data/spec/services/blacklight/search_service_spec.rb +488 -0
  327. data/spec/spec_helper.rb +20 -19
  328. data/spec/support/features/session_helpers.rb +4 -4
  329. data/spec/support/features.rb +1 -1
  330. data/spec/test_app_templates/Gemfile.extra +2 -4
  331. data/spec/test_app_templates/lib/generators/test_app_generator.rb +12 -13
  332. data/spec/views/catalog/_constraints.html.erb_spec.rb +3 -6
  333. data/spec/views/catalog/_constraints_element.html.erb_spec.rb +17 -13
  334. data/spec/views/catalog/_document.html.erb_spec.rb +11 -11
  335. data/spec/views/catalog/_document_list.html.erb_spec.rb +2 -1
  336. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +5 -5
  337. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +6 -6
  338. data/spec/views/catalog/_facets.html.erb_spec.rb +10 -12
  339. data/spec/views/catalog/{_index_default.erb_spec.rb → _index.html.erb_spec.rb} +14 -15
  340. data/spec/views/catalog/{_index_header_default.html.erb_spec.rb → _index_header.html.erb_spec.rb} +6 -9
  341. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +7 -30
  342. data/spec/views/catalog/_search_header.erb_spec.rb +1 -3
  343. data/spec/views/catalog/{_show_default.erb_spec.rb → _show.html.erb_spec.rb} +13 -14
  344. data/spec/views/catalog/_show_sidebar.erb_spec.rb +6 -9
  345. data/spec/views/catalog/_show_tools.html.erb_spec.rb +5 -5
  346. data/spec/views/catalog/_sort_and_per_page.html.erb_spec.rb +1 -2
  347. data/spec/views/catalog/_sort_widget.html.erb_spec.rb +3 -1
  348. data/spec/views/catalog/{_thumbnail_default.erb_spec.rb → _thumbnail.html.erb_spec.rb} +7 -9
  349. data/spec/views/catalog/_view_type_group.html.erb_spec.rb +12 -10
  350. data/spec/views/catalog/email_success.html.erb_spec.rb +8 -0
  351. data/spec/views/catalog/facet.html.erb_spec.rb +4 -3
  352. data/spec/views/catalog/facet.json.jbuilder_spec.rb +3 -2
  353. data/spec/views/catalog/index.atom.builder_spec.rb +11 -6
  354. data/spec/views/catalog/index.html.erb_spec.rb +6 -8
  355. data/spec/views/catalog/index.json.jbuilder_spec.rb +119 -26
  356. data/spec/views/catalog/opensearch.xml.builder_spec.rb +1 -1
  357. data/spec/views/catalog/show.html.erb_spec.rb +8 -8
  358. data/spec/views/catalog/show.json.jbuilder_spec.rb +40 -0
  359. data/spec/views/catalog/sms_success.html.erb_spec.rb +8 -0
  360. data/spec/views/{_user_util_links.html.erb_spec.rb → shared/_user_util_links.html.erb_spec.rb} +4 -7
  361. data/tasks/blacklight.rake +10 -8
  362. data/template.demo.rb +3 -11
  363. metadata +188 -189
  364. data/app/assets/javascripts/blacklight/autofocus.js +0 -16
  365. data/app/assets/javascripts/blacklight/bookmark_toggle.js +0 -23
  366. data/app/assets/javascripts/blacklight/checkbox_submit.js +0 -135
  367. data/app/controllers/concerns/blacklight/request_builders.rb +0 -77
  368. data/app/controllers/concerns/blacklight/saved_searches.rb +0 -70
  369. data/app/controllers/concerns/blacklight/search_helper.rb +0 -155
  370. data/app/controllers/concerns/blacklight/suggest.rb +0 -25
  371. data/app/controllers/saved_searches_controller.rb +0 -4
  372. data/app/controllers/suggest_controller.rb +0 -4
  373. data/app/helpers/blacklight/deprecated_url_helper_behavior.rb +0 -57
  374. data/app/helpers/blacklight/render_partials_helper.rb +0 -205
  375. data/app/helpers/blacklight_configuration_helper.rb +0 -4
  376. data/app/helpers/blacklight_url_helper.rb +0 -4
  377. data/app/helpers/component_helper.rb +0 -4
  378. data/app/helpers/facets_helper.rb +0 -4
  379. data/app/helpers/hash_as_hidden_fields_helper.rb +0 -4
  380. data/app/helpers/layout_helper.rb +0 -4
  381. data/app/helpers/render_constraints_helper.rb +0 -4
  382. data/app/helpers/search_history_constraints_helper.rb +0 -4
  383. data/app/helpers/suggest_helper.rb +0 -4
  384. data/app/models/concerns/blacklight/solr/document/more_like_this.rb +0 -6
  385. data/app/views/_user_util_links.html.erb +0 -26
  386. data/app/views/blacklight/nav/_saved_searches.html.erb +0 -1
  387. data/app/views/catalog/_index_default.html.erb +0 -12
  388. data/app/views/catalog/_show_default.html.erb +0 -10
  389. data/app/views/catalog/_thumbnail_default.html.erb +0 -5
  390. data/app/views/saved_searches/index.html.erb +0 -32
  391. data/app/views/shared/_ajax_modal.html.erb +0 -6
  392. data/lib/generators/blacklight/solr4_generator.rb +0 -31
  393. data/lib/generators/blacklight/templates/config/jetty.yml +0 -13
  394. data/solr/conf/schema.xml +0 -629
  395. data/solr/conf/solrconfig.xml +0 -411
  396. data/spec/controllers/blacklight/search_helper_spec.rb +0 -470
  397. data/spec/controllers/saved_searches_controller_spec.rb +0 -32
  398. data/spec/controllers/suggest_controller_spec.rb +0 -17
  399. data/spec/features/saved_searches_spec.rb +0 -47
  400. data/spec/helpers/deprecated_url_helper_behavior_spec.rb +0 -101
  401. data/spec/lib/blacklight/utils_spec.rb +0 -167
  402. data/spec/models/blacklight/solr/document/more_like_this_spec.rb +0 -18
  403. data/spec/presenters/document_presenter_spec.rb +0 -438
  404. data/spec/presenters/index_presenter_spec.rb +0 -173
  405. data/spec/presenters/show_presenter_spec.rb +0 -313
  406. data/spec/support/backport_test.rb +0 -14
  407. /data/app/views/catalog/{_show_header_default.html.erb → _show_header.html.erb} +0 -0
  408. /data/app/views/{_flash_msg.html.erb → shared/_flash_msg.html.erb} +0 -0
  409. /data/{solr → lib/generators/blacklight/templates/solr}/conf/_rest_managed.json +0 -0
  410. /data/{solr → lib/generators/blacklight/templates/solr}/conf/admin-extra.html +0 -0
  411. /data/{solr → lib/generators/blacklight/templates/solr}/conf/elevate.xml +0 -0
  412. /data/{solr → lib/generators/blacklight/templates/solr}/conf/mapping-ISOLatin1Accent.txt +0 -0
  413. /data/{solr → lib/generators/blacklight/templates/solr}/conf/protwords.txt +0 -0
  414. /data/{solr → lib/generators/blacklight/templates/solr}/conf/scripts.conf +0 -0
  415. /data/{solr → lib/generators/blacklight/templates/solr}/conf/spellings.txt +0 -0
  416. /data/{solr → lib/generators/blacklight/templates/solr}/conf/stopwords.txt +0 -0
  417. /data/{solr → lib/generators/blacklight/templates/solr}/conf/stopwords_en.txt +0 -0
  418. /data/{solr → lib/generators/blacklight/templates/solr}/conf/synonyms.txt +0 -0
  419. /data/{solr → lib/generators/blacklight/templates/solr}/conf/xslt/example.xsl +0 -0
  420. /data/{solr → lib/generators/blacklight/templates/solr}/conf/xslt/example_atom.xsl +0 -0
  421. /data/{solr → lib/generators/blacklight/templates/solr}/conf/xslt/example_rss.xsl +0 -0
  422. /data/{solr → lib/generators/blacklight/templates/solr}/conf/xslt/luke.xsl +0 -0
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
- describe CatalogController do
2
+
3
+ RSpec.describe CatalogController, api: true do
3
4
  let(:doc_id) { '2007020969' }
4
5
  let(:mock_response) { instance_double(Blacklight::Solr::Response) }
5
- let(:mock_document) { instance_double(SolrDocument) }
6
+ let(:mock_document) { instance_double(SolrDocument, export_formats: {}) }
7
+ let(:search_service) { instance_double(Blacklight::SearchService) }
6
8
 
7
9
  describe "index action" do
8
10
  context "with format :html" do
@@ -23,63 +25,67 @@ describe CatalogController do
23
25
  end
24
26
 
25
27
  # check each user manipulated parameter
26
- it "has docs and facets for query with results", :integration => true do
28
+ it "has docs and facets for query with results", integration: true do
27
29
  get :index, params: { q: user_query }
28
- expect(assigns(:response).docs).to_not be_empty
30
+ expect(assigns(:response).docs).not_to be_empty
29
31
  assert_facets_have_values(assigns(:response).aggregations)
30
32
  end
31
- it "has docs and facets for existing facet value", :integration => true do
32
- get :index, params: { f: {"format" => 'Book'} }
33
- expect(assigns(:response).docs).to_not be_empty
33
+ it "has docs and facets for existing facet value", integration: true do
34
+ get :index, params: { f: { "format" => 'Book' } }
35
+ expect(assigns(:response).docs).not_to be_empty
34
36
  assert_facets_have_values(assigns(:response).aggregations)
35
37
  end
36
- it "has docs and facets for non-default results per page", :integration => true do
38
+ it "has docs and facets for non-default results per page", integration: true do
37
39
  num_per_page = 7
38
40
  get :index, params: { per_page: num_per_page }
39
41
  expect(assigns(:response).docs).to have(num_per_page).items
40
42
  assert_facets_have_values(assigns(:response).aggregations)
41
43
  end
42
44
 
43
- it "has docs and facets for second page", :integration => true do
45
+ it "has docs and facets for second page", integration: true do
44
46
  page = 2
45
47
  get :index, params: { page: page }
46
- expect(assigns(:response).docs).to_not be_empty
47
- expect(assigns(:response).params[:start].to_i).to eq (page-1) * controller.blacklight_config[:default_solr_params][:rows]
48
+ expect(assigns(:response).docs).not_to be_empty
49
+ expect(assigns(:response).params[:start].to_i).to eq (page - 1) * controller.blacklight_config[:default_solr_params][:rows]
48
50
  assert_facets_have_values(assigns(:response).aggregations)
49
51
  end
50
52
 
51
- it "has no docs or facet values for query without results", :integration => true do
53
+ it "has no docs or facet values for query without results", integration: true do
52
54
  get :index, params: { q: 'sadfdsafasdfsadfsadfsadf' } # query for no results
53
55
  expect(assigns(:response).docs).to be_empty
54
- assigns(:response).aggregations.each do |key, facet|
56
+ assigns(:response).aggregations.each do |_key, facet|
55
57
  expect(facet.items).to be_empty
56
58
  end
57
59
  end
58
60
 
59
- it "shows 0 results when the user asks for an invalid value to a custom facet query", :integration => true do
61
+ it "shows 0 results when the user asks for an invalid value to a custom facet query", integration: true do
60
62
  get :index, params: { f: { example_query_facet_field: 'bogus' } } # bogus custom facet value
61
63
  expect(assigns(:response).docs).to be_empty
62
64
  end
63
65
 
64
- it "returns results (possibly 0) when the user asks for a valid value to a custom facet query", :integration => true do
66
+ it "returns results (possibly 0) when the user asks for a valid value to a custom facet query", integration: true do
65
67
  get :index, params: { f: { example_query_facet_field: 'years_10' } } # valid custom facet value with some results
66
- expect(assigns(:response).docs).to_not be_empty
67
- get :index, params: { f: {example_query_facet_field: 'years_5' } } # valid custom facet value with NO results
68
+ expect(assigns(:response).docs).not_to be_empty
69
+ end
70
+
71
+ it "returns no results when the users asks for a value that doesn't match any" do
72
+ get :index, params: { f: { example_query_facet_field: 'years_5' } } # valid custom facet value with NO results
68
73
  expect(assigns(:response).docs).to be_empty
69
74
  end
70
75
 
71
- it "has a spelling suggestion for an appropriately poor query", :integration => true do
76
+ it "has a spelling suggestion for an appropriately poor query", integration: true do
72
77
  get :index, params: { q: 'boo' }
73
- expect(assigns(:response).spelling.words).to_not be_nil
78
+ expect(assigns(:response).spelling.words).not_to be_nil
74
79
  end
75
80
 
76
81
  describe "session" do
77
82
  before do
78
83
  allow(controller).to receive(:search_results)
79
84
  end
85
+
80
86
  it "includes search hash with key :q" do
81
87
  get :index, params: { q: user_query }
82
- expect(session[:search]).to_not be_nil
88
+ expect(session[:search]).not_to be_nil
83
89
  expect(session[:search].keys).to include 'id'
84
90
  search = Search.find(session[:search]['id'])
85
91
  expect(search.query_params['q']).to eq user_query
@@ -88,11 +94,11 @@ describe CatalogController do
88
94
 
89
95
  # check with no user manipulation
90
96
  describe "for default query" do
91
- it "gets documents when no query", :integration => true do
97
+ it "gets documents when no query", integration: true do
92
98
  get :index
93
- expect(assigns(:response).docs).to_not be_empty
99
+ expect(assigns(:response).docs).not_to be_empty
94
100
  end
95
- it "gets facets when no query", :integration => true do
101
+ it "gets facets when no query", integration: true do
96
102
  get :index
97
103
  assert_facets_have_values(assigns(:response).aggregations)
98
104
  end
@@ -105,16 +111,16 @@ describe CatalogController do
105
111
  end
106
112
 
107
113
  # NOTE: status code is always 200 in isolation mode ...
108
- it "HTTP status code for GET should be 200", :integration => true do
114
+ it "HTTP status code for GET should be 200", integration: true do
109
115
  get :index
110
- expect(response).to be_success
116
+ expect(response).to be_successful
111
117
  end
112
118
  end
113
119
 
114
120
  describe "with format :rss" do
115
- it "gets the feed", :integration => true do
121
+ it "gets the feed", integration: true do
116
122
  get :index, params: { format: 'rss' }
117
- expect(response).to be_success
123
+ expect(response).to be_successful
118
124
  end
119
125
  end
120
126
 
@@ -122,12 +128,14 @@ describe CatalogController do
122
128
  render_views
123
129
  before do
124
130
  get :index, params: { format: 'json' }
125
- expect(response).to be_success
131
+ expect(response).to be_successful
126
132
  end
127
- let(:json) { JSON.parse(response.body)['response'] }
128
- let(:pages) { json["pages"] }
129
- let(:docs) { json["docs"] }
130
- let(:facets) { json["facets"] }
133
+
134
+ let(:json) { JSON.parse(response.body) }
135
+ let(:pages) { json['meta']['pages'] }
136
+ let(:docs) { json['data'] }
137
+ let(:facets) { json['included'].select { |x| x['type'] == 'facet' } }
138
+ let(:search_fields) { json['included'].select { |x| x['type'] == 'search_field' } }
131
139
 
132
140
  it "gets the pages" do
133
141
  expect(pages["total_count"]).to eq 30
@@ -137,22 +145,35 @@ describe CatalogController do
137
145
 
138
146
  it "gets the documents" do
139
147
  expect(docs).to have(10).documents
140
- expect(docs.first.keys).to match_array(["published_display", "author_display", "lc_callnum_display", "pub_date", "subtitle_display", "format", "material_type_display", "title_display", "id", "subject_topic_facet", "language_facet", "score"])
148
+ expect(docs.first['attributes'].keys).to match_array(
149
+ %w[author_tsim format language_ssim lc_callnum_ssim published_ssim title_tsim]
150
+ )
151
+ expect(docs.first['links']['self']).to eq solr_document_url(id: docs.first['id'])
141
152
  end
142
153
 
143
154
  it "gets the facets" do
144
155
  expect(facets).to have(9).facets
145
- expect(facets.first).to eq({"name"=>"format", "label" => "Format", "items"=>[{"value"=>"Book", "hits"=>30, "label"=>"Book"}]})
156
+
157
+ format = facets.find { |x| x['id'] == 'format' }
158
+
159
+ expect(format['attributes']['items'].map { |x| x['attributes'] }).to match_array([{ "value" => "Book", "hits" => 30, "label" => "Book" }])
160
+ expect(format['links']['self']).to eq facet_catalog_url(format: :json, id: 'format')
161
+ expect(format['attributes']['items'].first['links']['self']).to eq search_catalog_url(format: :json, f: { format: ['Book'] })
162
+ end
163
+
164
+ it "gets the search fields" do
165
+ expect(search_fields).to have(4).fields
166
+ expect(search_fields.map { |x| x['id'] }).to match_array %w[all_fields author subject title]
167
+ expect(search_fields.first['links']['self']).to eq search_catalog_url(format: :json, search_field: 'all_fields')
146
168
  end
147
169
 
148
170
  describe "facets" do
149
- let(:query_facet_items) { facets.last['items'] }
150
- let(:regular_facet_items) { facets.first['items'] }
171
+ let(:query_facet) { facets.find { |x| x['id'] == 'example_query_facet_field' } }
172
+ let(:query_facet_items) { query_facet['attributes']['items'].map { |x| x['attributes'] } }
173
+
151
174
  it "has items with labels and values" do
152
175
  expect(query_facet_items.first['label']).to eq 'within 10 Years'
153
176
  expect(query_facet_items.first['value']).to eq 'years_10'
154
- expect(regular_facet_items.first['label']).to eq "Book"
155
- expect(regular_facet_items.first['value']).to eq "Book"
156
177
  end
157
178
  end
158
179
  end
@@ -160,7 +181,7 @@ describe CatalogController do
160
181
  describe "with additional formats from configuration" do
161
182
  let(:blacklight_config) { Blacklight::Configuration.new }
162
183
 
163
- before :each do
184
+ before do
164
185
  allow(controller).to receive_messages blacklight_config: blacklight_config
165
186
  allow(controller).to receive_messages search_results: [double, double]
166
187
  end
@@ -184,7 +205,7 @@ describe CatalogController do
184
205
  end
185
206
 
186
207
  it "evaluates a proc" do
187
- blacklight_config.index.respond_to.yaml = lambda { render plain: "" }
208
+ blacklight_config.index.respond_to.yaml = -> { render plain: "" }
188
209
  get :index, params: { format: 'yaml' }
189
210
  expect(response.body).to be_empty
190
211
  end
@@ -235,90 +256,146 @@ describe CatalogController do
235
256
  put :track, params: { id: doc_id, counter: 3, redirect: 'http://localhost:3000/xyz' }
236
257
  assert_redirected_to("/xyz")
237
258
  end
259
+
260
+ it "keeps querystring on redirect" do
261
+ put :track, params: { id: doc_id, counter: 3, redirect: 'http://localhost:3000/xyz?locale=pt-BR' }
262
+ assert_redirected_to("/xyz?locale=pt-BR")
263
+ end
264
+ end
265
+
266
+ describe '#raw' do
267
+ context 'when disabled' do
268
+ it "returns 404" do
269
+ expect { get :raw, params: { id: doc_id, format: 'json' } }.to raise_error ActionController::RoutingError
270
+ end
271
+ end
272
+
273
+ context 'when enabled' do
274
+ before do
275
+ allow(controller.blacklight_config.raw_endpoint).to receive(:enabled).and_return(true)
276
+ end
277
+
278
+ it "gets the raw solr document" do
279
+ get :raw, params: { id: doc_id, format: 'json' }
280
+ expect(response).to be_successful
281
+ json = JSON.parse response.body
282
+ expect(json.keys).to match_array(
283
+ %w[id _version_ author_addl_tsim author_tsim format isbn_ssim
284
+ language_ssim lc_1letter_ssim lc_alpha_ssim lc_b4cutter_ssim
285
+ lc_callnum_ssim marc_ss material_type_ssim pub_date_ssim
286
+ published_ssim subject_addl_ssim subject_geo_ssim subject_ssim
287
+ subject_tsim subtitle_tsim timestamp title_addl_tsim title_tsim
288
+ url_suppl_ssim]
289
+ )
290
+ end
291
+ end
238
292
  end
239
293
 
240
294
  # SHOW ACTION
241
295
  describe "show action" do
242
296
  describe "with format :html" do
243
- it "gets document", :integration => true do
297
+ it "gets document", integration: true do
244
298
  get :show, params: { id: doc_id }
245
- expect(assigns[:document]).to_not be_nil
299
+ expect(assigns[:document]).not_to be_nil
246
300
  end
247
301
  end
248
302
 
249
303
  describe "with format :json" do
304
+ render_views
250
305
  it "gets the feed" do
251
306
  get :show, params: { id: doc_id, format: 'json' }
252
- expect(response).to be_success
307
+ expect(response).to be_successful
253
308
  json = JSON.parse response.body
254
- expect(json["response"]["document"].keys).to match_array(["author_t", "opensearch_display", "marc_display", "published_display", "author_display", "lc_callnum_display", "title_t", "pub_date", "pub_date_sort", "subtitle_display", "format", "url_suppl_display", "material_type_display", "title_display", "subject_addl_t", "subject_t", "isbn_t", "id", "title_addl_t", "subject_geo_facet", "subject_topic_facet", "author_addl_t", "language_facet", "subtitle_t", "timestamp"])
309
+ expect(json["data"]["attributes"].keys).to match_array(
310
+ %w[author_tsim format isbn_ssim language_ssim lc_callnum_ssim
311
+ published_ssim subtitle_tsim title_tsim url_suppl_ssim]
312
+ )
255
313
  end
256
314
  end
257
315
 
258
316
  describe "previous/next documents" do
259
- let(:search_session) { { :id => current_search.id } }
260
- let(:current_search) { Search.create(:query_params => { :q => ""}) }
317
+ let(:search_session) { { id: current_search.id } }
318
+ let(:current_search) { Search.create(query_params: { q: "" }) }
319
+
261
320
  before do
262
- allow(mock_document).to receive_messages(:export_formats => {})
263
- allow(controller).to receive_messages(
264
- fetch: [mock_response, mock_document],
265
- get_previous_and_next_documents_for_search: [double(:total => 5), [double("a"), mock_document, double("b")]],
266
- current_search_session: current_search
267
- )
321
+ allow(mock_document).to receive_messages(export_formats: {})
322
+ allow(controller).to receive(:search_service).and_return(search_service)
323
+ expect(search_service).to receive(:fetch).and_return([mock_response, mock_document])
324
+ allow(controller).to receive(:current_search_session).and_return(current_search)
268
325
  end
269
- it "sets previous document if counter present in session" do
270
- session[:search] = search_session.merge('counter' => 2)
271
- get :show, params: { id: doc_id }
272
- expect(assigns[:previous_document]).to_not be_nil
326
+
327
+ context 'if counter is present in session' do
328
+ before do
329
+ session[:search] = search_session.merge('counter' => 2)
330
+ end
331
+
332
+ context 'and no exception is raised' do
333
+ before do
334
+ expect(search_service).to receive(:previous_and_next_documents_for_search)
335
+ .and_return([double(total: 5), [double("a"), mock_document, double("b")]])
336
+ end
337
+
338
+ it "sets previous document" do
339
+ get :show, params: { id: doc_id }
340
+ expect(assigns[:search_context][:prev]).not_to be_nil
341
+ end
342
+
343
+ it "sets next document" do
344
+ get :show, params: { id: doc_id }
345
+ expect(assigns[:search_context][:next]).not_to be_nil
346
+ end
347
+ end
348
+
349
+ context 'and an exception is raised' do
350
+ before do
351
+ expect(search_service).to receive(:previous_and_next_documents_for_search) {
352
+ raise Blacklight::Exceptions::InvalidRequest, "Error"
353
+ }
354
+ end
355
+
356
+ it "does not break" do
357
+ get :show, params: { id: doc_id }
358
+ expect(assigns[:search_context]).to be_nil
359
+ end
360
+ end
273
361
  end
362
+
274
363
  it "does not set previous or next document if session is blank" do
275
364
  get :show, params: { id: doc_id }
276
- expect(assigns[:previous_document]).to be_nil
277
- expect(assigns[:next_document]).to be_nil
365
+ expect(assigns[:search_context]).to be_nil
278
366
  end
367
+
279
368
  it "does not set previous or next document if session[:search]['counter'] is nil" do
280
369
  session[:search] = {}
281
370
  get :show, params: { id: doc_id }
282
- expect(assigns[:previous_document]).to be_nil
283
- expect(assigns[:next_document]).to be_nil
284
- end
285
- it "sets next document if counter present in session" do
286
- session[:search] = search_session.merge('counter' => 2)
287
- get :show, params: { id: doc_id }
288
- expect(assigns[:next_document]).to_not be_nil
289
- end
290
-
291
- it "does not break if solr returns an exception" do
292
- allow(controller).to receive(:get_previous_and_next_documents_for_search) {
293
- raise Blacklight::Exceptions::InvalidRequest.new "Error"
294
- }
295
- get :show, params: { id: doc_id }
296
- expect(assigns[:previous_document]).to be_nil
297
- expect(assigns[:next_document]).to be_nil
371
+ expect(assigns[:search_context]).to be_nil
298
372
  end
299
373
  end
300
374
 
301
375
  # NOTE: status code is always 200 in isolation mode ...
302
- it "HTTP status code for GET should be 200", :integration => true do
376
+ it "HTTP status code for GET should be 200", integration: true do
303
377
  get :show, params: { id: doc_id }
304
- expect(response).to be_success
378
+ expect(response).to be_successful
305
379
  end
306
380
 
307
381
  it "renders show.html.erb" do
308
- allow(mock_document).to receive_messages(:export_formats => {})
309
- allow(controller).to receive_messages(fetch: [mock_response, mock_document])
382
+ allow(controller).to receive(:search_service).and_return(search_service)
383
+ expect(search_service).to receive(:fetch).and_return([mock_response, mock_document])
384
+
310
385
  get :show, params: { id: doc_id }
311
386
  expect(response).to render_template(:show)
312
387
  end
313
388
 
314
- describe "@document" do
389
+ describe '@document' do
315
390
  before do
316
- allow(mock_response).to receive_messages(documents: [SolrDocument.new(id: 'my_fake_doc')])
317
- allow(controller).to receive_messages(:find => mock_response )
391
+ allow(controller).to receive(:search_service).and_return(search_service)
392
+ expect(search_service).to receive(:fetch).and_return([mock_response, mock_document])
393
+
318
394
  get :show, params: { id: doc_id }
319
395
  end
320
- it "is a SolrDocument" do
321
- expect(assigns[:document]).to be_instance_of(SolrDocument)
396
+
397
+ it 'is a SolrDocument' do
398
+ expect(assigns[:document]).to eq mock_document
322
399
  end
323
400
  end
324
401
 
@@ -335,49 +412,70 @@ describe CatalogController do
335
412
  end
336
413
 
337
414
  before do
338
- allow(mock_response).to receive_messages(:documents => [SolrDocument.new(id: 'my_fake_doc')])
339
- allow(controller).to receive_messages(:find => mock_response,
340
- :get_single_doc_via_search => mock_document)
341
415
  Mime::Type.register "application/mock", :mock
342
416
  SolrDocument.use_extension(FakeExtension)
417
+ allow(controller).to receive(:search_service).and_return(search_service)
418
+ expect(search_service).to receive(:fetch).and_return([nil, SolrDocument.new(id: 'my_fake_doc')])
419
+ end
420
+
421
+ after do
422
+ SolrDocument.registered_extensions.pop # remove the fake extension
343
423
  end
344
424
 
345
425
  it "responds to an extension-registered format properly" do
346
426
  get :show, params: { id: doc_id, format: 'mock' }
347
- expect(response).to be_success
427
+ expect(response).to be_successful
348
428
  expect(response.body).to match /mock_export/
349
429
  end
350
-
351
- after do
352
- SolrDocument.registered_extensions.pop # remove the fake extension
353
- end
354
430
  end # dynamic export formats
355
431
  end # describe show action
356
432
 
357
433
  describe "opensearch" do
358
- before do
359
- allow(mock_response).to receive_messages(documents: [SolrDocument.new(id: 'my_fake_doc'), SolrDocument.new(id: 'my_other_doc')])
360
- allow(controller).to receive_messages(find: mock_response)
361
- end
362
434
  it "returns an opensearch description" do
363
435
  get :opensearch, params: { format: 'xml' }
364
- expect(response).to be_success
436
+ expect(response).to be_successful
437
+ end
438
+
439
+ context 'when searching for something' do
440
+ before do
441
+ allow(controller).to receive(:search_service).and_return(search_service)
442
+ expect(search_service).to receive(:opensearch_response)
443
+ .and_return(['a', [SolrDocument.new(id: 'my_fake_doc'),
444
+ SolrDocument.new(id: 'my_other_doc')]])
445
+ end
446
+
447
+ it "returns valid JSON" do
448
+ get :opensearch, params: { format: 'json', q: 'a' }
449
+ expect(response).to be_successful
450
+ end
451
+ end
452
+ end
453
+
454
+ describe 'GET suggest' do
455
+ it 'returns JSON' do
456
+ get :suggest, params: { format: 'json' }
457
+ expect(response.body).to eq [].to_json
365
458
  end
366
- it "returns valid JSON" do
367
- get :opensearch, params: { format: 'json', q: 'a' }
368
- expect(response).to be_success
459
+ it 'returns suggestions' do
460
+ get :suggest, params: { format: 'json', q: 'new' }
461
+ json = JSON.parse(response.body)
462
+ expect(json.count).to eq 5
463
+ expect(json.first['term']).to eq 'new jersey'
369
464
  end
370
465
  end
371
466
 
372
467
  describe "email/sms" do
373
468
  let(:mock_response) { instance_double(Blacklight::Solr::Response, documents: [SolrDocument.new(id: 'my_fake_doc'), SolrDocument.new(id: 'my_other_doc')]) }
469
+
374
470
  before do
375
- allow(controller).to receive_messages(find: mock_response)
471
+ allow(controller).to receive(:search_service).and_return(search_service)
472
+ expect(search_service).to receive(:fetch).and_return([mock_response, []])
376
473
  request.env["HTTP_REFERER"] = "/catalog/#{doc_id}"
377
- SolrDocument.use_extension( Blacklight::Document::Email )
378
- SolrDocument.use_extension( Blacklight::Document::Sms )
474
+ SolrDocument.use_extension(Blacklight::Document::Email)
475
+ SolrDocument.use_extension(Blacklight::Document::Sms)
379
476
  end
380
- describe "email" do
477
+
478
+ describe "email", api: false do
381
479
  it "gives error if no TO parameter" do
382
480
  post :email, params: { id: doc_id }
383
481
  expect(request.flash[:error]).to eq "You must enter a recipient in order to send this message"
@@ -392,7 +490,7 @@ describe CatalogController do
392
490
  end
393
491
  it "redirects back to the record upon success" do
394
492
  allow(RecordMailer).to receive(:email_record)
395
- .with(anything, { :to => 'test_email@projectblacklight.org', :message => 'xyz' }, hash_including(:host => 'test.host'))
493
+ .with(anything, { to: 'test_email@projectblacklight.org', message: 'xyz' }, hash_including(host: 'test.host'))
396
494
  .and_return double(deliver: nil)
397
495
  post :email, params: { id: doc_id, to: 'test_email@projectblacklight.org', message: 'xyz' }
398
496
  expect(request.flash[:error]).to be_nil
@@ -405,7 +503,7 @@ describe CatalogController do
405
503
  end
406
504
  end
407
505
 
408
- describe "sms" do
506
+ describe "sms", api: false do
409
507
  it "gives error if no phone number is given" do
410
508
  post :sms, params: { id: doc_id, carrier: 'att' }
411
509
  expect(request.flash[:error]).to eq "You must enter a recipient's phone number in order to send this message"
@@ -430,8 +528,8 @@ describe CatalogController do
430
528
  it "sends to the appropriate carrier email address" do
431
529
  expect(RecordMailer)
432
530
  .to receive(:sms_record)
433
- .with(anything, { to: '5555555555@txt.att.net' }, hash_including(:host => 'test.host'))
434
- .and_return double(:deliver => nil)
531
+ .with(anything, { to: '5555555555@txt.att.net' }, hash_including(host: 'test.host'))
532
+ .and_return double(deliver: nil)
435
533
  post :sms, params: { id: doc_id, to: '5555555555', carrier: 'txt.att.net' }
436
534
  end
437
535
  it "redirects back to the record upon success" do
@@ -449,38 +547,35 @@ describe CatalogController do
449
547
 
450
548
  describe "errors" do
451
549
  it "returns status 404 for a record that doesn't exist" do
452
- allow(controller).to receive_messages(:find => double(documents: []))
453
- get :show, params: { id: "987654321" }
454
- expect(response.status).to eq 404
455
- expect(response.content_type).to eq Mime[:html]
550
+ allow(controller).to receive_messages(find: double(documents: []))
551
+ expect do
552
+ get :show, params: { id: "987654321" }
553
+ end.to raise_error Blacklight::Exceptions::RecordNotFound
456
554
  end
457
555
 
458
- it "returns status 404 for a record that doesn't exist even for non-html format" do
459
- allow(controller).to receive_messages(:find => double(documents: []))
460
- get :show, params: { id: "987654321", format: "xml" }
461
- expect(response.status).to eq 404
462
- expect(response.content_type).to eq Mime[:xml]
463
- end
556
+ context "when there is an invalid search", api: false do
557
+ let(:service) { instance_double(Blacklight::SearchService) }
558
+ let(:fake_error) { Blacklight::Exceptions::InvalidRequest.new }
464
559
 
465
- it "redirects the user to the root url for a bad search" do
466
- fake_error = Blacklight::Exceptions::InvalidRequest.new
467
- allow(Rails.env).to receive_messages(:test? => false)
468
- allow(controller).to receive(:search_results) { |*args| raise fake_error }
469
- expect(controller.logger).to receive(:error).with(fake_error)
470
- get :index, params: { q: '+' }
560
+ before do
561
+ allow(controller).to receive(:search_service).and_return(service)
562
+ allow(service).to receive(:search_results) { |*_args| raise fake_error }
563
+ allow(Rails.env).to receive_messages(test?: false)
564
+ end
471
565
 
472
- expect(response.redirect_url).to eq root_url
473
- expect(request.flash[:notice]).to eq "Sorry, I don't understand your search."
474
- expect(response).to_not be_success
475
- expect(response.status).to eq 302
476
- end
566
+ it "redirects the user to the root url for a bad search" do
567
+ expect(controller.logger).to receive(:error).with(fake_error)
568
+ get :index, params: { q: '+' }
569
+ expect(response.redirect_url).to eq root_url
570
+ expect(request.flash[:notice]).to eq "Sorry, I don't understand your search."
571
+ expect(response).not_to be_successful
572
+ expect(response.status).to eq 302
573
+ end
477
574
 
478
- it "returns status 500 if the catalog path is raising an exception" do
479
- fake_error = Blacklight::Exceptions::InvalidRequest.new
480
- allow(controller).to receive(:search_results) { |*args| raise fake_error }
481
- allow(controller.flash).to receive(:sweep)
482
- allow(controller).to receive(:flash).and_return(:notice => I18n.t('blacklight.search.errors.request_error'))
483
- expect { get :index, params: { q: '+' } }.to raise_error Blacklight::Exceptions::InvalidRequest
575
+ it "returns status 500 if the catalog path is raising an exception" do
576
+ allow(controller).to receive(:flash).and_return(notice: I18n.t('blacklight.search.errors.request_error'))
577
+ expect { get :index, params: { q: '+' } }.to raise_error Blacklight::Exceptions::InvalidRequest
578
+ end
484
579
  end
485
580
  end
486
581
 
@@ -488,12 +583,12 @@ describe CatalogController do
488
583
  render_views
489
584
 
490
585
  before do
491
- allow(controller).to receive(:has_user_authentication_provider?) { false }
586
+ allow(controller).to receive(:has_user_authentication_provider?).and_return(false)
492
587
  end
493
588
 
494
589
  it "does not show user util links" do
495
590
  get :index
496
- expect(response.body).to_not match /Login/
591
+ expect(response.body).not_to match /Login/
497
592
  end
498
593
  end
499
594
 
@@ -504,6 +599,7 @@ describe CatalogController do
504
599
  expect(response).to be_successful
505
600
  end
506
601
  end
602
+
507
603
  describe "requesting html" do
508
604
  it "is successful" do
509
605
  get :facet, params: { id: 'format' }
@@ -514,6 +610,7 @@ describe CatalogController do
514
610
  expect(assigns[:pagination]).to be_kind_of Blacklight::Solr::FacetPaginator
515
611
  end
516
612
  end
613
+
517
614
  describe "requesting json" do
518
615
  render_views
519
616
  it "is successful" do
@@ -544,9 +641,9 @@ describe CatalogController do
544
641
 
545
642
  context 'when the requested facet is not in the configuration' do
546
643
  it 'raises a routing error' do
547
- expect {
644
+ expect do
548
645
  get :facet, params: { id: 'fake' }
549
- }.to raise_error ActionController::RoutingError, 'Not Found'
646
+ end.to raise_error ActionController::RoutingError, 'Not Found'
550
647
  end
551
648
  end
552
649
  end
@@ -554,20 +651,20 @@ describe CatalogController do
554
651
  describe "#add_to_search_history" do
555
652
  it "prepends the current search to the list" do
556
653
  session[:history] = []
557
- controller.send(:add_to_search_history, double(:id => 1))
654
+ controller.send(:add_to_search_history, double(id: 1))
558
655
  expect(session[:history]).to have(1).item
559
- controller.send(:add_to_search_history, double(:id => 2))
656
+ controller.send(:add_to_search_history, double(id: 2))
560
657
  expect(session[:history]).to have(2).items
561
658
  expect(session[:history].first).to eq 2
562
659
  end
563
660
 
564
661
  it "removes searches from the list when the list gets too big" do
565
- allow(controller).to receive(:blacklight_config).and_return(double(:search_history_window => 5))
662
+ allow(controller).to receive(:blacklight_config).and_return(double(search_history_window: 5))
566
663
  session[:history] = (0..4).to_a.reverse
567
664
  expect(session[:history]).to have(5).items
568
- controller.send(:add_to_search_history, double(:id => 5))
569
- controller.send(:add_to_search_history, double(:id => 6))
570
- controller.send(:add_to_search_history, double(:id => 7))
665
+ controller.send(:add_to_search_history, double(id: 5))
666
+ controller.send(:add_to_search_history, double(id: 6))
667
+ controller.send(:add_to_search_history, double(id: 7))
571
668
  expect(session[:history]).to include(*(3..7).to_a)
572
669
  end
573
670
  end
@@ -576,60 +673,66 @@ describe CatalogController do
576
673
  let(:parameter_class) { ActionController::Parameters }
577
674
 
578
675
  it "creates a session if we're on an search action" do
579
- allow(controller).to receive_messages(:action_name => "index")
676
+ allow(controller).to receive_messages(action_name: "index")
580
677
  allow(controller).to receive_messages(params: parameter_class.new(q: "x", page: 5))
581
678
  session = controller.send(:current_search_session)
582
- expect(session.query_params).to include(:q => "x")
583
- expect(session.query_params).to_not include(:page => 5)
679
+ expect(session.query_params).to include(q: "x")
680
+ expect(session.query_params).not_to include(page: 5)
584
681
  end
585
682
 
586
683
  it "creates a session if a search context was provided" do
587
- allow(controller).to receive_messages(params: parameter_class.new(search_context: JSON.dump(:q => "x")))
684
+ allow(controller).to receive_messages(params: parameter_class.new(search_context: JSON.dump(q: "x")))
588
685
  session = controller.send(:current_search_session)
589
686
  expect(session.query_params).to include("q" => "x")
590
687
  end
591
688
 
592
689
  it "uses an existing session if a search id was provided" do
593
- s = Search.create(:query_params => { :q => "x" })
690
+ s = Search.create(query_params: { q: "x" })
594
691
  session[:history] ||= []
595
692
  session[:history] << s.id
596
693
  allow(controller).to receive_messages(params: parameter_class.new(search_id: s.id))
597
694
  session = controller.send(:current_search_session)
598
- expect(session.query_params).to include(:q => "x")
695
+ expect(session.query_params).to include(q: "x")
599
696
  expect(session).to eq(s)
600
697
  end
601
698
 
602
699
  it "uses an existing search session if the search is in the uri" do
603
- s = Search.create(:query_params => { :q => "x" })
700
+ s = Search.create(query_params: { q: "x" })
604
701
  session[:search] ||= {}
605
702
  session[:search]['id'] = s.id
606
703
  session[:history] ||= []
607
704
  session[:history] << s.id
608
705
  session = controller.send(:current_search_session)
609
- expect(session.query_params).to include(:q => "x")
706
+ expect(session.query_params).to include(q: "x")
610
707
  expect(session).to eq(s)
611
708
  end
612
709
  end
613
710
 
614
711
  describe "#has_search_parameters?" do
615
712
  subject { controller.has_search_parameters? }
713
+
616
714
  describe "none" do
617
- before { allow(controller).to receive_messages(params: { }) }
618
- it { should be false }
715
+ before { allow(controller).to receive_messages(params: {}) }
716
+
717
+ it { is_expected.to be false }
619
718
  end
719
+
620
720
  describe "with a query" do
621
721
  before { allow(controller).to receive_messages(params: { q: 'hello' }) }
622
- it { should be true }
722
+
723
+ it { is_expected.to be true }
623
724
  end
725
+
624
726
  describe "with a facet" do
625
- before { allow(controller).to receive_messages(params: { f: { "field" => ["value"]} }) }
626
- it { should be true }
727
+ before { allow(controller).to receive_messages(params: { f: { "field" => ["value"] } }) }
728
+
729
+ it { is_expected.to be true }
627
730
  end
628
731
  end
629
732
 
630
- describe "#add_show_tools_partial" do
733
+ describe "#add_show_tools_partial", api: false do
631
734
  before do
632
- described_class.add_show_tools_partial(:like, callback: :perform_like, validator: :validate_like_params)
735
+ described_class.blacklight_config.add_show_tools_partial(:like, callback: :perform_like, validator: :validate_like_params)
633
736
  allow(controller).to receive(:solr_document_url).and_return('catalog/1')
634
737
  allow(controller).to receive(:action_documents).and_return(1)
635
738
  Rails.application.routes.draw do
@@ -683,13 +786,83 @@ describe CatalogController do
683
786
  expect(controller.send(:search_facet_path, id: "some_facet", page: 5)).to eq facet_catalog_path(id: "some_facet")
684
787
  end
685
788
  end
789
+
790
+ describe "facet_limit_for" do
791
+ let(:blacklight_config) { controller.blacklight_config }
792
+
793
+ it "returns specified value for facet_field specified" do
794
+ expect(controller.facet_limit_for("subject_ssim")).to eq blacklight_config.facet_fields["subject_ssim"].limit
795
+ end
796
+
797
+ it "facet_limit_hash should return hash with key being facet_field and value being configured limit" do
798
+ # facet_limit_hash has been removed from solrhelper in refactor. should it go back?
799
+ skip "facet_limit_hash has been removed from solrhelper in refactor. should it go back?"
800
+ expect(controller.facet_limit_hash).to eq blacklight_config[:facet][:limits]
801
+ end
802
+
803
+ it "handles no facet_limits in config" do
804
+ blacklight_config.facet_fields = {}
805
+ expect(controller.facet_limit_for("subject_ssim")).to be_nil
806
+ end
807
+
808
+ describe "for 'true' configured values" do
809
+ before do
810
+ allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
811
+ end
812
+
813
+ let(:blacklight_config) do
814
+ Blacklight::Configuration.new do |config|
815
+ config.add_facet_field "language_facet", limit: true
816
+ end
817
+ end
818
+
819
+ it "returns nil if no @response available" do
820
+ expect(controller.facet_limit_for("some_unknown_field")).to be_nil
821
+ end
822
+
823
+ it "gets from @response facet.limit if available" do
824
+ response = instance_double(Blacklight::Solr::Response, aggregations: { "language_facet" => double(limit: nil) })
825
+ controller.instance_variable_set(:@response, response)
826
+ blacklight_config.facet_fields['language_facet'].limit = 10
827
+ expect(controller.facet_limit_for("language_facet")).to eq 10
828
+ end
829
+
830
+ it "gets the limit from the facet field in @response" do
831
+ response = instance_double(Blacklight::Solr::Response, aggregations: { "language_facet" => double(limit: 16) })
832
+ controller.instance_variable_set(:@response, response)
833
+ expect(controller.facet_limit_for("language_facet")).to eq 15
834
+ end
835
+
836
+ it "defaults to 10" do
837
+ expect(controller.facet_limit_for("language_facet")).to eq 10
838
+ end
839
+ end
840
+
841
+ context 'for facet fields with a key that is different from the field name' do
842
+ before do
843
+ allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
844
+ end
845
+
846
+ let(:blacklight_config) do
847
+ Blacklight::Configuration.new do |config|
848
+ config.add_facet_field 'some_key', field: 'x', limit: true
849
+ end
850
+ end
851
+
852
+ it 'gets the limit from the facet field in the @response' do
853
+ response = instance_double(Blacklight::Solr::Response, aggregations: { 'x' => double(limit: 16) })
854
+ controller.instance_variable_set(:@response, response)
855
+ expect(controller.facet_limit_for('some_key')).to eq 15
856
+ end
857
+ end
858
+ end
686
859
  end
687
860
 
688
861
  # there must be at least one facet, and each facet must have at least one value
689
862
  def assert_facets_have_values(aggregations)
690
- expect(aggregations).to_not be_empty
863
+ expect(aggregations).not_to be_empty
691
864
  # should have at least one value for each facet
692
- aggregations.each do |key, facet|
865
+ aggregations.each do |_key, facet|
693
866
  expect(facet.items).to have_at_least(1).item
694
867
  end
695
868
  end