blacklight 8.0.0.beta1 → 8.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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -0
  3. data/.github/workflows/ruby.yml +6 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop_todo.yml +3 -1
  6. data/README.md +1 -1
  7. data/Rakefile +18 -0
  8. data/VERSION +1 -1
  9. data/app/assets/config/blacklight/manifest.js +3 -0
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js +132 -140
  11. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  12. data/app/assets/javascripts/blacklight/blacklight.js +132 -140
  13. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  14. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +1 -1
  15. data/app/assets/stylesheets/blacklight/_facets.scss +32 -5
  16. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +1 -1
  17. data/app/components/blacklight/advanced_search_form_component.rb +3 -3
  18. data/app/components/blacklight/document/actions_component.rb +1 -1
  19. data/app/components/blacklight/document/show_tools_component.html.erb +12 -0
  20. data/app/components/blacklight/document/show_tools_component.rb +23 -0
  21. data/app/components/blacklight/document_component.rb +48 -20
  22. data/app/components/blacklight/document_metadata_component.html.erb +4 -2
  23. data/app/components/blacklight/document_metadata_component.rb +8 -2
  24. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +2 -2
  25. data/app/components/blacklight/facet_field_list_component.html.erb +2 -2
  26. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  27. data/app/components/blacklight/metadata_field_layout_component.rb +7 -4
  28. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +17 -0
  29. data/app/components/blacklight/response/facet_group_component.html.erb +2 -1
  30. data/app/components/blacklight/response/facet_group_component.rb +1 -1
  31. data/app/components/blacklight/response/sort_component.rb +1 -1
  32. data/app/components/blacklight/response/spellcheck_component.rb +1 -1
  33. data/app/components/blacklight/response/view_type_button_component.rb +1 -1
  34. data/app/components/blacklight/response/view_type_component.rb +2 -2
  35. data/app/components/blacklight/search/sidebar_component.html.erb +1 -1
  36. data/app/components/blacklight/search_context/server_applied_params_component.html.erb +4 -0
  37. data/app/components/blacklight/search_context/server_applied_params_component.rb +13 -0
  38. data/app/components/blacklight/search_context/server_item_pagination_component.rb +71 -0
  39. data/app/components/blacklight/system/dropdown_component.rb +3 -3
  40. data/app/components/blacklight/system/flash_message_component.rb +2 -2
  41. data/app/components/blacklight/system/modal_component.rb +1 -1
  42. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  43. data/app/components/blacklight/top_navbar_component.rb +4 -0
  44. data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
  45. data/app/controllers/concerns/blacklight/search_context.rb +46 -6
  46. data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -101
  47. data/app/helpers/blacklight/catalog_helper_behavior.rb +27 -54
  48. data/app/helpers/blacklight/component_helper_behavior.rb +0 -11
  49. data/app/helpers/blacklight/document_helper_behavior.rb +76 -0
  50. data/app/helpers/blacklight/layout_helper_behavior.rb +59 -0
  51. data/app/helpers/blacklight/render_partials_helper_behavior.rb +1 -0
  52. data/app/helpers/blacklight/url_helper_behavior.rb +11 -3
  53. data/app/javascript/blacklight/bookmark_toggle.js +8 -15
  54. data/app/javascript/blacklight/button_focus.js +10 -10
  55. data/app/javascript/blacklight/index.js +6 -5
  56. data/app/javascript/blacklight/modal.js +24 -24
  57. data/app/javascript/blacklight/search_context.js +51 -57
  58. data/app/models/concerns/blacklight/document.rb +11 -0
  59. data/app/models/record_mailer.rb +19 -15
  60. data/app/presenters/blacklight/document_presenter.rb +13 -11
  61. data/app/presenters/blacklight/index_presenter.rb +1 -1
  62. data/app/presenters/blacklight/rendering/abstract_step.rb +4 -0
  63. data/app/presenters/blacklight/rendering/join.rb +7 -1
  64. data/app/presenters/blacklight/rendering/link_to_facet.rb +1 -1
  65. data/app/presenters/blacklight/rendering/microdata.rb +1 -1
  66. data/app/services/blacklight/search_service.rb +2 -1
  67. data/app/views/catalog/_document.atom.builder +1 -1
  68. data/app/views/catalog/_document.html.erb +3 -8
  69. data/app/views/catalog/_document_list.html.erb +2 -1
  70. data/app/views/catalog/_facet_layout.html.erb +2 -2
  71. data/app/views/catalog/_show_main_content.html.erb +5 -11
  72. data/app/views/catalog/_show_tools.html.erb +1 -14
  73. data/app/views/catalog/facet.html.erb +3 -3
  74. data/app/views/catalog/index.html.erb +3 -0
  75. data/app/views/catalog/show.html.erb +1 -6
  76. data/app/views/layouts/blacklight/base.html.erb +4 -5
  77. data/app/views/record_mailer/email_record.text.erb +4 -3
  78. data/app/views/record_mailer/sms_record.text.erb +4 -4
  79. data/blacklight.gemspec +2 -2
  80. data/config/importmap.rb +1 -1
  81. data/config/locales/blacklight.ar.yml +209 -232
  82. data/config/locales/blacklight.ca.yml +0 -6
  83. data/config/locales/blacklight.de.yml +197 -215
  84. data/config/locales/blacklight.en.yml +2 -6
  85. data/config/locales/blacklight.es.yml +196 -215
  86. data/config/locales/blacklight.fr.yml +196 -219
  87. data/config/locales/blacklight.hu.yml +193 -212
  88. data/config/locales/blacklight.it.yml +197 -215
  89. data/config/locales/blacklight.nl.yml +193 -212
  90. data/config/locales/blacklight.pt-BR.yml +195 -215
  91. data/config/locales/blacklight.sq.yml +193 -212
  92. data/config/locales/blacklight.zh.yml +194 -213
  93. data/docker-compose.yml +1 -0
  94. data/lib/blacklight/configuration/session_tracking_config.rb +45 -0
  95. data/lib/blacklight/configuration/view_config.rb +0 -4
  96. data/lib/blacklight/configuration.rb +8 -4
  97. data/lib/blacklight/engine.rb +6 -7
  98. data/lib/blacklight/routes/searchable.rb +1 -0
  99. data/lib/generators/blacklight/assets/importmap_generator.rb +9 -8
  100. data/lib/generators/blacklight/assets/propshaft_generator.rb +11 -2
  101. data/lib/generators/blacklight/assets/sprockets_generator.rb +2 -0
  102. data/lib/generators/blacklight/assets_generator.rb +3 -1
  103. data/lib/generators/blacklight/install_generator.rb +3 -1
  104. data/lib/generators/blacklight/templates/solr_document.rb +0 -6
  105. data/package.json +7 -4
  106. data/rollup.config.js +11 -1
  107. data/spec/components/blacklight/document_component_spec.rb +66 -15
  108. data/spec/components/blacklight/header_component_spec.rb +20 -0
  109. data/spec/components/blacklight/response/view_type_component_spec.rb +17 -0
  110. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  111. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +29 -0
  112. data/spec/components/blacklight/{search_context_component_spec.rb → search_context/server_item_pagination_component_spec.rb} +15 -4
  113. data/spec/controllers/bookmarks_controller_spec.rb +1 -1
  114. data/spec/controllers/catalog_controller_spec.rb +18 -6
  115. data/spec/features/component_template_override_spec.rb +8 -0
  116. data/spec/features/modal_spec.rb +12 -0
  117. data/spec/features/sitelinks_search_box_spec.rb +13 -0
  118. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -1
  119. data/spec/helpers/blacklight_helper_spec.rb +0 -56
  120. data/spec/helpers/catalog_helper_spec.rb +56 -0
  121. data/spec/lib/blacklight/configuration/session_tracking_config_spec.rb +38 -0
  122. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +2 -2
  123. data/spec/models/blacklight/configuration_spec.rb +2 -2
  124. data/spec/models/blacklight/icon_spec.rb +0 -2
  125. data/spec/models/blacklight/search_builder_spec.rb +3 -3
  126. data/spec/models/blacklight/solr/request_spec.rb +2 -2
  127. data/spec/models/record_mailer_spec.rb +36 -23
  128. data/spec/presenters/blacklight/document_presenter_spec.rb +1 -0
  129. data/spec/presenters/blacklight/field_presenter_spec.rb +2 -2
  130. data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
  131. data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
  132. data/spec/presenters/pipeline_spec.rb +13 -2
  133. data/spec/routing/catalog_routing_spec.rb +4 -0
  134. data/spec/spec_helper.rb +1 -1
  135. data/spec/support/view_component_test_helpers.rb +21 -0
  136. data/spec/test_app_templates/Gemfile.extra +4 -0
  137. data/spec/test_app_templates/lib/generators/test_app_generator.rb +8 -0
  138. data/spec/views/catalog/_document.html.erb_spec.rb +22 -1
  139. data/spec/views/catalog/_document_list.html.erb_spec.rb +7 -2
  140. data/spec/views/catalog/_show_tools.html.erb_spec.rb +2 -2
  141. data/spec/views/catalog/index.json.jbuilder_spec.rb +1 -1
  142. data/tasks/blacklight.rake +1 -1
  143. metadata +39 -21
  144. data/app/components/blacklight/search_context_component.rb +0 -68
  145. data/app/models/concerns/blacklight/document/email.rb +0 -27
  146. data/app/models/concerns/blacklight/document/sms.rb +0 -25
  147. data/spec/features/sitelinks_search_box.rb +0 -13
  148. data/spec/models/blacklight/document/email_spec.rb +0 -57
  149. data/spec/models/blacklight/document/sms_spec.rb +0 -58
  150. data/spec/support/view_component_capybara_test_helpers.rb +0 -8
  151. /data/app/components/blacklight/{search_context_component.html.erb → search_context/server_item_pagination_component.html.erb} +0 -0
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'shellwords'
4
+
3
5
  module Blacklight
