blacklight-access_controls 0.6.2 → 0.7.0.rc1

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.
@@ -337,9 +337,6 @@
337
337
  <!-- field for the QueryParser to use when an explicit fieldname is absent -->
338
338
  <!-- <defaultSearchField>text</defaultSearchField> -->
339
339
 
340
- <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
341
- <solrQueryParser defaultOperator="OR"/>
342
-
343
340
  <!-- copyField commands copy one field to another at the time a document
344
341
  is added to the index. It's used either to index the same field differently,
345
342
  or to add multiple fields to the same field for easier/faster searching. -->
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- FactoryGirl.define do
3
+ FactoryBot.define do
4
4
  factory :user do
5
5
  sequence(:email) { |n| "user_#{n}@example.com" }
6
6
  password 'password'
@@ -7,13 +7,13 @@ EngineCart.load_application!
7
7
 
8
8
  require 'blacklight-access_controls'
9
9
 
10
- require 'factory_girl_rails'
10
+ require 'factory_bot_rails'
11
11
  require 'database_cleaner'
12
12
 
13
13
  Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
14
14
 
15
15
  RSpec.configure do |config|
16
- config.include FactoryGirl::Syntax::Methods
16
+ config.include FactoryBot::Syntax::Methods
17
17
 
18
18
  config.include SolrSupport
19
19
 
@@ -21,12 +21,12 @@ RSpec.configure do |config|
21
21
  DatabaseCleaner.clean_with :truncation
22
22
  end
23
23
 
24
- config.before(:each) do
24
+ config.before do
25
25
  DatabaseCleaner.strategy = :transaction
26
26
  DatabaseCleaner.start
27
27
  end
28
28
 
29
- config.after(:each) do
29
+ config.after do
30
30
  DatabaseCleaner.clean
31
31
  end
32
32
  end
@@ -3,38 +3,40 @@
3
3
  require 'cancan/matchers'
4
4
 
5
5
  describe Ability do
6
- let(:ability) { Ability.new(user) }
6
+ let(:ability) { described_class.new(user) }
7
7
 
8
8
  describe 'class methods' do
9
9
  it 'has keys for access control fields' do
10
- expect(Ability.read_group_field).to eq 'read_access_group_ssim'
11
- expect(Ability.read_user_field).to eq 'read_access_person_ssim'
12
- expect(Ability.discover_group_field).to eq 'discover_access_group_ssim'
13
- expect(Ability.discover_user_field).to eq 'discover_access_person_ssim'
14
- expect(Ability.download_group_field).to eq 'download_access_group_ssim'
15
- expect(Ability.download_user_field).to eq 'download_access_person_ssim'
10
+ expect(described_class.read_group_field).to eq 'read_access_group_ssim'
11
+ expect(described_class.read_user_field).to eq 'read_access_person_ssim'
12
+ expect(described_class.discover_group_field).to eq 'discover_access_group_ssim'
13
+ expect(described_class.discover_user_field).to eq 'discover_access_person_ssim'
14
+ expect(described_class.download_group_field).to eq 'download_access_group_ssim'
15
+ expect(described_class.download_user_field).to eq 'download_access_person_ssim'
16
16
  end
17
17
  end
18
18
 
19
19
  describe 'Given an asset that has been made publicly discoverable' do
20
- let(:asset) { SolrDocument.new(id: 'public_discovery',
21
- discover_access_group_ssim: ['public']) }
20
+ let(:asset) do
21
+ SolrDocument.new(id: 'public_discovery',
22
+ discover_access_group_ssim: ['public'])
23
+ end
22
24
 
23
25
  context 'Then a not-signed-in user' do
24
- let(:user) { nil }
25
-
26
26
  subject { ability }
27
27
 
28
+ let(:user) { nil }
29
+
28
30
  it { is_expected.to be_able_to(:discover, asset) }
29
31
  it { is_expected.not_to be_able_to(:read, asset) }
30
32
  it { is_expected.not_to be_able_to(:download, asset) }
31
33
  end
32
34
 
33
35
  context 'Then a registered user' do
34
- let(:user) { create(:user) }
35
-
36
36
  subject { ability }
37
37
 
38
+ let(:user) { create(:user) }
39
+
38
40
  it { is_expected.to be_able_to(:discover, asset) }
39
41
  it { is_expected.not_to be_able_to(:read, asset) }
40
42
  it { is_expected.not_to be_able_to(:download, asset) }
@@ -44,10 +46,10 @@ describe Ability do
44
46
  subject { ability }
45
47
 
46
48
  let(:user) { create(:user) }
