scimitar 2.2.0 → 2.4.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/app/controllers/scimitar/active_record_backed_resources_controller.rb +27 -7
- data/app/models/scimitar/resources/mixin.rb +73 -1
- data/lib/scimitar/version.rb +2 -2
- data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
- data/spec/apps/dummy/app/models/mock_group.rb +1 -1
- data/spec/apps/dummy/app/models/mock_user.rb +5 -3
- data/spec/apps/dummy/config/routes.rb +10 -6
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +2 -2
- data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +8 -3
- data/spec/apps/dummy/db/schema.rb +9 -7
- data/spec/models/scimitar/lists/query_parser_spec.rb +8 -8
- data/spec/models/scimitar/resources/mixin_spec.rb +657 -40
- data/spec/requests/active_record_backed_resources_controller_spec.rb +230 -48
- metadata +3 -5
- data/spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb +0 -5
@@ -5,11 +5,21 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
5
5
|
before :each do
|
6
6
|
allow_any_instance_of(Scimitar::ApplicationController).to receive(:authenticated?).and_return(true)
|
7
7
|
|
8
|
+
# If a sort order is unspecified, the controller defaults to ID ascending.
|
9
|
+
# With UUID based IDs, testing life is made easier by ensuring that the
|
10
|
+
# creation order matches an ascending UUID sort order (which is what would
|
11
|
+
# happen if we were using integer primary keys).
|
12
|
+
#
|
8
13
|
lmt = Time.parse("2023-01-09 14:25:00 +1300")
|
14
|
+
ids = 3.times.map { SecureRandom.uuid }.sort()
|
9
15
|
|
10
|
-
@u1 = MockUser.create(username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com', scim_uid: '001', created_at: lmt, updated_at: lmt + 1)
|
11
|
-
@u2 = MockUser.create(username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2)
|
12
|
-
@u3 = MockUser.create(username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com', scim_uid: '003', created_at: lmt, updated_at: lmt + 3)
|
16
|
+
@u1 = MockUser.create(primary_key: ids.shift(), username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com', scim_uid: '001', created_at: lmt, updated_at: lmt + 1)
|
17
|
+
@u2 = MockUser.create(primary_key: ids.shift(), username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2)
|
18
|
+
@u3 = MockUser.create(primary_key: ids.shift(), username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com', scim_uid: '003', created_at: lmt, updated_at: lmt + 3)
|
19
|
+
|
20
|
+
@g1 = MockGroup.create!(display_name: 'Group 1')
|
21
|
+
@g2 = MockGroup.create!(display_name: 'Group 2')
|
22
|
+
@g3 = MockGroup.create!(display_name: 'Group 3')
|
13
23
|
end
|
14
24
|
|
15
25
|
# ===========================================================================
|
@@ -32,21 +42,41 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
32
42
|
end # "context 'with no items' do"
|
33
43
|
|
34
44
|
context 'with items' do
|
35
|
-
|
36
|
-
|
45
|
+
context 'with a UUID, renamed primary key column' do
|
46
|
+
it 'returns all items' do
|
47
|
+
get '/Users', params: { format: :scim }
|
37
48
|
|
38
|
-
|
39
|
-
|
49
|
+
expect(response.status).to eql(200)
|
50
|
+
result = JSON.parse(response.body)
|
40
51
|
|
41
|
-
|
42
|
-
|
52
|
+
expect(result['totalResults']).to eql(3)
|
53
|
+
expect(result['Resources'].size).to eql(3)
|
43
54
|
|
44
|
-
|
45
|
-
|
55
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
56
|
+
expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s, @u3.primary_key.to_s])
|
46
57
|
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
59
|
+
expect(usernames).to match_array(['1', '2', '3'])
|
60
|
+
end
|
61
|
+
end # "context 'with a UUID, renamed primary key column' do"
|
62
|
+
|
63
|
+
context 'with an integer, conventionally named primary key column' do
|
64
|
+
it 'returns all items' do
|
65
|
+
get '/Groups', params: { format: :scim }
|
66
|
+
|
67
|
+
expect(response.status).to eql(200)
|
68
|
+
result = JSON.parse(response.body)
|
69
|
+
|
70
|
+
expect(result['totalResults']).to eql(3)
|
71
|
+
expect(result['Resources'].size).to eql(3)
|
72
|
+
|
73
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
74
|
+
expect(ids).to match_array([@g1.id.to_s, @g2.id.to_s, @g3.id.to_s])
|
75
|
+
|
76
|
+
usernames = result['Resources'].map { |resource| resource['displayName'] }
|
77
|
+
expect(usernames).to match_array(['Group 1', 'Group 2', 'Group 3'])
|
78
|
+
end
|
79
|
+
end # "context 'with an integer, conventionally named primary key column' do"
|
50
80
|
|
51
81
|
it 'applies a filter, with case-insensitive value comparison' do
|
52
82
|
get '/Users', params: {
|
@@ -61,7 +91,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
61
91
|
expect(result['Resources'].size).to eql(1)
|
62
92
|
|
63
93
|
ids = result['Resources'].map { |resource| resource['id'] }
|
64
|
-
expect(ids).to match_array([@u2.
|
94
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
65
95
|
|
66
96
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
67
97
|
expect(usernames).to match_array(['2'])
|
@@ -80,7 +110,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
80
110
|
expect(result['Resources'].size).to eql(1)
|
81
111
|
|
82
112
|
ids = result['Resources'].map { |resource| resource['id'] }
|
83
|
-
expect(ids).to match_array([@u2.
|
113
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
84
114
|
|
85
115
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
86
116
|
expect(usernames).to match_array(['2'])
|
@@ -93,7 +123,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
93
123
|
it 'applies a filter on primary keys, using direct comparison (rather than e.g. case-insensitive operators)' do
|
94
124
|
get '/Users', params: {
|
95
125
|
format: :scim,
|
96
|
-
filter: "id eq \"#{@u3.
|
126
|
+
filter: "id eq \"#{@u3.primary_key}\""
|
97
127
|
}
|
98
128
|
|
99
129
|
expect(response.status).to eql(200)
|
@@ -103,7 +133,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
103
133
|
expect(result['Resources'].size).to eql(1)
|
104
134
|
|
105
135
|
ids = result['Resources'].map { |resource| resource['id'] }
|
106
|
-
expect(ids).to match_array([@u3.
|
136
|
+
expect(ids).to match_array([@u3.primary_key.to_s])
|
107
137
|
|
108
138
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
109
139
|
expect(usernames).to match_array(['3'])
|
@@ -122,7 +152,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
122
152
|
expect(result['Resources'].size).to eql(1)
|
123
153
|
|
124
154
|
ids = result['Resources'].map { |resource| resource['id'] }
|
125
|
-
expect(ids).to match_array([@u2.
|
155
|
+
expect(ids).to match_array([@u2.primary_key.to_s])
|
126
156
|
|
127
157
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
128
158
|
expect(usernames).to match_array(['2'])
|
@@ -141,7 +171,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
141
171
|
expect(result['Resources'].size).to eql(1)
|
142
172
|
|
143
173
|
ids = result['Resources'].map { |resource| resource['id'] }
|
144
|
-
expect(ids).to match_array([@u3.
|
174
|
+
expect(ids).to match_array([@u3.primary_key.to_s])
|
145
175
|
|
146
176
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
147
177
|
expect(usernames).to match_array(['3'])
|
@@ -161,7 +191,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
161
191
|
expect(result['Resources'].size).to eql(2)
|
162
192
|
|
163
193
|
ids = result['Resources'].map { |resource| resource['id'] }
|
164
|
-
expect(ids).to match_array([@u1.
|
194
|
+
expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s])
|
165
195
|
|
166
196
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
167
197
|
expect(usernames).to match_array(['1', '2'])
|
@@ -180,7 +210,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
180
210
|
expect(result['Resources'].size).to eql(2)
|
181
211
|
|
182
212
|
ids = result['Resources'].map { |resource| resource['id'] }
|
183
|
-
expect(ids).to match_array([@u2.
|
213
|
+
expect(ids).to match_array([@u2.primary_key.to_s, @u3.primary_key.to_s])
|
184
214
|
|
185
215
|
usernames = result['Resources'].map { |resource| resource['userName'] }
|
186
216
|
expect(usernames).to match_array(['2', '3'])
|
@@ -204,18 +234,34 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
204
234
|
# ===========================================================================
|
205
235
|
|
206
236
|
context '#show' do
|
207
|
-
|
208
|
-
|
209
|
-
|
237
|
+
context 'with a UUID, renamed primary key column' do
|
238
|
+
it 'shows an item' do
|
239
|
+
expect_any_instance_of(MockUsersController).to receive(:show).once.and_call_original
|
240
|
+
get "/Users/#{@u2.primary_key}", params: { format: :scim }
|
210
241
|
|
211
|
-
|
212
|
-
|
242
|
+
expect(response.status).to eql(200)
|
243
|
+
result = JSON.parse(response.body)
|
213
244
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
245
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
246
|
+
expect(result['userName']).to eql('2')
|
247
|
+
expect(result['name']['familyName']).to eql('Bar')
|
248
|
+
expect(result['meta']['resourceType']).to eql('User')
|
249
|
+
end
|
250
|
+
end # "context 'with a UUID, renamed primary key column' do"
|
251
|
+
|
252
|
+
context 'with an integer, conventionally named primary key column' do
|
253
|
+
it 'shows an item' do
|
254
|
+
expect_any_instance_of(MockGroupsController).to receive(:show).once.and_call_original
|
255
|
+
get "/Groups/#{@g2.id}", params: { format: :scim }
|
256
|
+
|
257
|
+
expect(response.status).to eql(200)
|
258
|
+
result = JSON.parse(response.body)
|
259
|
+
|
260
|
+
expect(result['id']).to eql(@g2.id.to_s) # Note - ID was converted String; not Integer
|
261
|
+
expect(result['displayName']).to eql('Group 2')
|
262
|
+
expect(result['meta']['resourceType']).to eql('Group')
|
263
|
+
end
|
264
|
+
end # "context 'with an integer, conventionally named primary key column' do"
|
219
265
|
|
220
266
|
it 'renders 404' do
|
221
267
|
get '/Users/xyz', params: { format: :scim }
|
@@ -234,7 +280,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
234
280
|
it 'with minimal parameters' do
|
235
281
|
mock_before = MockUser.all.to_a
|
236
282
|
|
237
|
-
attributes = { userName: '4' }
|
283
|
+
attributes = { userName: '4' } # Minimum required by schema
|
238
284
|
attributes = spec_helper_hupcase(attributes) if force_upper_case
|
239
285
|
|
240
286
|
expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
|
@@ -248,7 +294,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
248
294
|
expect(response.status).to eql(201)
|
249
295
|
result = JSON.parse(response.body)
|
250
296
|
|
251
|
-
expect(result['id']).to eql(new_mock.
|
297
|
+
expect(result['id']).to eql(new_mock.primary_key.to_s)
|
252
298
|
expect(result['meta']['resourceType']).to eql('User')
|
253
299
|
expect(new_mock.username).to eql('4')
|
254
300
|
end
|
@@ -363,13 +409,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
363
409
|
|
364
410
|
expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
|
365
411
|
expect {
|
366
|
-
put "/Users/#{@u2.
|
412
|
+
put "/Users/#{@u2.primary_key}", params: attributes.merge(format: :scim)
|
367
413
|
}.to_not change { MockUser.count }
|
368
414
|
|
369
415
|
expect(response.status).to eql(200)
|
370
416
|
result = JSON.parse(response.body)
|
371
417
|
|
372
|
-
expect(result['id']).to eql(@u2.
|
418
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
373
419
|
expect(result['meta']['resourceType']).to eql('User')
|
374
420
|
|
375
421
|
@u2.reload
|
@@ -391,7 +437,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
391
437
|
|
392
438
|
it 'notes schema validation failures' do
|
393
439
|
expect {
|
394
|
-
put "/Users/#{@u2.
|
440
|
+
put "/Users/#{@u2.primary_key}", params: {
|
395
441
|
format: :scim
|
396
442
|
# userName parameter is required by schema, but missing
|
397
443
|
}
|
@@ -470,13 +516,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
470
516
|
|
471
517
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
472
518
|
expect {
|
473
|
-
patch "/Users/#{@u2.
|
519
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
474
520
|
}.to_not change { MockUser.count }
|
475
521
|
|
476
522
|
expect(response.status).to eql(200)
|
477
523
|
result = JSON.parse(response.body)
|
478
524
|
|
479
|
-
expect(result['id']).to eql(@u2.
|
525
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
480
526
|
expect(result['meta']['resourceType']).to eql('User')
|
481
527
|
|
482
528
|
@u2.reload
|
@@ -507,13 +553,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
507
553
|
|
508
554
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
509
555
|
expect {
|
510
|
-
patch "/Users/#{@u2.
|
556
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
511
557
|
}.to_not change { MockUser.count }
|
512
558
|
|
513
559
|
expect(response.status).to eql(200)
|
514
560
|
result = JSON.parse(response.body)
|
515
561
|
|
516
|
-
expect(result['id']).to eql(@u2.
|
562
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
517
563
|
expect(result['meta']['resourceType']).to eql('User')
|
518
564
|
|
519
565
|
@u2.reload
|
@@ -539,13 +585,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
539
585
|
|
540
586
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
541
587
|
expect {
|
542
|
-
patch "/Users/#{@u2.
|
588
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
543
589
|
}.to_not change { MockUser.count }
|
544
590
|
|
545
591
|
expect(response.status).to eql(200)
|
546
592
|
result = JSON.parse(response.body)
|
547
593
|
|
548
|
-
expect(result['id']).to eql(@u2.
|
594
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
549
595
|
expect(result['meta']['resourceType']).to eql('User')
|
550
596
|
|
551
597
|
@u2.reload
|
@@ -571,13 +617,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
571
617
|
|
572
618
|
expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
|
573
619
|
expect {
|
574
|
-
patch "/Users/#{@u2.
|
620
|
+
patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
|
575
621
|
}.to_not change { MockUser.count }
|
576
622
|
|
577
623
|
expect(response.status).to eql(200)
|
578
624
|
result = JSON.parse(response.body)
|
579
625
|
|
580
|
-
expect(result['id']).to eql(@u2.
|
626
|
+
expect(result['id']).to eql(@u2.primary_key.to_s)
|
581
627
|
expect(result['meta']['resourceType']).to eql('User')
|
582
628
|
|
583
629
|
@u2.reload
|
@@ -601,7 +647,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
601
647
|
|
602
648
|
it 'notes Rails validation failures' do
|
603
649
|
expect {
|
604
|
-
patch "/Users/#{@u2.
|
650
|
+
patch "/Users/#{@u2.primary_key}", params: {
|
605
651
|
format: :scim,
|
606
652
|
Operations: [
|
607
653
|
{
|
@@ -645,6 +691,142 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
645
691
|
result = JSON.parse(response.body)
|
646
692
|
expect(result['status']).to eql('404')
|
647
693
|
end
|
694
|
+
|
695
|
+
context 'when removing users from groups' do
|
696
|
+
before :each do
|
697
|
+
@g1.mock_users << @u1
|
698
|
+
@g1.mock_users << @u2
|
699
|
+
@g1.mock_users << @u3
|
700
|
+
|
701
|
+
# (Self-check) Verify group representation
|
702
|
+
#
|
703
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
704
|
+
|
705
|
+
expect(response.status).to eql(200)
|
706
|
+
result = JSON.parse(response.body)
|
707
|
+
|
708
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(MockUser.pluck(:primary_key).sort())
|
709
|
+
end
|
710
|
+
|
711
|
+
it 'can remove all users' do
|
712
|
+
expect {
|
713
|
+
expect {
|
714
|
+
patch "/Groups/#{@g1.id}", params: {
|
715
|
+
format: :scim,
|
716
|
+
Operations: [
|
717
|
+
{
|
718
|
+
op: 'remove',
|
719
|
+
path: 'members'
|
720
|
+
}
|
721
|
+
]
|
722
|
+
}
|
723
|
+
}.to_not change { MockUser.count }
|
724
|
+
}.to_not change { MockGroup.count }
|
725
|
+
|
726
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
727
|
+
|
728
|
+
expect(response.status).to eql(200)
|
729
|
+
result = JSON.parse(response.body)
|
730
|
+
|
731
|
+
expect(result['members']).to be_empty
|
732
|
+
expect(@g1.reload().mock_users).to be_empty
|
733
|
+
end
|
734
|
+
|
735
|
+
# Define via 'let':
|
736
|
+
#
|
737
|
+
# * Hash 'payload', to send via 'patch'
|
738
|
+
# * MockUser 'removed_user', which is the user that should be removed
|
739
|
+
#
|
740
|
+
shared_examples 'a user remover' do
|
741
|
+
it 'which removes the identified user' do
|
742
|
+
expect {
|
743
|
+
expect {
|
744
|
+
patch "/Groups/#{@g1.id}", params: payload()
|
745
|
+
}.to_not change { MockUser.count }
|
746
|
+
}.to_not change { MockGroup.count }
|
747
|
+
|
748
|
+
expected_remaining_user_ids = MockUser
|
749
|
+
.where.not(primary_key: removed_user().id)
|
750
|
+
.pluck(:primary_key)
|
751
|
+
.sort()
|
752
|
+
|
753
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
754
|
+
|
755
|
+
expect(response.status).to eql(200)
|
756
|
+
result = JSON.parse(response.body)
|
757
|
+
|
758
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(expected_remaining_user_ids)
|
759
|
+
expect(@g1.reload().mock_users.map(&:primary_key).sort()).to eql(expected_remaining_user_ids)
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
# https://www.rfc-editor.org/rfc/rfc7644#section-3.5.2.2
|
764
|
+
#
|
765
|
+
context 'and using an RFC-compliant payload' do
|
766
|
+
let(:removed_user) { @u2 }
|
767
|
+
let(:payload) do
|
768
|
+
{
|
769
|
+
format: :scim,
|
770
|
+
Operations: [
|
771
|
+
{
|
772
|
+
op: 'remove',
|
773
|
+
path: "members[value eq \"#{removed_user().primary_key}\"]",
|
774
|
+
}
|
775
|
+
]
|
776
|
+
}
|
777
|
+
end
|
778
|
+
|
779
|
+
it_behaves_like 'a user remover'
|
780
|
+
end # context 'and using an RFC-compliant payload' do
|
781
|
+
|
782
|
+
# https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
|
783
|
+
#
|
784
|
+
context 'and using a Microsoft variant payload' do
|
785
|
+
let(:removed_user) { @u2 }
|
786
|
+
let(:payload) do
|
787
|
+
{
|
788
|
+
format: :scim,
|
789
|
+
Operations: [
|
790
|
+
{
|
791
|
+
op: 'remove',
|
792
|
+
path: 'members',
|
793
|
+
value: [{
|
794
|
+
'$ref' => nil,
|
795
|
+
'value' => removed_user().primary_key
|
796
|
+
}]
|
797
|
+
}
|
798
|
+
]
|
799
|
+
}
|
800
|
+
end
|
801
|
+
|
802
|
+
it_behaves_like 'a user remover'
|
803
|
+
end # context 'and using a Microsoft variant payload' do
|
804
|
+
|
805
|
+
# https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
|
806
|
+
#
|
807
|
+
context 'and using a Salesforce variant payload' do
|
808
|
+
let(:removed_user) { @u2 }
|
809
|
+
let(:payload) do
|
810
|
+
{
|
811
|
+
format: :scim,
|
812
|
+
Operations: [
|
813
|
+
{
|
814
|
+
op: 'remove',
|
815
|
+
path: 'members',
|
816
|
+
value: {
|
817
|
+
'members' => [{
|
818
|
+
'$ref' => nil,
|
819
|
+
'value' => removed_user().primary_key
|
820
|
+
}]
|
821
|
+
}
|
822
|
+
}
|
823
|
+
]
|
824
|
+
}
|
825
|
+
end
|
826
|
+
|
827
|
+
it_behaves_like 'a user remover'
|
828
|
+
end # context 'and using a Salesforce variant payload' do
|
829
|
+
end # "context 'when removing users from groups' do"
|
648
830
|
end # "context '#update' do"
|
649
831
|
|
650
832
|
# ===========================================================================
|
@@ -654,7 +836,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
654
836
|
expect_any_instance_of(MockUsersController).to receive(:destroy).once.and_call_original
|
655
837
|
expect_any_instance_of(MockUser).to receive(:destroy!).once.and_call_original
|
656
838
|
expect {
|
657
|
-
delete "/Users/#{@u2.
|
839
|
+
delete "/Users/#{@u2.primary_key}", params: { format: :scim }
|
658
840
|
}.to change { MockUser.count }.by(-1)
|
659
841
|
|
660
842
|
expect(response.status).to eql(204)
|
@@ -666,7 +848,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
666
848
|
expect_any_instance_of(MockUser).to_not receive(:destroy!)
|
667
849
|
|
668
850
|
expect {
|
669
|
-
delete "/CustomDestroyUsers/#{@u2.
|
851
|
+
delete "/CustomDestroyUsers/#{@u2.primary_key}", params: { format: :scim }
|
670
852
|
}.to_not change { MockUser.count }
|
671
853
|
|
672
854
|
expect(response.status).to eql(204)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scimitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RIPA Global
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-01-
|
12
|
+
date: 2023-01-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -211,7 +211,6 @@ files:
|
|
211
211
|
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
212
212
|
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
213
213
|
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
214
|
-
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
215
214
|
- spec/apps/dummy/db/schema.rb
|
216
215
|
- spec/controllers/scimitar/application_controller_spec.rb
|
217
216
|
- spec/controllers/scimitar/resource_types_controller_spec.rb
|
@@ -261,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
261
260
|
- !ruby/object:Gem::Version
|
262
261
|
version: '0'
|
263
262
|
requirements: []
|
264
|
-
rubygems_version: 3.4.
|
263
|
+
rubygems_version: 3.4.4
|
265
264
|
signing_key:
|
266
265
|
specification_version: 4
|
267
266
|
summary: SCIM v2 for Rails
|
@@ -283,7 +282,6 @@ test_files:
|
|
283
282
|
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
284
283
|
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
285
284
|
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
286
|
-
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
287
285
|
- spec/apps/dummy/db/schema.rb
|
288
286
|
- spec/controllers/scimitar/application_controller_spec.rb
|
289
287
|
- spec/controllers/scimitar/resource_types_controller_spec.rb
|