4
6
  class Install < Rails::Generators::Base
5
7
  source_root File.expand_path('../templates', __FILE__)
@@ -35,7 +37,7 @@ module Blacklight
35
37
  # Call external generator in AssetsGenerator, so we can
36
38
  # leave that callable seperately too.
37
39
  def copy_public_assets
38
- generated_options = "--bootstrap-version='#{options[:'bootstrap-version']}'" if options[:'bootstrap-version']
40
+ generated_options = "--bootstrap-version='#{Shellwords.escape(options[:'bootstrap-version'])}'" if options[:'bootstrap-version']
39
41
 
40
42
  generate "blacklight:assets", generated_options unless options[:'skip-assets']
41
43
  end
@@ -6,12 +6,6 @@ class <%= model_name.classify %>
6
6
 
7
7
  # self.unique_key = 'id'
8
8
 
9
- # Email uses the semantic field mappings below to generate the body of an email.
10
- SolrDocument.use_extension(Blacklight::Document::Email)
11
-
12
- # SMS uses the semantic field mappings below to generate the body of an SMS email.
13
- SolrDocument.use_extension(Blacklight::Document::Sms)
14
-
15
9
  # DublinCore uses the semantic field mappings below to assemble an OAI-compliant Dublin Core document
16
10
  # Semantic mappings of solr stored fields. Fields may be multi or
