blacklight 9.0.0 → 9.1.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.
- checksums.yaml +4 -4
- data/.env +3 -3
- data/.github/matrix.json +12 -18
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/test.yml +4 -3
- data/.rubocop.yml +72 -7
- data/.rubocop_todo.yml +142 -268
- data/Gemfile +1 -1
- data/README.md +2 -9
- data/VERSION +1 -1
- data/app/assets/builds/blacklight.css +37 -23
- data/app/assets/images/blacklight/logo-dark.svg +184 -0
- data/app/assets/images/blacklight/logo.svg +184 -0
- data/app/assets/javascripts/blacklight/blacklight.esm.js +128 -45
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +128 -45
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -1
- data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +17 -0
- data/app/assets/stylesheets/blacklight/_constraints.scss +2 -2
- data/app/assets/stylesheets/blacklight/_facets.scss +14 -10
- data/app/assets/stylesheets/blacklight/_header.scss +0 -4
- data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -9
- data/app/components/blacklight/facets/inclusive_constraint_component.html.erb +1 -1
- data/app/components/blacklight/icons/checkmark_component.rb +16 -0
- data/app/components/blacklight/icons/circle_half_component.rb +16 -0
- data/app/components/blacklight/icons/moon_stars_component.rb +17 -0
- data/app/components/blacklight/icons/sun_component.rb +16 -0
- data/app/components/blacklight/metadata_field_component.rb +1 -1
- data/app/components/blacklight/search_navbar_component.html.erb +1 -1
- data/app/components/blacklight/theme_switcher_component.html.erb +31 -0
- data/app/components/blacklight/theme_switcher_component.rb +6 -0
- data/app/components/blacklight/top_navbar_component.html.erb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +8 -14
- data/app/controllers/concerns/blacklight/catalog.rb +9 -10
- data/app/controllers/concerns/blacklight/controller.rb +54 -11
- data/app/controllers/concerns/blacklight/guest_user.rb +51 -0
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/controllers/concerns/blacklight/search_history.rb +3 -1
- data/app/controllers/concerns/blacklight/searchable.rb +18 -0
- data/app/helpers/blacklight/layout_helper_behavior.rb +7 -0
- data/app/javascript/blacklight-frontend/color_theme_switcher.js +85 -0
- data/app/javascript/blacklight-frontend/index.js +2 -0
- data/app/models/concerns/blacklight/document/dublin_core.rb +2 -2
- data/app/models/concerns/blacklight/document.rb +1 -1
- data/app/models/concerns/blacklight/user.rb +36 -0
- data/app/presenters/blacklight/field_presenter.rb +1 -1
- data/app/presenters/blacklight/rendering/microdata.rb +1 -0
- data/app/services/blacklight/bookmarks_search_builder.rb +4 -4
- data/app/services/blacklight/search_service.rb +46 -33
- data/app/values/blacklight/types.rb +1 -1
- data/app/views/catalog/_email_form.html.erb +3 -3
- data/app/views/catalog/_home_text.html.erb +1 -1
- data/app/views/catalog/_sms_form.html.erb +4 -4
- data/app/views/catalog/index.rss.builder +4 -4
- data/app/views/catalog/opensearch.json.jbuilder +3 -0
- data/app/views/catalog/opensearch.xml.builder +2 -2
- data/app/views/layouts/blacklight/base.html.erb +13 -1
- data/app/views/shared/_user_util_links.html.erb +18 -5
- data/blacklight.gemspec +3 -3
- data/config/locales/blacklight.ar.yml +5 -0
- data/config/locales/blacklight.ca.yml +5 -0
- data/config/locales/blacklight.de.yml +6 -2
- data/config/locales/blacklight.en.yml +5 -0
- data/config/locales/blacklight.es.yml +5 -0
- data/config/locales/blacklight.fr.yml +5 -0
- data/config/locales/blacklight.hu.yml +5 -0
- data/config/locales/blacklight.it.yml +6 -2
- data/config/locales/blacklight.nl.yml +5 -0
- data/config/locales/blacklight.pt-BR.yml +6 -2
- data/config/locales/blacklight.sq.yml +5 -0
- data/config/locales/blacklight.zh.yml +5 -0
- data/lib/blacklight/component.rb +1 -1
- data/lib/blacklight/configuration/action_config_map_entry.rb +31 -0
- data/lib/blacklight/configuration/display_field.rb +1 -0
- data/lib/blacklight/configuration/field.rb +6 -6
- data/lib/blacklight/configuration/fields.rb +1 -1
- data/lib/blacklight/configuration/sort_field.rb +2 -2
- data/lib/blacklight/configuration.rb +30 -19
- data/lib/blacklight/parameters.rb +1 -1
- data/lib/blacklight/search_builder.rb +58 -19
- data/lib/blacklight/search_state.rb +4 -0
- data/lib/blacklight/solr/request.rb +8 -1
- data/lib/blacklight/solr/response/group_response.rb +1 -1
- data/lib/blacklight/solr/response/spelling.rb +8 -8
- data/lib/blacklight/solr/response.rb +2 -21
- data/lib/blacklight/solr/search_builder_behavior.rb +3 -9
- data/lib/blacklight.rb +2 -2
- data/lib/generators/blacklight/assets/importmap_generator.rb +2 -2
- data/lib/generators/blacklight/assets_generator.rb +1 -1
- data/lib/generators/blacklight/controller_generator.rb +1 -1
- data/lib/generators/blacklight/document_generator.rb +1 -1
- data/lib/generators/blacklight/install_generator.rb +6 -4
- data/lib/generators/blacklight/models_generator.rb +1 -1
- data/lib/generators/blacklight/search_builder_generator.rb +1 -1
- data/lib/generators/blacklight/solr_generator.rb +1 -1
- data/lib/generators/blacklight/templates/catalog_controller.rb +20 -1
- data/lib/generators/blacklight/templates/solr/conf/schema.xml +264 -178
- data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +6 -14
- data/lib/generators/blacklight/test_support_generator.rb +1 -1
- data/lib/generators/blacklight/user_generator.rb +66 -5
- data/lib/railties/blacklight.rake +4 -4
- data/package.json +2 -2
- data/spec/components/blacklight/document/action_component_spec.rb +1 -1
- data/spec/components/blacklight/document/group_component_spec.rb +1 -1
- data/spec/components/blacklight/document_component_spec.rb +9 -9
- data/spec/components/blacklight/facet_component_spec.rb +2 -2
- data/spec/components/blacklight/facets/index_navigation_component_spec.rb +1 -2
- data/spec/components/blacklight/facets/list_component_spec.rb +1 -1
- data/spec/components/blacklight/facets/suggest_component_spec.rb +1 -2
- data/spec/components/blacklight/metadata_field_component_spec.rb +26 -0
- data/spec/components/blacklight/skip_link_component_spec.rb +2 -2
- data/spec/controllers/application_controller_spec.rb +71 -0
- data/spec/controllers/bookmarks_controller_spec.rb +18 -5
- data/spec/controllers/catalog_controller_spec.rb +7 -5
- data/spec/features/advanced_search_spec.rb +29 -16
- data/spec/features/alternate_controller_spec.rb +4 -4
- data/spec/features/axe_spec.rb +34 -22
- data/spec/features/bookmarks_spec.rb +13 -13
- data/spec/features/dark_mode_spec.rb +42 -0
- data/spec/features/did_you_mean_spec.rb +27 -27
- data/spec/features/facet_missing_spec.rb +3 -3
- data/spec/features/record_view_spec.rb +14 -14
- data/spec/features/search_context_spec.rb +8 -8
- data/spec/features/search_filters_spec.rb +16 -16
- data/spec/features/search_formats_spec.rb +2 -2
- data/spec/features/search_history_spec.rb +11 -11
- data/spec/features/search_pagination_spec.rb +17 -17
- data/spec/features/search_results_spec.rb +3 -3
- data/spec/features/search_sort_spec.rb +4 -4
- data/spec/features/search_spec.rb +20 -20
- data/spec/helpers/blacklight/url_helper_behavior_spec.rb +15 -15
- data/spec/helpers/blacklight_helper_spec.rb +1 -1
- data/spec/helpers/catalog_helper_spec.rb +7 -7
- data/spec/integration/generators/blacklight/user_generator_spec.rb +60 -0
- data/spec/lib/blacklight/search_state/pivot_filter_field_spec.rb +1 -1
- data/spec/models/blacklight/configurable_spec.rb +1 -1
- data/spec/models/blacklight/configuration_spec.rb +0 -19
- data/spec/models/blacklight/document/dublin_core_spec.rb +2 -2
- data/spec/models/blacklight/facet_paginator_spec.rb +1 -1
- data/spec/models/blacklight/search_builder_spec.rb +15 -3
- data/spec/models/blacklight/solr/repository_spec.rb +10 -2
- data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +3 -5
- data/spec/models/blacklight/user_spec.rb +32 -5
- data/spec/models/bookmark_spec.rb +1 -1
- data/spec/models/record_mailer_spec.rb +8 -8
- data/spec/models/search_spec.rb +1 -1
- data/spec/models/solr_document_spec.rb +4 -0
- data/spec/presenters/blacklight/index_presenter_spec.rb +1 -0
- data/spec/presenters/blacklight/rendering/pipeline_spec.rb +1 -0
- data/spec/presenters/blacklight/show_presenter_spec.rb +1 -0
- data/spec/presenters/blacklight/thumbnail_presenter_spec.rb +1 -0
- data/spec/services/blacklight/search_service_spec.rb +7 -7
- data/spec/spec_helper.rb +3 -12
- data/spec/support/features/session_helpers.rb +13 -4
- data/spec/support/features/turbo_helpers.rb +13 -0
- data/spec/support/features.rb +2 -0
- data/spec/support/user_helpers.rb +24 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- data/spec/views/catalog/_document.html.erb_spec.rb +4 -4
- data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -2
- data/spec/views/catalog/_sort_and_per_page.html.erb_spec.rb +5 -5
- data/spec/views/catalog/index.html.erb_spec.rb +2 -2
- data/spec/views/catalog/show.html.erb_spec.rb +3 -4
- data/spec/views/shared/_user_util_links.html.erb_spec.rb +56 -0
- data/template.demo.rb +2 -1
- metadata +30 -22
- data/.hound.yml +0 -4
- data/.jshintrc +0 -22
- data/app/assets/images/blacklight/logo.png +0 -0
|
@@ -137,15 +137,23 @@ RSpec.describe Blacklight::SearchBuilder, :api do
|
|
|
137
137
|
|
|
138
138
|
describe "#page" do
|
|
139
139
|
it "is the current user parameter page number" do
|
|
140
|
-
expect(subject.with(page: 2).
|
|
140
|
+
expect(subject.with(page: 2).page).to eq 2
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "is page 1 if not page number given" do
|
|
144
|
-
expect(subject.
|
|
144
|
+
expect(subject.page).to eq 1
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
it "coerces parameters to integers" do
|
|
148
|
-
expect(subject.with(page: '2b').
|
|
148
|
+
expect(subject.with(page: '2b').page).to eq 2
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'sets the page number' do
|
|
152
|
+
expect(subject.page(3).page).to eq 3
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'gracefully handles setting the page number with a nil value' do
|
|
156
|
+
expect(subject.page(nil).page).to eq 1
|
|
149
157
|
end
|
|
150
158
|
end
|
|
151
159
|
|
|
@@ -160,6 +168,10 @@ RSpec.describe Blacklight::SearchBuilder, :api do
|
|
|
160
168
|
expect(subject.rows(17).rows).to eq 17
|
|
161
169
|
end
|
|
162
170
|
|
|
171
|
+
it "gracefully hnadles setting the number of rows to a nil value" do
|
|
172
|
+
expect(subject.rows(nil).rows).to eq 10
|
|
173
|
+
end
|
|
174
|
+
|
|
163
175
|
it "is the per_page parameter" do
|
|
164
176
|
expect(subject.with(per_page: 5).rows).to eq 5
|
|
165
177
|
end
|
|
@@ -160,7 +160,11 @@ RSpec.describe Blacklight::Solr::Repository, :api do
|
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
describe "setting to post" do
|
|
163
|
-
let
|
|
163
|
+
let(:blacklight_config) do
|
|
164
|
+
config = Blacklight::Configuration.new
|
|
165
|
+
config.http_method = :post
|
|
166
|
+
config
|
|
167
|
+
end
|
|
164
168
|
|
|
165
169
|
it "keep value set to post" do
|
|
166
170
|
expect(blacklight_config.http_method).to eq :post
|
|
@@ -210,7 +214,11 @@ RSpec.describe Blacklight::Solr::Repository, :api do
|
|
|
210
214
|
end
|
|
211
215
|
|
|
212
216
|
describe "http_method configuration", :integration do
|
|
213
|
-
let
|
|
217
|
+
let(:blacklight_config) do
|
|
218
|
+
config = Blacklight::Configuration.new
|
|
219
|
+
config.http_method = :post
|
|
220
|
+
config
|
|
221
|
+
end
|
|
214
222
|
|
|
215
223
|
it "sends a post request to solr and get a response back" do
|
|
216
224
|
response = subject.search(params: { q: all_docs_query })
|
|
@@ -524,13 +524,11 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, :api do
|
|
|
524
524
|
end
|
|
525
525
|
|
|
526
526
|
describe "#add_facets_for_advanced_search_form" do
|
|
527
|
+
let(:user_params) do
|
|
528
|
+
Blacklight::SearchState.new({}, blacklight_config, mock_controller)
|
|
529
|
+
end
|
|
527
530
|
let(:solr_parameters) { Blacklight::Solr::Request.new }
|
|
528
531
|
let(:mock_controller) { instance_double(CatalogController, action_name: 'advanced_search') }
|
|
529
|
-
let(:mock_search_state) { instance_double(Blacklight::SearchState, controller: mock_controller) }
|
|
530
|
-
|
|
531
|
-
before do
|
|
532
|
-
allow(search_builder).to receive(:search_state).and_return(mock_search_state)
|
|
533
|
-
end
|
|
534
532
|
|
|
535
533
|
context "when action is advanced_search and form_solr_parameters are configured" do
|
|
536
534
|
before do
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
RSpec.describe "Blacklight::User", :api do
|
|
4
|
-
subject {
|
|
4
|
+
subject { create_user email: 'xyz@example.com', password: 'xyz12345' }
|
|
5
5
|
|
|
6
6
|
def mock_bookmark document_id
|
|
7
7
|
Bookmark.new document_id: document_id, document_type: SolrDocument.to_s
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
describe ".blacklight_email_column" do
|
|
11
|
+
it "returns the email column the model actually has" do
|
|
12
|
+
expected = User.column_names.include?("email_address") ? :email_address : :email
|
|
13
|
+
expect(User.blacklight_email_column).to eq expected
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe ".create_guest_user!" do
|
|
18
|
+
it "creates a persisted user with a generated, unique identifier" do
|
|
19
|
+
guest = User.create_guest_user!
|
|
20
|
+
|
|
21
|
+
expect(guest).to be_persisted
|
|
22
|
+
expect(guest.public_send(User.blacklight_email_column)).to match(/^guest_.*@example\.com$/)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "generates a distinct identifier each time" do
|
|
26
|
+
one = User.create_guest_user!
|
|
27
|
+
two = User.create_guest_user!
|
|
28
|
+
|
|
29
|
+
expect(one.public_send(User.blacklight_email_column))
|
|
30
|
+
.not_to eq(two.public_send(User.blacklight_email_column))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
10
34
|
describe "#bookmarks_for_documents" do
|
|
11
35
|
before do
|
|
12
36
|
subject.bookmarks << mock_bookmark(1)
|
|
@@ -47,12 +71,15 @@ RSpec.describe "Blacklight::User", :api do
|
|
|
47
71
|
end
|
|
48
72
|
|
|
49
73
|
describe '#to_s' do
|
|
50
|
-
it 'is the
|
|
51
|
-
|
|
74
|
+
it 'is the configured display key by default' do
|
|
75
|
+
display_key = User.column_names.include?("email_address") ? :email_address : :email
|
|
76
|
+
|
|
77
|
+
expect(subject.to_s).to eq subject.public_send(display_key)
|
|
52
78
|
end
|
|
53
79
|
|
|
54
|
-
context 'when no
|
|
55
|
-
let(:
|
|
80
|
+
context 'when no configured display key method is provided' do
|
|
81
|
+
let(:display_key) { User.column_names.include?("email_address") ? :email_address : :email }
|
|
82
|
+
let(:old_method) { subject.class.instance_method(display_key) }
|
|
56
83
|
|
|
57
84
|
before do
|
|
58
85
|
subject.class.send(:undef_method, old_method.name)
|
|
@@ -37,11 +37,11 @@ RSpec.describe RecordMailer do
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "starts the subject w/ Item Record:" do
|
|
40
|
-
expect(email.subject).to match
|
|
40
|
+
expect(email.subject).to match(/^Item Record:/)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "puts the title of the item in the subject" do
|
|
44
|
-
expect(email.subject).to
|
|
44
|
+
expect(email.subject).to include('The horn')
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "has the correct from address (w/o the port number)" do
|
|
@@ -49,9 +49,9 @@ RSpec.describe RecordMailer do
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
it "prints out the correct body" do
|
|
52
|
-
expect(email.body).to
|
|
53
|
-
expect(email.body).to
|
|
54
|
-
expect(email.body).to match
|
|
52
|
+
expect(email.body).to include('Title: The horn')
|
|
53
|
+
expect(email.body).to include('Author: Janetzky, Kurt')
|
|
54
|
+
expect(email.body).to match(/projectblacklight.org/)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it "uses https URLs when protocol is set" do
|
|
@@ -104,9 +104,9 @@ RSpec.describe RecordMailer do
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "prints out the correct body" do
|
|
107
|
-
expect(@sms.body).to
|
|
108
|
-
expect(@sms.body).to
|
|
109
|
-
expect(@sms.body).to match
|
|
107
|
+
expect(@sms.body).to include('Title: The horn')
|
|
108
|
+
expect(@sms.body).to include('Author: Janetzky, Kurt')
|
|
109
|
+
expect(@sms.body).to match(/projectblacklight.org:3000/)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
it "uses https URL when protocol is set" do
|
data/spec/models/search_spec.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
RSpec.describe Search do
|
|
4
4
|
let(:search) { described_class.new(user: user) }
|
|
5
|
-
let(:user) {
|
|
5
|
+
let(:user) { create_user email: 'xyz@example.com', password: 'xyz12345' }
|
|
6
6
|
let(:hash_params) { { q: "query", f: { facet: "filter" } } }
|
|
7
7
|
let(:query_params) { hash_params }
|
|
8
8
|
|
|
@@ -54,6 +54,7 @@ RSpec.describe SolrDocument, :api do
|
|
|
54
54
|
attribute :first_author, :select, 'author_tesim', by: :min
|
|
55
55
|
attribute :date, :date, field: 'date_dtsi'
|
|
56
56
|
attribute :time, :time, field: 'date_dtsi'
|
|
57
|
+
attribute :details, :json, 'details_ssi'
|
|
57
58
|
attribute :whatever, :string, default: ->(*) { 'default_value' }
|
|
58
59
|
end
|
|
59
60
|
end
|
|
@@ -61,6 +62,7 @@ RSpec.describe SolrDocument, :api do
|
|
|
61
62
|
doc_class.new(id: '123',
|
|
62
63
|
title_tesim: ['Good Omens'],
|
|
63
64
|
author_tesim: ['Neil Gaiman', 'Terry Pratchett'],
|
|
65
|
+
details_ssi: '{"pages":288}',
|
|
64
66
|
date_dtsi: '1990-01-01T17:23:13Z')
|
|
65
67
|
end
|
|
66
68
|
|
|
@@ -72,6 +74,8 @@ RSpec.describe SolrDocument, :api do
|
|
|
72
74
|
expect(document.date.to_s).to eq '1990-01-01'
|
|
73
75
|
expect(document.time).to be_a Time
|
|
74
76
|
expect(document.time.to_s).to eq '1990-01-01 17:23:13 UTC'
|
|
77
|
+
expect(document.details).to be_a Hash
|
|
78
|
+
expect(document.details).to eq({ 'pages' => 288 })
|
|
75
79
|
expect(document.whatever).to eq 'default_value'
|
|
76
80
|
end
|
|
77
81
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
RSpec.describe Blacklight::ThumbnailPresenter do
|
|
4
4
|
include Capybara::RSpecMatchers
|
|
5
|
+
|
|
5
6
|
let(:view_context) { double "View context" }
|
|
6
7
|
let(:config) { Blacklight::Configuration.new.view_config(:index) }
|
|
7
8
|
let(:presenter) { described_class.new(document, view_context, config) }
|
|
@@ -145,7 +145,7 @@ RSpec.describe Blacklight::SearchService, :api do
|
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
it 'has all facets specified in initializer' do
|
|
148
|
-
expect(@facets.keys).to include
|
|
148
|
+
expect(@facets.keys).to include(*blacklight_config.facet_fields.keys)
|
|
149
149
|
expect(@facets.none? { |_k, v| v.nil? }).to be true
|
|
150
150
|
end
|
|
151
151
|
|
|
@@ -379,40 +379,40 @@ RSpec.describe Blacklight::SearchService, :api do
|
|
|
379
379
|
end
|
|
380
380
|
|
|
381
381
|
it "returns the previous and next documents for a search" do
|
|
382
|
-
_response, docs = service.previous_and_next_documents_for_search(4, q: '')
|
|
382
|
+
_response, docs = service.previous_and_next_documents_for_search(4, { q: '' })
|
|
383
383
|
|
|
384
384
|
expect(docs.first.id).to eq @full_response.documents[3].id
|
|
385
385
|
expect(docs.last.id).to eq @full_response.documents[5].id
|
|
386
386
|
end
|
|
387
387
|
|
|
388
388
|
it "returns only the next document if the counter is 0" do
|
|
389
|
-
_response, docs = service.previous_and_next_documents_for_search(0, q: '')
|
|
389
|
+
_response, docs = service.previous_and_next_documents_for_search(0, { q: '' })
|
|
390
390
|
|
|
391
391
|
expect(docs.first).to be_nil
|
|
392
392
|
expect(docs.last.id).to eq @full_response.documents[1].id
|
|
393
393
|
end
|
|
394
394
|
|
|
395
395
|
it "returns only the previous document if the counter is the total number of documents" do
|
|
396
|
-
_response, docs = service.previous_and_next_documents_for_search(@full_response.total - 1, q: '')
|
|
396
|
+
_response, docs = service.previous_and_next_documents_for_search(@full_response.total - 1, { q: '' })
|
|
397
397
|
expect(docs.first.id).to eq @full_response.documents.slice(-2).id
|
|
398
398
|
expect(docs.last).to be_nil
|
|
399
399
|
end
|
|
400
400
|
|
|
401
401
|
it "returns an array of nil values if there is only one result" do
|
|
402
|
-
_response, docs = service.previous_and_next_documents_for_search(0, q: 'id:2007020969')
|
|
402
|
+
_response, docs = service.previous_and_next_documents_for_search(0, { q: 'id:2007020969' })
|
|
403
403
|
expect(docs.last).to be_nil
|
|
404
404
|
expect(docs.first).to be_nil
|
|
405
405
|
end
|
|
406
406
|
|
|
407
407
|
it 'returns only the unique key by default' do
|
|
408
|
-
_response, docs = service.previous_and_next_documents_for_search(0, q: '')
|
|
408
|
+
_response, docs = service.previous_and_next_documents_for_search(0, { q: '' })
|
|
409
409
|
expect(docs.last.to_h).to eq 'id' => @full_response.documents[1].id
|
|
410
410
|
end
|
|
411
411
|
|
|
412
412
|
it 'allows the query parameters to be customized using configuration' do
|
|
413
413
|
blacklight_config.document_pagination_params[:fl] = 'id,format'
|
|
414
414
|
|
|
415
|
-
_response, docs = service.previous_and_next_documents_for_search(0, q: '')
|
|
415
|
+
_response, docs = service.previous_and_next_documents_for_search(0, { q: '' })
|
|
416
416
|
|
|
417
417
|
expect(docs.last.to_h).to eq @full_response.documents[1].to_h.slice('id', 'format')
|
|
418
418
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -48,25 +48,16 @@ RSpec.configure do |config|
|
|
|
48
48
|
# When we're testing the API, only run the api tests
|
|
49
49
|
config.filter_run api: true if ENV['BLACKLIGHT_API_TEST'].present?
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
config.fixture_paths = [Rails.root.join("spec/fixtures")]
|
|
53
|
-
else
|
|
54
|
-
config.fixture_path = Rails.root.join("spec/fixtures")
|
|
55
|
-
end
|
|
51
|
+
config.fixture_paths = [Rails.root.join("spec/fixtures")]
|
|
56
52
|
|
|
57
53
|
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
58
54
|
# examples within a transaction, remove the following line or assign false
|
|
59
55
|
# instead of true.
|
|
60
56
|
config.use_transactional_fixtures = true
|
|
61
57
|
|
|
62
|
-
if defined? Devise::Test::ControllerHelpers
|
|
63
|
-
config.include Devise::Test::ControllerHelpers, type: :controller
|
|
64
|
-
else
|
|
65
|
-
config.include Devise::TestHelpers, type: :controller
|
|
66
|
-
config.include Devise::TestHelpers, type: :i18n
|
|
67
|
-
end
|
|
68
|
-
|
|
69
58
|
config.infer_spec_type_from_file_location!
|
|
59
|
+
config.include UserHelpers
|
|
60
|
+
config.include Devise::Test::ControllerHelpers, type: :controller if defined?(Devise)
|
|
70
61
|
config.include PresenterTestHelpers, type: :presenter
|
|
71
62
|
config.include ViewComponent::TestHelpers, type: :component
|
|
72
63
|
config.include ViewComponentTestHelpers, type: :component
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
module Features
|
|
5
5
|
module SessionHelpers
|
|
6
6
|
def sign_up_with(email, password)
|
|
7
|
+
return create_user(email: email, password: password) if respond_to?(:new_session_path)
|
|
8
|
+
|
|
7
9
|
Capybara.exact = true
|
|
8
10
|
visit new_user_registration_path
|
|
9
11
|
fill_in 'Email', with: email
|
|
@@ -14,10 +16,17 @@ module Features
|
|
|
14
16
|
|
|
15
17
|
def sign_in(login = 'user1')
|
|
16
18
|
email = "#{login}@#{login}.com"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
create_user(email: email, password: "password")
|
|
20
|
+
|
|
21
|
+
if respond_to?(:new_session_path)
|
|
22
|
+
visit new_session_path
|
|
23
|
+
fill_in("email_address", with: email)
|
|
24
|
+
fill_in("password", with: "password")
|
|
25
|
+
else
|
|
26
|
+
visit new_user_session_path
|
|
27
|
+
fill_in("user_email", with: email)
|
|
28
|
+
fill_in("user_password", with: "password")
|
|
29
|
+
end
|
|
21
30
|
|
|
22
31
|
if has_button? "Sign in"
|
|
23
32
|
click_on("Sign in")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# spec/support/features/turbo_helpers.rb
|
|
4
|
+
module Features
|
|
5
|
+
module TurboHelpers
|
|
6
|
+
# Turbo Drive marks the document as busy for the duration of a visit. Capybara
|
|
7
|
+
# clicks return before the visit completes, so wait for the busy state to clear
|
|
8
|
+
# before making assertions that don't wait on their own (e.g. be_axe_clean).
|
|
9
|
+
def wait_for_turbo
|
|
10
|
+
expect(page).to have_no_css('html[aria-busy]', visible: :all)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/spec/support/features.rb
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
require File.expand_path('features/search_helpers.rb', __dir__)
|
|
6
6
|
require File.expand_path('features/session_helpers.rb', __dir__)
|
|
7
|
+
require File.expand_path('features/turbo_helpers.rb', __dir__)
|
|
7
8
|
|
|
8
9
|
RSpec.configure do |config|
|
|
9
10
|
config.include Features::SearchHelpers, type: :feature
|
|
10
11
|
config.include Features::SessionHelpers, type: :feature
|
|
12
|
+
config.include Features::TurboHelpers, type: :feature
|
|
11
13
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module UserHelpers
|
|
4
|
+
def build_user(attributes = {})
|
|
5
|
+
User.new(user_attributes(attributes))
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def create_user(attributes = {})
|
|
9
|
+
User.create!(user_attributes(attributes))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def user_attributes(attributes = {})
|
|
13
|
+
attributes = attributes.dup
|
|
14
|
+
password = attributes.delete(:password) || "password"
|
|
15
|
+
email = attributes.delete(:email) || attributes.delete(:email_address) || "user@example.com"
|
|
16
|
+
email_attribute = User.column_names.include?("email_address") ? :email_address : :email
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
email_attribute => email,
|
|
20
|
+
password: password,
|
|
21
|
+
password_confirmation: attributes.delete(:password_confirmation) || password
|
|
22
|
+
}.merge(attributes)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -15,7 +15,7 @@ class TestAppGenerator < Rails::Generators::Base
|
|
|
15
15
|
Bundler.with_unbundled_env do
|
|
16
16
|
run "bundle install"
|
|
17
17
|
end
|
|
18
|
-
options = '--devise'
|
|
18
|
+
options = Rails.gem_version >= Gem::Version.new('8.0.0') ? '--authentication' : '--devise'
|
|
19
19
|
if ENV['BLACKLIGHT_API_TEST'].present?
|
|
20
20
|
options += ' --skip-assets'
|
|
21
21
|
end
|
|
@@ -17,9 +17,9 @@ RSpec.describe "catalog/_document" do
|
|
|
17
17
|
stub_template "catalog/_b_default.html.erb" => "b_partial"
|
|
18
18
|
stub_template "catalog/_c_default.html.erb" => "c_partial"
|
|
19
19
|
render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.index }
|
|
20
|
-
expect(rendered).to
|
|
21
|
-
expect(rendered).to
|
|
22
|
-
expect(rendered).to
|
|
20
|
+
expect(rendered).to include('a_partial')
|
|
21
|
+
expect(rendered).to include('b_partial')
|
|
22
|
+
expect(rendered).to include('c_partial')
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
context 'with a configured document component' do
|
|
@@ -39,7 +39,7 @@ RSpec.describe "catalog/_document" do
|
|
|
39
39
|
|
|
40
40
|
it 'renders the document component' do
|
|
41
41
|
render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: blacklight_config.index }
|
|
42
|
-
expect(rendered).to
|
|
42
|
+
expect(rendered).to include('blah')
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
RSpec.describe "catalog/_paginate_compact.html.erb" do
|
|
4
|
-
let(:user) {
|
|
4
|
+
let(:user) { create_user }
|
|
5
5
|
let(:blacklight_config) { Blacklight::Configuration.new }
|
|
6
6
|
|
|
7
7
|
before do
|
|
@@ -16,7 +16,7 @@ RSpec.describe "catalog/_paginate_compact.html.erb" do
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "renders ActiveRecord collections" do
|
|
19
|
-
50.times {
|
|
19
|
+
50.times { Bookmark.create!(user: user) }
|
|
20
20
|
render partial: 'catalog/paginate_compact', object: Bookmark.page(1).per(25)
|
|
21
21
|
expect(rendered).to have_css ".page-entries"
|
|
22
22
|
expect(rendered).to have_css "a[@rel=next]"
|
|
@@ -17,10 +17,10 @@ RSpec.describe "catalog/_sort_and_per_page" do
|
|
|
17
17
|
stub_template "catalog/_per_page_widget.html.erb" => "per_page_widget"
|
|
18
18
|
stub_template "catalog/_view_type_group.html.erb" => "view_type_group"
|
|
19
19
|
render
|
|
20
|
-
expect(rendered).to
|
|
21
|
-
expect(rendered).to
|
|
22
|
-
expect(rendered).to
|
|
23
|
-
expect(rendered).to
|
|
20
|
+
expect(rendered).to include('paginate_compact')
|
|
21
|
+
expect(rendered).to include('sort_widget')
|
|
22
|
+
expect(rendered).to include('per_page_widget')
|
|
23
|
+
expect(rendered).to include('view_type_group')
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "does not render the pagination controls with bad limit values" do
|
|
@@ -30,6 +30,6 @@ RSpec.describe "catalog/_sort_and_per_page" do
|
|
|
30
30
|
stub_template "catalog/_per_page_widget.html.erb" => "per_page_widget"
|
|
31
31
|
stub_template "catalog/_view_type_group.html.erb" => "view_type_group"
|
|
32
32
|
render
|
|
33
|
-
expect(rendered).not_to
|
|
33
|
+
expect(rendered).not_to include('paginate_compact')
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -12,7 +12,7 @@ RSpec.describe "catalog/index.html.erb" do
|
|
|
12
12
|
it "renders the Search::SidebarComponent component" do
|
|
13
13
|
render
|
|
14
14
|
|
|
15
|
-
expect(sidebar).to
|
|
15
|
+
expect(sidebar).to include('Limit your search')
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ RSpec.describe "catalog/index.html.erb" do
|
|
|
31
31
|
|
|
32
32
|
it "renders the search_header partial" do
|
|
33
33
|
render
|
|
34
|
-
expect(rendered).to
|
|
34
|
+
expect(rendered).to include('sortAndPerPage')
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -9,7 +9,6 @@ RSpec.describe "catalog/show.html.erb" do
|
|
|
9
9
|
allow(presenter).to receive(:html_title).and_return('Heading')
|
|
10
10
|
allow(document).to receive(:more_like_this).and_return([])
|
|
11
11
|
allow(view).to receive_messages(has_user_authentication_provider?: false)
|
|
12
|
-
allow(view).to receive_messages(render_document_sidebar_partial: "Sidebar")
|
|
13
12
|
allow(view).to receive_messages(current_search_session: nil, search_session: {})
|
|
14
13
|
assign :document, document
|
|
15
14
|
allow(view).to receive_messages(document_presenter: presenter, action_name: 'show', blacklight_config: blacklight_config)
|
|
@@ -36,8 +35,8 @@ RSpec.describe "catalog/show.html.erb" do
|
|
|
36
35
|
stub_template "catalog/_b_default.html.erb" => "b_partial"
|
|
37
36
|
stub_template "catalog/_c_default.html.erb" => "c_partial"
|
|
38
37
|
render
|
|
39
|
-
expect(rendered).to
|
|
40
|
-
expect(rendered).to
|
|
41
|
-
expect(rendered).to
|
|
38
|
+
expect(rendered).to include('a_partial')
|
|
39
|
+
expect(rendered).to include('b_partial')
|
|
40
|
+
expect(rendered).to include('c_partial')
|
|
42
41
|
end
|
|
43
42
|
end
|
|
@@ -7,6 +7,10 @@ RSpec.describe "shared/_user_util_links" do
|
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
before do
|
|
11
|
+
allow(controller).to receive(:render_bookmarks_control?).and_return false
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
it "renders the correct bookmark count" do
|
|
11
15
|
count = rand(99)
|
|
12
16
|
allow(controller).to receive(:render_bookmarks_control?).and_return true
|
|
@@ -15,4 +19,56 @@ RSpec.describe "shared/_user_util_links" do
|
|
|
15
19
|
render "shared/user_util_links"
|
|
16
20
|
expect(rendered).to have_css('#bookmarks_nav span.badge[data-role=bookmark-counter]', text: count.to_s)
|
|
17
21
|
end
|
|
22
|
+
|
|
23
|
+
it "renders Rails authentication session links" do
|
|
24
|
+
user = instance_double(User, to_s: "xyz@example.com")
|
|
25
|
+
|
|
26
|
+
allow(view).to receive_messages(
|
|
27
|
+
blacklight_account_path: nil,
|
|
28
|
+
blacklight_config: blacklight_config,
|
|
29
|
+
blacklight_login_path: "/session/new",
|
|
30
|
+
blacklight_logout_link_options: { data: { turbo_method: :delete } },
|
|
31
|
+
blacklight_logout_path: "/session",
|
|
32
|
+
current_user: user,
|
|
33
|
+
has_user_authentication_provider?: true
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
render "shared/user_util_links"
|
|
37
|
+
|
|
38
|
+
expect(rendered).to have_link("Log Out", href: "/session")
|
|
39
|
+
expect(rendered).to have_css('a[data-turbo-method="delete"]', text: "Log Out")
|
|
40
|
+
expect(rendered).to have_no_link("xyz@example.com")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "renders Devise-compatible session and registration links" do
|
|
44
|
+
user = instance_double(User, to_s: "xyz@example.com")
|
|
45
|
+
|
|
46
|
+
allow(view).to receive_messages(
|
|
47
|
+
blacklight_account_path: "/users/edit",
|
|
48
|
+
blacklight_config: blacklight_config,
|
|
49
|
+
blacklight_login_path: "/users/sign_in",
|
|
50
|
+
blacklight_logout_link_options: {},
|
|
51
|
+
blacklight_logout_path: "/users/sign_out",
|
|
52
|
+
current_user: user,
|
|
53
|
+
has_user_authentication_provider?: true
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
render "shared/user_util_links"
|
|
57
|
+
|
|
58
|
+
expect(rendered).to have_link("Log Out", href: "/users/sign_out")
|
|
59
|
+
expect(rendered).to have_link("xyz@example.com", href: "/users/edit")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "renders a provider-neutral login link" do
|
|
63
|
+
allow(view).to receive_messages(
|
|
64
|
+
blacklight_config: blacklight_config,
|
|
65
|
+
blacklight_login_path: "/session/new",
|
|
66
|
+
current_user: nil,
|
|
67
|
+
has_user_authentication_provider?: true
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
render "shared/user_util_links"
|
|
71
|
+
|
|
72
|
+
expect(rendered).to have_link("Login", href: "/session/new")
|
|
73
|
+
end
|
|
18
74
|
end
|
data/template.demo.rb
CHANGED
|
@@ -4,7 +4,8 @@ gem 'blacklight', '>= 7.0'
|
|
|
4
4
|
|
|
5
5
|
after_bundle do
|
|
6
6
|
# run the blacklight install generator
|
|
7
|
-
|
|
7
|
+
default_authentication_option = Rails.gem_version >= Gem::Version.new('8.0.0') ? '--authentication' : '--devise'
|
|
8
|
+
options = ENV.fetch("BLACKLIGHT_INSTALL_OPTIONS", "#{default_authentication_option} --marc")
|
|
8
9
|
|
|
9
10
|
generate 'blacklight:install', options
|
|
10
11
|
|