47
- let(:asset) {
49
+ let(:asset) do
48
50
  create_solr_doc(id: 'public_discovery',
49
51
  discover_access_group_ssim: ['public'])
50
- }
52
+ end
51
53
 
52
54
  # It should still work, even if we just pass in an ID
53
55
  it { is_expected.to be_able_to(:discover, asset.id) }
@@ -57,24 +59,26 @@ describe Ability do
57
59
  end
58
60
 
59
61
  describe 'Given an asset that has been made publicly readable' do
60
- let(:asset) { SolrDocument.new(id: 'public_read',
61
- read_access_group_ssim: ['public']) }
62
+ let(:asset) do
63
+ SolrDocument.new(id: 'public_read',
64
+ read_access_group_ssim: ['public'])
65
+ end
62
66
 
63
67
  context 'Then a not-signed-in user' do
64
- let(:user) { nil }
65
-
66
68
  subject { ability }
67
69
 
70
+ let(:user) { nil }
71
+
68
72
  it { is_expected.to be_able_to(:discover, asset) }
69
73
  it { is_expected.to be_able_to(:read, asset) }
70
74
  it { is_expected.not_to be_able_to(:download, asset) }
71
75
  end
72
76
 
73
77
  context 'Then a registered user' do
74
- let(:user) { create(:user) }
75
-
76
78
  subject { ability }
77
79
 
80
+ let(:user) { create(:user) }
81
+
78
82
  it { is_expected.to be_able_to(:discover, asset) }
79
83
  it { is_expected.to be_able_to(:read, asset) }
80
84
  it { is_expected.not_to be_able_to(:download, asset) }
@@ -84,10 +88,10 @@ describe Ability do
84
88
  subject { ability }
85
89
 
86
90
  let(:user) { create(:user) }
87
- let(:asset) {
91
+ let(:asset) do
88
92
  create_solr_doc(id: 'public_read',
89
93
  read_access_group_ssim: ['public'])
90
- }
94
+ end
91
95
 
92
96
  # It should still work, even if we just pass in an ID
93
97
  it { is_expected.to be_able_to(:discover, asset.id) }
@@ -98,14 +102,16 @@ describe Ability do
98
102
 
99
103
  describe 'Given an asset that has been made publicly downloadable' do
100
104
  let(:id) { 'public_download' }
101
- let(:asset) { SolrDocument.new(id: id,
102
- download_access_group_ssim: ['public']) }
105
+ let(:asset) do
106
+ SolrDocument.new(id: id,
107
+ download_access_group_ssim: ['public'])
108
+ end
103
109
 
104
110
  context 'Then a not-signed-in user' do
105
- let(:user) { nil }
106
-
107
111
  subject { ability }
108
112
 
113
+ let(:user) { nil }
114
+
109
115
  it { is_expected.to be_able_to(:discover, asset) }
110
116
  it { is_expected.to be_able_to(:read, asset) }
111
117
  it { is_expected.to be_able_to(:download, asset) }
@@ -125,10 +131,10 @@ describe Ability do
125
131
  subject { ability }
126
132
 
127
133
  let(:user) { create(:user) }
128
- let(:asset) {
134
+ let(:asset) do
129
135
  create_solr_doc(id: id,
130
136
  download_access_group_ssim: ['public'])
131
- }
137
+ end
132
138
 
133
139
  # It should still work, even if we just pass in an ID
134
140
  it { is_expected.to be_able_to(:discover, asset.id) }
@@ -142,30 +148,30 @@ describe Ability do
142
148
  let(:asset) { SolrDocument.new(id: 'user_disco', discover_access_person_ssim: [user_with_access.email]) }
143
149
 
144
150
  context 'Then a not-signed-in user' do
145
- let(:user) { nil }
146
-
147
151
  subject { ability }
148
152
 
153
+ let(:user) { nil }
154
+
149
155
  it { is_expected.not_to be_able_to(:discover, asset) }
150
156
  it { is_expected.not_to be_able_to(:read, asset) }
151
157
  it { is_expected.not_to be_able_to(:download, asset) }
152
158
  end
153
159
 
154
160
  context 'Then a different registered user' do
155
- let(:user) { create(:user) }
156
-
157
161
  subject { ability }
158
162
 
163
+ let(:user) { create(:user) }
164
+
159
165
  it { is_expected.not_to be_able_to(:discover, asset) }
160
166
  it { is_expected.not_to be_able_to(:read, asset) }
161
167
  it { is_expected.not_to be_able_to(:download, asset) }
162
168
  end
163
169
 
164
170
  context 'Then that user' do
165
- let(:user) { user_with_access }
166
-
167
171
  subject { ability }
168
172
 
173
+ let(:user) { user_with_access }
174
+
169
175
  it { is_expected.to be_able_to(:discover, asset) }