17
11
  # single valued. See Blacklight::Document::SemanticFields#field_semantics
data/package.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "blacklight-frontend",
3
- "version": "8.0.0-beta.1",
3
+ "version": "8.0.0",
4
4
  "description": "[![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=main)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Coverage Status](https://coveralls.io/repos/github/projectblacklight/blacklight/badge.svg?branch=main)](https://coveralls.io/github/projectblacklight/blacklight?branch=main)",
5
5
  "main": "app/assets/javascripts/blacklight",
6
+ "module": "app/assets/javascripts/blacklight/blacklight.esm.js",
6
7
  "scripts": {
7
- "js-compile-bundle": "rollup --config rollup.config.js --sourcemap && ESM=true rollup --config rollup.config.js --sourcemap"
8
+ "prepare": "rollup --config rollup.config.js --sourcemap && ESM=true rollup --config rollup.config.js --sourcemap"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
11
12
  "url": "git+https://github.com/projectblacklight/blacklight.git"
12
13
  },
13
14
  "files": [
14
- "app/assets"
15
+ "app/assets",
16
+ "app/javascript"
15
17
  ],
16
18
  "author": "",
17
19
  "license": "Apache-2.0",
@@ -20,7 +22,8 @@
20
22
  },
21
23
  "homepage": "https://github.com/projectblacklight/blacklight#readme",
22
24
  "devDependencies": {
23
- "rollup": "^2.60.0"
25
+ "rollup": "^2.60.0",
26
+ "rollup-plugin-includepaths": "^0.2.4"
24
27
  },