170
176
  it { is_expected.not_to be_able_to(:read, asset) }
171
177
  it { is_expected.not_to be_able_to(:download, asset) }
@@ -177,30 +183,30 @@ describe Ability do
177
183
  let(:asset) { SolrDocument.new(id: 'user_read', read_access_person_ssim: [user_with_access.email]) }
178
184
 
179
185
  context 'Then a not-signed-in user' do
180
- let(:user) { nil }
181
-
182
186
  subject { ability }
183
187
 
188
+ let(:user) { nil }
189
+
184
190
  it { is_expected.not_to be_able_to(:discover, asset) }
185
191
  it { is_expected.not_to be_able_to(:read, asset) }
186
192
  it { is_expected.not_to be_able_to(:download, asset) }
187
193
  end
188
194
 
189
195
  context 'Then a different registered user' do
190
- let(:user) { create(:user) }
191
-
192
196
  subject { ability }
193
197
 
198
+ let(:user) { create(:user) }
199
+
194
200
  it { is_expected.not_to be_able_to(:discover, asset) }
195
201
  it { is_expected.not_to be_able_to(:read, asset) }
196
202
  it { is_expected.not_to be_able_to(:download, asset) }
197
203
  end
198
204
 
199
205
  context 'Then that user' do
200
- let(:user) { user_with_access }
201
-
202
206
  subject { ability }
203
207
 
208
+ let(:user) { user_with_access }
209
+
204
210
  it { is_expected.to be_able_to(:discover, asset) }
205
211
  it { is_expected.to be_able_to(:read, asset) }
206
212
  it { is_expected.not_to be_able_to(:download, asset) }
@@ -212,30 +218,30 @@ describe Ability do
212
218
  let(:asset) { SolrDocument.new(id: 'user_read', download_access_person_ssim: [user_with_access.email]) }
213
219
 
214
220
  context 'Then a not-signed-in user' do
215
- let(:user) { nil }
216
-
217
221
  subject { ability }
218
222
 
223
+ let(:user) { nil }
224
+
219
225
  it { is_expected.not_to be_able_to(:discover, asset) }
220
226
  it { is_expected.not_to be_able_to(:read, asset) }
221
227
  it { is_expected.not_to be_able_to(:download, asset) }
222
228
  end
223
229
 
224
230
  context 'Then a different registered user' do
225
- let(:user) { create(:user) }
226
-
227
231
  subject { ability }
228
232
 
233
+ let(:user) { create(:user) }
234
+
229
235
  it { is_expected.not_to be_able_to(:discover, asset) }
230
236
  it { is_expected.not_to be_able_to(:read, asset) }
231
237
  it { is_expected.not_to be_able_to(:download, asset) }
232
238
  end
233
239
 
234
240
  context 'Then that user' do
235
- let(:user) { user_with_access }
236
-
237
241
  subject { ability }
238
242
 
243
+ let(:user) { user_with_access }
244
+
239
245
  it { is_expected.to be_able_to(:discover, asset) }
240
246
  it { is_expected.to be_able_to(:read, asset) }
241
247
  it { is_expected.to be_able_to(:download, asset) }
@@ -249,13 +255,13 @@ describe Ability do
249
255
  end
250
256
 
251
257
  describe '#guest_user' do
252
- let(:user) { nil }
253
-
254
258
  subject { ability.guest_user }
255
259
 
260
+ let(:user) { nil }
261
+
256
262
  it 'is a new user' do
257
263
  expect(subject).to be_a User
258
- expect(subject.new_record?).to be_truthy
264
+ expect(subject).to be_new_record
259
265
  end
260
266
  end
261
267
 
@@ -275,17 +281,17 @@ describe Ability do
275
281
  end
276
282
 
277
283
  context 'a user with groups' do
278
- let(:user) { double(groups: %w(group1 group2), new_record?: false) }
284
+ let(:user) { double(groups: %w[group1 group2], new_record?: false) }
279
285
 
280
286
  it { is_expected.to include('group1', 'group2') }
281
287
  end
282
288
  end
283
289
 
284
290
  describe 'with a custom method' do
285
- let(:user) { create(:user) }
286
-
287
291
  subject { MyAbility.new(user) }
288
292
 
293
+ let(:user) { create(:user) }
294
+
289
295
  before do
290
296
  class MyAbility