25
28
  "browserslist": [
26
29
  "defaults",
data/rollup.config.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ import includePaths from 'rollup-plugin-includepaths';
4
+
3
5
  const path = require('path')
4
6
 
5
7
  const BUNDLE = process.env.BUNDLE === 'true'
@@ -9,6 +11,13 @@ const fileDest = `blacklight${ESM ? '.esm' : ''}`
9
11
  const external = []
10
12
  const globals = {}
11
13
 
14
+ let includePathOptions = {
15
+ include: {},
16
+ paths: ['app/javascript'],
17
+ external: [],
18
+ extensions: ['.js']
19
+ };
20
+
12
21
  const rollupConfig = {
13
22
  input: path.resolve(__dirname, `app/javascript/blacklight/index.js`),
14
23
  output: {
@@ -17,7 +26,8 @@ const rollupConfig = {
17
26
  globals,
18
27
  generatedCode: 'es2015'
19
28
  },
20
- external
29
+ external,
30
+ plugins: [includePaths(includePathOptions)]
21
31
  }
22
32
 
23
33
  if (!ESM) {
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::DocumentComponent, type: :component do
6
- subject(:component) { described_class.new(document: document, presenter: view_context.document_presenter(document), **attr) }
6
+ subject(:component) { described_class.new(document: document, **attr) }
7
7
 
8
8
  let(:attr) { {} }
9
9
  let(:view_context) { controller.view_context }
@@ -15,7 +15,9 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
15
15
  Capybara::Node::Simple.new(render)
16
16
  end
17
17
 
18
- let(:document) do
18
+ let(:document) { view_context.document_presenter(presented_document) }
19
+
20
+ let(:presented_document) do
19
21
  SolrDocument.new(
20
22
  id: 'x',
21
23
  thumbnail_path_ss: 'http://example.com/image.jpg',
@@ -26,7 +28,7 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
26
28
 
27
29
  let(:blacklight_config) do
28
30
  CatalogController.blacklight_config.deep_copy.tap do |config|
29
- config.track_search_session = false
31
+ config.track_search_session.storage = false
30
32
  config.index.thumbnail_field = 'thumbnail_path_ss'
31
33
  config.index.document_actions[:bookmark].partial = '/catalog/bookmark_control'
32
34
  end
@@ -74,6 +76,10 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
74
76
  end
75
77
 
76
78
  context 'index view' do
79
+ before do
80
+ controller.action_name = "index"
81
+ end
82
+
77
83
  let(:attr) { { counter: 5 } }
78
84
 
79
85
  it 'has data properties' do
@@ -92,9 +98,12 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
92
98
  end
93
99
 
94
100
  context 'with a document rendered as part of a collection' do
95
- let(:attr) { { document_counter: 10, counter_offset: 100 } }
101
+ # ViewComponent 3 changes iteration counters to begin at 0 rather than 1
102
+ let(:document_counter) { ViewComponent::VERSION::MAJOR < 3 ? 11 : 10 }
103
+ let(:attr) { { document_counter: document_counter, counter_offset: 100 } }
96
104
 
97
105
  it 'renders a counter with the title' do
106
+ # after ViewComponent 2.5, collection counter params are 1-indexed
98
107
  expect(rendered).to have_selector 'header', text: '111. Title'
99
108
  end
100
109
  end
@@ -106,13 +115,22 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
106
115
  it 'renders a thumbnail' do
107
116
  expect(rendered).to have_selector 'a[href="/catalog/x"] img[src="http://example.com/image.jpg"]'
108
117
  end
118
+
119
+ context 'with default metadata component' do
120
+ it 'renders metadata' do
121
+ expect(rendered).to have_selector 'dl.document-metadata'
122
+ expect(rendered).to have_selector 'dt', text: 'Title:'
123
+ expect(rendered).to have_selector 'dd', text: 'Title'
124
+ expect(rendered).not_to have_selector 'dt', text: 'ISBN:'
125
+ end
126
+ end
109
127
  end
110
128
 
111
129
  context 'show view' do
112
130
  let(:attr) { { title_component: :h1, show: true } }
113
131
 
114
132
  before do
115
- allow(view_context).to receive(:action_name).and_return('show')
133
+ controller.action_name = "show"
116
134
  end
117
135
 
118
136
  it 'renders with an id' do
@@ -143,25 +161,58 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
143
161
  blacklight_config.show.embed_component = StubComponent
144
162
  expect(rendered).to have_content 'embed'
145
163
  end
146
- end
147
164
 
148
- it 'renders metadata' do
149
- expect(rendered).to have_selector 'dl.document-metadata'
150
- expect(rendered).to have_selector 'dt', text: 'Title:'
151
- expect(rendered).to have_selector 'dd', text: 'Title'
152
- expect(rendered).not_to have_selector 'dt', text: 'ISBN:'
165
+ context 'with configured metadata component' do
166
+ let(:custom_component_class) do
167
+ Class.new(Blacklight::DocumentMetadataComponent) do
168
+ # Override component rendering with our own value
169
+ def call
170
+ 'blah'
171
+ end
172
+ end
173
+ end
174
+
175
+ before do
176
+ stub_const('MyMetadataComponent', custom_component_class)
177
+ blacklight_config.show.metadata_component = MyMetadataComponent
178
+ end
179
+
180
+ it 'renders custom component' do
181
+ expect(rendered).to have_text 'blah'
182
+ end
183
+ end
184
+
185
+ context 'with configured title component' do
186
+ let(:custom_component_class) do
187
+ Class.new(Blacklight::DocumentTitleComponent) do
188
+ # Override component rendering with our own value
189
+ def call
190
+ 'Titleriffic'
191
+ end
192
+ end
193
+ end
194
+
195
+ before do
196
+ stub_const('MyTitleComponent', custom_component_class)
197
+ blacklight_config.show.title_component = MyTitleComponent
198
+ end
199
+
200
+ it 'renders custom component' do
201
+ expect(rendered).to have_text 'Titleriffic'
202
+ end
203
+ end
153
204
  end
154
205
 
155
206
  it 'renders partials' do
156
- component.partial { 'Partials' }
207
+ component.with_partial { 'Partials' }
157
208
  expect(rendered).to have_content 'Partials'
158
209
  end
159
210
 
160
- context 'with before_title' do
211
+ context 'with before_titles' do
161
212
  let(:render) do
162
213
  component.render_in(view_context) do
163
- component.title do |c|
164
- c.before_title { 'Prefix!' }
214
+ component.with_title do |c|
215
+ c.with_before_title { 'Prefix!' }
165
216
  end
166
217
  end
167
218
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::HeaderComponent, type: :component do
4
+ before do
5
+ with_controller_class(CatalogController) do
6
+ allow(controller).to receive(:current_user).and_return(nil)
7
+ allow(controller).to receive(:search_action_url).and_return('/search')
8
+ render
9
+ end
10
+ end
11
+
12
+ context 'with no slots' do
13
+ let(:render) { render_inline(described_class.new(blacklight_config: CatalogController.blacklight_config)) }
14
+
15
+ it 'draws the topbar' do
16
+ expect(page).to have_css 'nav.topbar'
17
+ expect(page).to have_link 'Blacklight', href: '/'
18
+ end
19
+ end
20
+ end
@@ -11,7 +11,24 @@ RSpec.describe Blacklight::Response::ViewTypeComponent, type: :component do
11
11
  let(:search_state) { instance_double(Blacklight::SearchState, to_h: { controller: 'catalog', action: 'index' }) }
12
12
  let(:view_config) { Blacklight::Configuration::ViewConfig.new }
13
13
 
14
+ let(:custom_component_class) do
15
+ Class.new(Blacklight::Icons::IconComponent) do
16
+ # Override component rendering with our own value
17
+ def call
18
+ 'blah'
19
+ end
20
+ end
21
+ end
22
+
23
+ before do
24
+ stub_const('Blacklight::Icons::DefComponent', custom_component_class)
25
+ end
26
+
14
27
  describe "when some views exist" do
28
+ before do
29
+ stub_const('Blacklight::Icons::AbcComponent', custom_component_class)
30
+ end
31
+
15
32
  let(:views) do
16
33
  {
17
34
  abc: view_config,
@@ -29,7 +29,7 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
29
29
  context 'when a button is passed in' do
30
30
  subject(:render) do
31
31
  render_inline(instance) do |c|
32
- c.search_button do
32
+ c.with_search_button do
33
33
  controller.view_context.tag.button "hello", id: 'custom_search'
34
34
  end
35
35
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :component do
6
+ subject(:render) { instance.render_in(view_context) }
7
+
8
+ let(:instance) { described_class.new }
9
+ let(:current_search_session) { nil }
10
+ let(:view_context) { controller.view_context }
11
+
12
+ before do
13
+ view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for('application/_start_over.html.erb' => 'start over'))
14
+ allow(view_context).to receive(:current_search_session).and_return current_search_session
15
+ allow(view_context).to receive(:link_back_to_catalog).with(any_args)
16
+ end
17
+
18
+ it 'is blank without current session' do
19
+ expect(render).to be_blank
20
+ end
21
+
22
+ context 'with current session' do
23
+ let(:current_search_session) { double(query_params: { q: 'abc' }) }
24
+
25
+ it 'is not blank' do
26
+ expect(render).not_to be_blank
27
+ end
28
+ end
29
+ end
@@ -2,14 +2,17 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Blacklight::SearchContextComponent, type: :component do
5
+ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :component do
6
6
  subject(:render) { render_inline(instance) }
7
7
 
8
- let(:search_session) { {} }
9
- let(:instance) { described_class.new(search_context: search_context, search_session: search_session) }
8
+ let(:current_document_id) { 9 }
9
+ let(:current_document) { SolrDocument.new(id: current_document_id) }
10
+ let(:search_session) { { 'document_id' => current_document_id } }
11
+ let(:instance) { described_class.new(search_context: search_context, search_session: search_session, current_document: current_document) }
10
12
 
11
13
  before do
12
- allow(controller).to receive(:current_search_session).and_return(double(id: 9))
14
+ allow(controller).to receive(:current_search_session).and_return(double(id: current_document_id))
15
+ controller.class.helper_method :current_search_session
13
16
  end
14
17
 
15
18
  context 'when there is no next or previous' do
@@ -36,5 +39,13 @@ RSpec.describe Blacklight::SearchContextComponent, type: :component do
36
39
  it "renders content" do
37
40
  expect(render.css('.pagination-search-widgets').to_html).not_to be_blank
38
41
  end
42
+
43
+ context "session and document are out of sync" do
44
+ let(:current_document) { SolrDocument.new(id: current_document_id + 1) }
45
+
46
+ it "does not render content" do
47
+ expect(render.to_html).to be_blank
48
+ end
49
+ end
39
50
  end
40
51
  end
@@ -7,7 +7,7 @@ RSpec.describe BookmarksController do
7
7
  end
8
8
 
9
9
  it 'opts out of search session tracking' do
10
- expect(@controller.blacklight_config.track_search_session).to be false
10
+ expect(@controller.blacklight_config.track_search_session.storage).to be false
11
11
  end
12
12
  end
13
13
 
@@ -158,7 +158,7 @@ RSpec.describe CatalogController, api: true do
158
158
 
159
159
  format = facets.find { |x| x['id'] == 'format' }
160
160
 
161
- expect(format['attributes']['items'].pluck('attributes')).to match_array([{ "value" => "Book", "hits" => 30, "label" => "Book" }])
161
+ expect(format['attributes']['items'].pluck('attributes')).to contain_exactly({ "value" => "Book", "hits" => 30, "label" => "Book" })
162
162
  expect(format['links']['self']).to eq facet_catalog_url(format: :json, id: 'format')
163
163
  expect(format['attributes']['items'].first['links']['self']).to eq search_catalog_url(format: :json, f: { format: ['Book'] })
164
164
  end
@@ -468,17 +468,14 @@ RSpec.describe CatalogController, api: true do
468
468
  end
469
469
 
470
470
  describe "email/sms" do
471
+ let(:mock_document) { SolrDocument.new }
472
+
471
473
  before do
472
- mock_document.extend(Blacklight::Document::Sms)
473
- mock_document.extend(Blacklight::Document::Email)
474
- allow(mock_document).to receive(:to_semantic_values).and_return({})
475
474
  allow(mock_document).to receive(:to_model).and_return(SolrDocument.new(id: 'my_fake_doc'))
476
475
 
477
476
  allow(controller).to receive(:search_service).and_return(search_service)
478
477
  expect(search_service).to receive(:fetch).and_return([mock_document])
479
478
  request.env["HTTP_REFERER"] = "/catalog/#{doc_id}"
480
- SolrDocument.use_extension(Blacklight::Document::Email)
481
- SolrDocument.use_extension(Blacklight::Document::Sms)
482
479
  end
483
480
 
484
481
  describe "email", api: false do
@@ -797,6 +794,21 @@ RSpec.describe CatalogController, api: true do
797
794
  expect(controller.send(:search_facet_path, id: "some_facet", page: 5)).to eq facet_catalog_path(id: "some_facet")
798
795
  end
799
796
  end
797
+
798
+ describe "page_links" do
799
+ it "has prev/next docs and result set data for non-empty result sets", integration: true do
800
+ get :page_links, params: { f: { "format" => 'Book' }, counter: 2 }
801
+ expect(assigns(:page_link_data)).not_to be_empty
802
+ expect(assigns(:page_link_data).fetch(:prev, nil)).to end_with('counter=1')
803
+ expect(assigns(:page_link_data).fetch(:next, nil)).to end_with('counter=3')
804
+ expect(assigns(:page_link_data).fetch(:totalRaw, nil)).to be 30
805
+ end
806
+
807
+ it "is empty for empty result sets", integration: true do
808
+ get :page_links, params: { f: { "format" => 'empty-result-set' }, counter: 1 }
809
+ expect(assigns(:page_link_data)).to be_empty
810
+ end
811
+ end
800
812
  end
801
813
 
802
814
  # there must be at least one facet, and each facet must have at least one value
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Generated test application template at default path' do
4
+ it 'unobtrusively overrides default top navbar component template' do
5
+ visit root_path
6
+ expect(page).to have_css 'nav[data-template-override="top_navbar_component"]'
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Modal' do
4
+ it 'can open and dismiss the email modal', js: true do
5
+ visit solr_document_path('2007020969')
6
+ expect(page).to have_no_selector 'dialog#blacklight-modal'
7
+ click_link 'Email'
8
+ expect(page).to have_selector 'dialog#blacklight-modal'
9
+ click_button '×'
10
+ expect(page).to have_no_selector 'dialog#blacklight-modal'
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Sitelinks search box' do
4
+ it 'is home page' do
5
+ visit root_path
6
+ expect(page).to have_selector 'script[type="application/ld+json"]', visible: :hidden
7
+ end
8
+
9
+ it 'on search page' do
10
+ visit search_catalog_path q: 'book'
11
+ expect(page).not_to have_selector 'script[type="application/ld+json"]', visible: :hidden
12
+ end
13
+ end
@@ -187,7 +187,7 @@ RSpec.describe Blacklight::UrlHelperBehavior do
187
187
  end
188
188
 
189
189
  it "uses the track_search_session configuration to determine whether to track the search session" do
190
- blacklight_config.track_search_session = false
190
+ blacklight_config.track_search_session.storage = false
191
191
  expect(helper.session_tracking_path(document, x: 1)).to be_nil
192
192
  end
193
193
  end
@@ -134,18 +134,6 @@ RSpec.describe BlacklightHelper do
134
134
  end
135
135
  end
136
136
 
137
- describe "render_grouped_response?" do
138
- it "checks if the response ivar contains grouped data" do
139
- assign(:response, instance_double(Blacklight::Solr::Response, grouped?: true))
140
- expect(helper.render_grouped_response?).to be true
141
- end
142
-
143
- it "checks if the response param contains grouped data" do
144
- response = instance_double(Blacklight::Solr::Response, grouped?: true)
145
- expect(helper.render_grouped_response?(response)).to be true
146
- end
147
- end
148
-
149
137
  describe "#opensearch_description_tag" do
150
138
  subject { helper.opensearch_description_tag 'title', 'href' }
151
139
 
@@ -210,48 +198,4 @@ RSpec.describe BlacklightHelper do
210
198
  end
211
199
  end
212
200
  end
213
-
214
- describe "#document_index_view_type" do
215
- it "defaults to the default view" do
216
- allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
217
- allow(helper).to receive(:default_document_index_view_type).and_return(:xyz)
218
- expect(helper.document_index_view_type).to eq :xyz
219
- end
220
-
221
- it "uses the query parameter" do
222
- allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
223
- expect(helper.document_index_view_type(view: :a)).to eq :a
224
- end
225
-
226
- it "uses the default view if the requested view is not available" do
227
- allow(helper).to receive(:default_document_index_view_type).and_return(:xyz)
228
- allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
229
- expect(helper.document_index_view_type(view: :c)).to eq :xyz
230
- end
231
-
232
- context "when they have a preferred view" do
233
- before do
234
- session[:preferred_view] = :b
235
- end
236
-
237
- context "and no view is specified" do
238
- it "uses the saved preference" do
239
- allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2, c: 3)
240
- expect(helper.document_index_view_type).to eq :b
241
- end
242
-
243
- it "uses the default view if the preference is not available" do
244
- allow(helper).to receive(:document_index_views).and_return(a: 1)
245
- expect(helper.document_index_view_type).to eq :a
246
- end
247
- end
248
-
249
- context "and a view is specified" do
250
- it "uses the query parameter" do
251
- allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2, c: 3)
252
- expect(helper.document_index_view_type(view: :c)).to eq :c
253
- end
254
- end
255
- end
256
- end
257
201
  end
@@ -284,4 +284,60 @@ RSpec.describe CatalogHelper do
284
284
  it { is_expected.to eq "foobar / Format: Book" }
285
285
  end
286
286
  end
287
+
288
+ describe "render_grouped_response?" do
289
+ it "checks if the response ivar contains grouped data" do
290
+ assign(:response, instance_double(Blacklight::Solr::Response, grouped?: true))
291
+ expect(helper.render_grouped_response?).to be true
292
+ end
293
+
294
+ it "checks if the response param contains grouped data" do
295
+ response = instance_double(Blacklight::Solr::Response, grouped?: true)
296
+ expect(helper.render_grouped_response?(response)).to be true
297
+ end
298
+ end
299
+
300
+ describe "#document_index_view_type" do
301
+ it "defaults to the default view" do
302
+ allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
303
+ allow(helper).to receive(:default_document_index_view_type).and_return(:xyz)
304
+ expect(helper.document_index_view_type).to eq :xyz
305
+ end
306
+
307
+ it "uses the query parameter" do
308
+ allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
309
+ expect(helper.document_index_view_type(view: :a)).to eq :a
310
+ end
311
+
312
+ it "uses the default view if the requested view is not available" do
313
+ allow(helper).to receive(:default_document_index_view_type).and_return(:xyz)
314
+ allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2)
315
+ expect(helper.document_index_view_type(view: :c)).to eq :xyz
316
+ end
317
+
318
+ context "when they have a preferred view" do
319
+ before do
320
+ session[:preferred_view] = :b
321
+ end
322
+
323
+ context "and no view is specified" do
324
+ it "uses the saved preference" do
325
+ allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2, c: 3)
326
+ expect(helper.document_index_view_type).to eq :b
327
+ end
328
+
329
+ it "uses the default view if the preference is not available" do
330
+ allow(helper).to receive(:document_index_views).and_return(a: 1)
331
+ expect(helper.document_index_view_type).to eq :a
332
+ end
333
+ end
334
+
335
+ context "and a view is specified" do
336
+ it "uses the query parameter" do
337
+ allow(helper).to receive(:document_index_views).and_return(a: 1, b: 2, c: 3)
338
+ expect(helper.document_index_view_type(view: :c)).to eq :c
339
+ end
340
+ end
341
+ end
342
+ end
287
343
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::Configuration::SessionTrackingConfig do
4
+ subject(:config) { described_class.new }
5
+
6
+ it "defaults @storage to 'server'" do
7
+ expect(config.storage).to eq 'server'
8
+ end
9
+
10
+ context "@storage is set to 'server'" do
11
+ before do
12
+ config.storage = 'server'
13
+ end
14
+
15
+ it "defaults components values" do
16
+ expect(config.applied_params_component).to eq Blacklight::SearchContext::ServerAppliedParamsComponent
17
+ expect(config.item_pagination_component).to eq Blacklight::SearchContext::ServerItemPaginationComponent
18
+ end
19
+
20
+ it "defaults tracking url helper" do
21
+ expect(config.url_helper).to be_nil
22
+ end
23
+ end
24
+
25
+ context "@storage is set to false" do
26
+ before do
27
+ config.storage = false
28
+ end
29
+
30
+ it "defaults components values" do
31
+ expect(config.applied_params_component).to be_nil
32
+ end
33
+
34
+ it "defaults tracking url helper" do
35
+ expect(config.url_helper).to be_nil
36
+ end
37
+ end
38
+ end
@@ -76,7 +76,7 @@ RSpec.describe Blacklight::OpenStructWithHashAccess do
76
76
 
77
77
  it "sorts the underlying hash" do
78
78
  sorted = subject.sort_by { |_k, v| v }
79
- expect(sorted.keys).to match_array [:b, :a, :c]
79
+ expect(sorted.keys).to contain_exactly(:b, :a, :c)
80
80
  end
81
81
  end
82
82
 
@@ -85,7 +85,7 @@ RSpec.describe Blacklight::OpenStructWithHashAccess do
85
85
 
86
86
  it "sorts the underlying hash" do
87
87
  subject.sort_by! { |_k, v| v }
88
- expect(subject.keys).to match_array [:b, :a, :c]
88
+ expect(subject.keys).to contain_exactly(:b, :a, :c)
89
89
  end
90
90
  end
91
91