291
297
  include Blacklight::AccessControls::Ability
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::AccessControls::SearchBuilder do
4
+ subject { search_builder }
5
+
6
+ let(:search_builder) do
7
+ described_class.new(controller, ability: ability)
8
+ end
9
+ let(:controller) { double }
10
+ let(:user) { User.new }
11
+ let(:ability) { Ability.new(user) }
12
+
13
+ describe '#discovery_permissions' do
14
+ subject { search_builder.default_permission_types }
15
+
16
+ it { is_expected.to eq %w[discover read] }
17
+ end
18
+
19
+ describe '#apply_gated_discovery' do
20
+ let(:fq_first) do
21
+ solr_parameters = {}
22
+ search_builder.send(:apply_gated_discovery, solr_parameters)
23
+ solr_parameters[:fq].first
24
+ end
25
+
26
+ describe 'logger' do
27
+ # Expectation will be triggered by Ability class (that calls Rails.logger.debug earlier). So we double Ability to avoid false positive.
28
+ let(:ability) { instance_double(Ability, user_groups: [], current_user: user) }
29
+
30
+ it 'is called with debug' do
31
+ expect(Rails.logger).to receive(:debug).with(/^Solr parameters/)
32
+ search_builder.send(:apply_gated_discovery, {})
33
+ end
34
+ end
35
+
36
+ context 'Given I am not logged in' do
37
+ it "Then I should be treated as a member of the 'public' group" do
38
+ expect(fq_first).to eq '({!terms f=discover_access_group_ssim}public) OR ({!terms f=read_access_group_ssim}public)'
39
+ end
40
+
41
+ it "Then I should not be treated as a member of the 'registered' group" do
42
+ expect(fq_first).not_to match(/registered/)
43
+ end
44
+ end
45
+
46
+ context 'Given I am a registered user' do
47
+ let(:groups) { %w[faculty africana-faculty] }
48
+ let(:user) do
49
+ create(:user).tap do |u|
50
+ allow(u).to receive(:groups) { groups }
51
+ end
52
+ end
53
+
54
+ it 'searches for my user key in discover and read fields' do
55
+ expect(fq_first).to match(/discover_access_person_ssim\:#{user.user_key}/)
56
+ expect(fq_first).to match(/read_access_person_ssim\:#{user.user_key}/)
57
+ end
58
+
59
+ it 'searches for my groups' do
60
+ expect(fq_first).to match(/\{!terms f=discover_access_group_ssim\}public,faculty,africana-faculty,registered/)
61
+ expect(fq_first).to match(/\{!terms f=read_access_group_ssim\}public,faculty,africana-faculty,registered/)
62
+ end
63
+
64
+ it 'does not build empty clauses' do
65
+ expect(search_builder).to receive(:apply_user_permissions).and_return(['({!terms f=discover_access_group_ssim}public,faculty,africana-faculty,registered)', '', nil])
66
+ expect(fq_first).not_to match(/ OR $/) # i.e. doesn't end w/ empty
67
+ end
68
+
69
+ context 'slashes in the group names' do
70
+ let(:groups) { ['abc/123', 'cde/567'] }
71
+
72
+ it 'does not escape slashes' do
73
+ expect(fq_first).to match(%r{\{!terms f=discover_access_group_ssim\}public,abc/123,cde/567,registered})
74
+ expect(fq_first).to match(%r{\{!terms f=read_access_group_ssim\}public,abc/123,cde/567,registered})
75
+ end
76
+ end
77
+
78
+ context 'spaces in the group names' do
79
+ let(:groups) { ['abc 123', 'cd/e 567'] }
80
+
81
+ it 'does not escape spaces in group names' do
82
+ expect(fq_first).to match(%r{\{!terms f=discover_access_group_ssim\}public,abc 123,cd/e 567,registered})
83
+ expect(fq_first).to match(%r{\{!terms f=read_access_group_ssim\}public,abc 123,cd/e 567,registered})
84
+ end
85
+ end
86
+
87
+ context 'colons in the groups names' do
88
+ let(:groups) { ['abc:123', 'cde:567'] }
89
+
90
+ it 'does not escape colons' do
91
+ expect(fq_first).to match(/\{!terms f=discover_access_group_ssim\}public,abc:123,cde:567,registered/)
92
+ expect(fq_first).to match(/\{!terms f=read_access_group_ssim\}public,abc:123,cde:567,registered/)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '#apply_user_permissions' do
99
+ describe 'when the user is a guest user (user key nil)' do
100
+ it 'does not create filters' do
101
+ expect(search_builder.send(:apply_user_permissions)).to eq []
102
+ end
103
+ end
104
+
105
+ describe 'when the user is a guest user (user key empty string)' do
106
+ let(:user) { User.new(email: '') }
107
+
108
+ it 'does not create filters' do
109
+ expect(search_builder.send(:apply_user_permissions)).to eq []
110
+ end
111
+ end
112
+ end
113
+ end