scimitar 1.8.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scimitar/active_record_backed_resources_controller.rb +20 -94
  3. data/app/controllers/scimitar/application_controller.rb +13 -41
  4. data/app/controllers/scimitar/schemas_controller.rb +0 -5
  5. data/app/models/scimitar/complex_types/address.rb +6 -0
  6. data/app/models/scimitar/engine_configuration.rb +5 -13
  7. data/app/models/scimitar/error_response.rb +0 -12
  8. data/app/models/scimitar/lists/query_parser.rb +10 -25
  9. data/app/models/scimitar/resource_invalid_error.rb +1 -1
  10. data/app/models/scimitar/resources/base.rb +4 -14
  11. data/app/models/scimitar/resources/mixin.rb +13 -140
  12. data/app/models/scimitar/schema/address.rb +0 -1
  13. data/app/models/scimitar/schema/attribute.rb +5 -14
  14. data/app/models/scimitar/schema/base.rb +1 -1
  15. data/app/models/scimitar/schema/vdtp.rb +1 -1
  16. data/app/models/scimitar/service_provider_configuration.rb +3 -14
  17. data/config/initializers/scimitar.rb +3 -28
  18. data/lib/scimitar/version.rb +2 -2
  19. data/lib/scimitar.rb +2 -7
  20. data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
  21. data/spec/apps/dummy/app/models/mock_group.rb +1 -1
  22. data/spec/apps/dummy/app/models/mock_user.rb +8 -36
  23. data/spec/apps/dummy/config/application.rb +1 -0
  24. data/spec/apps/dummy/config/environments/test.rb +28 -5
  25. data/spec/apps/dummy/config/initializers/scimitar.rb +10 -61
  26. data/spec/apps/dummy/config/routes.rb +7 -28
  27. data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -10
  28. data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
  29. data/spec/apps/dummy/db/schema.rb +4 -11
  30. data/spec/controllers/scimitar/application_controller_spec.rb +3 -126
  31. data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
  32. data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -10
  33. data/spec/models/scimitar/complex_types/address_spec.rb +4 -3
  34. data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
  35. data/spec/models/scimitar/lists/query_parser_spec.rb +9 -76
  36. data/spec/models/scimitar/resources/base_spec.rb +70 -208
  37. data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
  38. data/spec/models/scimitar/resources/mixin_spec.rb +43 -790
  39. data/spec/models/scimitar/schema/attribute_spec.rb +3 -22
  40. data/spec/models/scimitar/schema/base_spec.rb +1 -1
  41. data/spec/models/scimitar/schema/user_spec.rb +0 -10
  42. data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -709
  43. data/spec/requests/application_controller_spec.rb +3 -16
  44. data/spec/spec_helper.rb +0 -8
  45. metadata +14 -25
  46. data/LICENSE.txt +0 -21
  47. data/README.md +0 -710
  48. data/lib/scimitar/support/utilities.rb +0 -51
  49. data/spec/apps/dummy/app/controllers/custom_create_mock_users_controller.rb +0 -25
  50. data/spec/apps/dummy/app/controllers/custom_replace_mock_users_controller.rb +0 -25
  51. data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +0 -24
  52. data/spec/apps/dummy/app/controllers/custom_update_mock_users_controller.rb +0 -25
@@ -1,42 +1,25 @@
1
1
  require 'spec_helper'
2
- require 'time'
3
2
 
4
3
  RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
5
4
  before :each do
6
5
  allow_any_instance_of(Scimitar::ApplicationController).to receive(:authenticated?).and_return(true)
7
6
 
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
- #
13
- lmt = Time.parse("2023-01-09 14:25:00 +1300")
14
- ids = 3.times.map { SecureRandom.uuid }.sort()
15
-
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')
7
+ @u1 = MockUser.create(username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com')
8
+ @u2 = MockUser.create(username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com')
9
+ @u3 = MockUser.create(username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com')
23
10
  end
24
11
 
25
12
  # ===========================================================================
26
13
 
27
14
  context '#index' do
28
15
  context 'with no items' do
29
- before :each do
16
+ it 'returns empty list' do
30
17
  MockUser.delete_all
31
- end
32
18
 
33
- it 'returns empty list' do
34
19
  expect_any_instance_of(MockUsersController).to receive(:index).once.and_call_original
35
20
  get '/Users', params: { format: :scim }
36
21
 
37
- expect(response.status ).to eql(200)
38
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
39
-
22
+ expect(response.status).to eql(200)
40
23
  result = JSON.parse(response.body)
41
24
 
42
25
  expect(result['totalResults']).to eql(0)
@@ -46,172 +29,55 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
46
29
  end # "context 'with no items' do"
47
30
 
48
31
  context 'with items' do
49
- context 'with a UUID, renamed primary key column' do
50
- it 'returns all items' do
51
- get '/Users', params: { format: :scim }
52
-
53
- expect(response.status ).to eql(200)
54
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
55
-
56
- result = JSON.parse(response.body)
57
-
58
- expect(result['totalResults']).to eql(3)
59
- expect(result['Resources'].size).to eql(3)
60
-
61
- ids = result['Resources'].map { |resource| resource['id'] }
62
- expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s, @u3.primary_key.to_s])
63
-
64
- usernames = result['Resources'].map { |resource| resource['userName'] }
65
- expect(usernames).to match_array(['1', '2', '3'])
66
- end
67
- end # "context 'with a UUID, renamed primary key column' do"
68
-
69
- context 'with an integer, conventionally named primary key column' do
70
- it 'returns all items' do
71
- get '/Groups', params: { format: :scim }
72
-
73
- expect(response.status ).to eql(200)
74
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
75
-
76
- result = JSON.parse(response.body)
77
-
78
- expect(result['totalResults']).to eql(3)
79
- expect(result['Resources'].size).to eql(3)
80
-
81
- ids = result['Resources'].map { |resource| resource['id'] }
82
- expect(ids).to match_array([@g1.id.to_s, @g2.id.to_s, @g3.id.to_s])
83
-
84
- usernames = result['Resources'].map { |resource| resource['displayName'] }
85
- expect(usernames).to match_array(['Group 1', 'Group 2', 'Group 3'])
86
- end
87
- end # "context 'with an integer, conventionally named primary key column' do"
88
-
89
- it 'applies a filter, with case-insensitive value comparison' do
90
- get '/Users', params: {
91
- format: :scim,
92
- filter: 'name.givenName eq "FOO" and name.familyName pr and emails ne "home_1@test.com"'
93
- }
94
-
95
- expect(response.status ).to eql(200)
96
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
32
+ it 'returns all items' do
33
+ get '/Users', params: { format: :scim }
97
34
 
35
+ expect(response.status).to eql(200)
98
36
  result = JSON.parse(response.body)
99
37
 
100
- expect(result['totalResults']).to eql(1)
101
- expect(result['Resources'].size).to eql(1)
38
+ expect(result['totalResults']).to eql(3)
39
+ expect(result['Resources'].size).to eql(3)
102
40
 
103
41
  ids = result['Resources'].map { |resource| resource['id'] }
104
- expect(ids).to match_array([@u2.primary_key.to_s])
42
+ expect(ids).to match_array([@u1.id.to_s, @u2.id.to_s, @u3.id.to_s])
105
43
 
106
44
  usernames = result['Resources'].map { |resource| resource['userName'] }
107
- expect(usernames).to match_array(['2'])
45
+ expect(usernames).to match_array(['1', '2', '3'])
108
46
  end
109
47
 
110
- it 'applies a filter, with case-insensitive attribute matching (GitHub issue #37)' do
48
+ it 'applies a filter, with case-insensitive value comparison' do
111
49
  get '/Users', params: {
112
50
  format: :scim,
113
- filter: 'name.GIVENNAME eq "Foo" and name.Familyname pr and emails ne "home_1@test.com"'
51
+ filter: 'name.givenName eq "Foo" and name.familyName pr and emails ne "home_1@TEST.COM"'
114
52
  }
115
53
 
116
- expect(response.status ).to eql(200)
117
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
118
-
54
+ expect(response.status).to eql(200)
119
55
  result = JSON.parse(response.body)
120
56
 
121
57
  expect(result['totalResults']).to eql(1)
122
58
  expect(result['Resources'].size).to eql(1)
123
59
 
124
60
  ids = result['Resources'].map { |resource| resource['id'] }
125
- expect(ids).to match_array([@u2.primary_key.to_s])
61
+ expect(ids).to match_array([@u2.id.to_s])
126
62
 
127
63
  usernames = result['Resources'].map { |resource| resource['userName'] }
128
64
  expect(usernames).to match_array(['2'])
129
65
  end
130
66
 
131
- # Strange attribute capitalisation in tests here builds on test coverage
132
- # for now-fixed GitHub issue #37.
133
- #
134
- context '"meta" / IDs (GitHub issue #36)' do
135
- it 'applies a filter on primary keys, using direct comparison (rather than e.g. case-insensitive operators)' do
136
- get '/Users', params: {
137
- format: :scim,
138
- filter: "id eq \"#{@u3.primary_key}\""
139
- }
140
-
141
- expect(response.status ).to eql(200)
142
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
143
-
144
- result = JSON.parse(response.body)
145
-
146
- expect(result['totalResults']).to eql(1)
147
- expect(result['Resources'].size).to eql(1)
148
-
149
- ids = result['Resources'].map { |resource| resource['id'] }
150
- expect(ids).to match_array([@u3.primary_key.to_s])
151
-
152
- usernames = result['Resources'].map { |resource| resource['userName'] }
153
- expect(usernames).to match_array(['3'])
154
- end
155
-
156
- it 'applies a filter on external IDs, using direct comparison' do
157
- get '/Users', params: {
158
- format: :scim,
159
- filter: "externalID eq \"#{@u2.scim_uid}\""
160
- }
161
-
162
- expect(response.status ).to eql(200)
163
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
164
-
165
- result = JSON.parse(response.body)
166
-
167
- expect(result['totalResults']).to eql(1)
168
- expect(result['Resources'].size).to eql(1)
169
-
170
- ids = result['Resources'].map { |resource| resource['id'] }
171
- expect(ids).to match_array([@u2.primary_key.to_s])
172
-
173
- usernames = result['Resources'].map { |resource| resource['userName'] }
174
- expect(usernames).to match_array(['2'])
175
- end
176
-
177
- it 'applies a filter on "meta" entries, using direct comparison' do
178
- get '/Users', params: {
179
- format: :scim,
180
- filter: "Meta.LastModified eq \"#{@u3.updated_at}\""
181
- }
182
-
183
- expect(response.status ).to eql(200)
184
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
185
-
186
- result = JSON.parse(response.body)
187
-
188
- expect(result['totalResults']).to eql(1)
189
- expect(result['Resources'].size).to eql(1)
190
-
191
- ids = result['Resources'].map { |resource| resource['id'] }
192
- expect(ids).to match_array([@u3.primary_key.to_s])
193
-
194
- usernames = result['Resources'].map { |resource| resource['userName'] }
195
- expect(usernames).to match_array(['3'])
196
- end
197
- end # "context '"meta" / IDs (GitHub issue #36)' do"
198
-
199
67
  it 'obeys a page size' do
200
68
  get '/Users', params: {
201
69
  format: :scim,
202
70
  count: 2
203
71
  }
204
72
 
205
- expect(response.status ).to eql(200)
206
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
207
-
73
+ expect(response.status).to eql(200)
208
74
  result = JSON.parse(response.body)
209
75
 
210
76
  expect(result['totalResults']).to eql(3)
211
77
  expect(result['Resources'].size).to eql(2)
212
78
 
213
79
  ids = result['Resources'].map { |resource| resource['id'] }
214
- expect(ids).to match_array([@u1.primary_key.to_s, @u2.primary_key.to_s])
80
+ expect(ids).to match_array([@u1.id.to_s, @u2.id.to_s])
215
81
 
216
82
  usernames = result['Resources'].map { |resource| resource['userName'] }
217
83
  expect(usernames).to match_array(['1', '2'])
@@ -223,16 +89,14 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
223
89
  startIndex: 2
224
90
  }
225
91
 
226
- expect(response.status ).to eql(200)
227
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
228
-
92
+ expect(response.status).to eql(200)
229
93
  result = JSON.parse(response.body)
230
94
 
231
95
  expect(result['totalResults']).to eql(3)
232
96
  expect(result['Resources'].size).to eql(2)
233
97
 
234
98
  ids = result['Resources'].map { |resource| resource['id'] }
235
- expect(ids).to match_array([@u2.primary_key.to_s, @u3.primary_key.to_s])
99
+ expect(ids).to match_array([@u2.id.to_s, @u3.id.to_s])
236
100
 
237
101
  usernames = result['Resources'].map { |resource| resource['userName'] }
238
102
  expect(usernames).to match_array(['2', '3'])
@@ -246,11 +110,8 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
246
110
  filter: 'name.givenName'
247
111
  }
248
112
 
249
- expect(response.status ).to eql(400)
250
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
251
-
113
+ expect(response.status).to eql(400)
252
114
  result = JSON.parse(response.body)
253
-
254
115
  expect(result['scimType']).to eql('invalidFilter')
255
116
  end
256
117
  end # "context 'with bad calls' do"
@@ -259,47 +120,24 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
259
120
  # ===========================================================================
260
121
 
261
122
  context '#show' do
262
- context 'with a UUID, renamed primary key column' do
263
- it 'shows an item' do
264
- expect_any_instance_of(MockUsersController).to receive(:show).once.and_call_original
265
- get "/Users/#{@u2.primary_key}", params: { format: :scim }
266
-
267
- expect(response.status ).to eql(200)
268
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
269
-
270
- result = JSON.parse(response.body)
271
-
272
- expect(result['id']).to eql(@u2.primary_key.to_s)
273
- expect(result['userName']).to eql('2')
274
- expect(result['name']['familyName']).to eql('Bar')
275
- expect(result['meta']['resourceType']).to eql('User')
276
- end
277
- end # "context 'with a UUID, renamed primary key column' do"
278
-
279
- context 'with an integer, conventionally named primary key column' do
280
- it 'shows an item' do
281
- expect_any_instance_of(MockGroupsController).to receive(:show).once.and_call_original
282
- get "/Groups/#{@g2.id}", params: { format: :scim }
123
+ it 'shows an item' do
124
+ expect_any_instance_of(MockUsersController).to receive(:show).once.and_call_original
125
+ get "/Users/#{@u2.id}", params: { format: :scim }
283
126
 
284
- expect(response.status ).to eql(200)
285
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
286
-
287
- result = JSON.parse(response.body)
127
+ expect(response.status).to eql(200)
128
+ result = JSON.parse(response.body)
288
129
 
289
- expect(result['id']).to eql(@g2.id.to_s) # Note - ID was converted String; not Integer
290
- expect(result['displayName']).to eql('Group 2')
291
- expect(result['meta']['resourceType']).to eql('Group')
292
- end
293
- end # "context 'with an integer, conventionally named primary key column' do"
130
+ expect(result['id']).to eql(@u2.id.to_s) # Note - ID was converted String; not Integer
131
+ expect(result['userName']).to eql('2')
132
+ expect(result['name']['familyName']).to eql('Bar')
133
+ expect(result['meta']['resourceType']).to eql('User')
134
+ end
294
135
 
295
136
  it 'renders 404' do
296
137
  get '/Users/xyz', params: { format: :scim }
297
138
 
298
- expect(response.status ).to eql(404)
299
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
300
-
139
+ expect(response.status).to eql(404)
301
140
  result = JSON.parse(response.body)
302
-
303
141
  expect(result['status']).to eql('404')
304
142
  end
305
143
  end # "context '#show' do"
@@ -312,15 +150,10 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
312
150
  it 'with minimal parameters' do
313
151
  mock_before = MockUser.all.to_a
314
152
 
315
- attributes = { userName: '4' } # Minimum required by schema
153
+ attributes = { userName: '4' } # Minimum required by schema
316
154
  attributes = spec_helper_hupcase(attributes) if force_upper_case
317
155
 
318
- # Prove that certain known pathways are called; can then unit test
319
- # those if need be and be sure that this covers #create actions.
320
- #
321
156
  expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
322
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
323
-
324
157
  expect {
325
158
  post "/Users", params: attributes.merge(format: :scim)
326
159
  }.to change { MockUser.count }.by(1)
@@ -328,12 +161,10 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
328
161
  mock_after = MockUser.all.to_a
329
162
  new_mock = (mock_after - mock_before).first
330
163
 
331
- expect(response.status ).to eql(201)
332
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
333
-
164
+ expect(response.status).to eql(201)
334
165
  result = JSON.parse(response.body)
335
166
 
336
- expect(result['id']).to eql(new_mock.primary_key.to_s)
167
+ expect(result['id']).to eql(new_mock.id.to_s)
337
168
  expect(result['meta']['resourceType']).to eql('User')
338
169
  expect(new_mock.username).to eql('4')
339
170
  end
@@ -349,7 +180,6 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
349
180
  givenName: 'Given',
350
181
  familyName: 'Family'
351
182
  },
352
- meta: { resourceType: 'User' },
353
183
  emails: [
354
184
  {
355
185
  type: 'work',
@@ -371,9 +201,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
371
201
  mock_after = MockUser.all.to_a
372
202
  new_mock = (mock_after - mock_before).first
373
203
 
374
- expect(response.status ).to eql(201)
375
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
376
-
204
+ expect(response.status).to eql(201)
377
205
  result = JSON.parse(response.body)
378
206
 
379
207
  expect(result['id']).to eql(new_mock.id.to_s)
@@ -404,11 +232,8 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
404
232
  }
405
233
  }.to_not change { MockUser.count }
406
234
 
407
- expect(response.status ).to eql(409)
408
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
409
-
235
+ expect(response.status).to eql(409)
410
236
  result = JSON.parse(response.body)
411
-
412
237
  expect(result['scimType']).to eql('uniqueness')
413
238
  expect(result['detail']).to include('already been taken')
414
239
  end
@@ -421,11 +246,8 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
421
246
  }
422
247
  }.to_not change { MockUser.count }
423
248
 
424
- expect(response.status ).to eql(400)
425
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
426
-
249
+ expect(response.status).to eql(400)
427
250
  result = JSON.parse(response.body)
428
-
429
251
  expect(result['scimType']).to eql('invalidValue')
430
252
  expect(result['detail']).to include('is required')
431
253
  end
@@ -438,83 +260,12 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
438
260
  }
439
261
  }.to_not change { MockUser.count }
440
262
 
441
- expect(response.status ).to eql(400)
442
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
443
-
263
+ expect(response.status).to eql(400)
444
264
  result = JSON.parse(response.body)
445
265
 
446
266
  expect(result['scimType']).to eql('invalidValue')
447
267
  expect(result['detail']).to include('is reserved')
448
268
  end
449
-
450
- context 'with a block' do
451
- it 'invokes the block' do
452
- mock_before = MockUser.all.to_a
453
-
454
- expect_any_instance_of(CustomCreateMockUsersController).to receive(:create).once.and_call_original
455
- expect {
456
- post "/CustomCreateUsers", params: {
457
- format: :scim,
458
- userName: '4' # Minimum required by schema
459
- }
460
- }.to change { MockUser.count }.by(1)
461
-
462
- mock_after = MockUser.all.to_a
463
- new_mock = (mock_after - mock_before).first
464
-
465
- expect(response.status ).to eql(201)
466
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
467
-
468
- result = JSON.parse(response.body)
469
-
470
- expect(result['id']).to eql(new_mock.id.to_s)
471
- expect(result['meta']['resourceType']).to eql('User')
472
- expect(new_mock.first_name).to eql(CustomCreateMockUsersController::OVERRIDDEN_NAME)
473
- end
474
-
475
- it 'returns 409 for duplicates (by Rails validation)' do
476
- existing_user = MockUser.create!(
477
- username: '4',
478
- first_name: 'Will Be Overridden',
479
- last_name: 'Baz',
480
- home_email_address: 'random@test.com',
481
- scim_uid: '999'
482
- )
483
-
484
- expect_any_instance_of(CustomCreateMockUsersController).to receive(:create).once.and_call_original
485
- expect {
486
- post "/CustomCreateUsers", params: {
487
- format: :scim,
488
- userName: '4' # Already exists
489
- }
490
- }.to_not change { MockUser.count }
491
-
492
- expect(response.status ).to eql(409)
493
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
494
-
495
- result = JSON.parse(response.body)
496
-
497
- expect(result['scimType']).to eql('uniqueness')
498
- expect(result['detail']).to include('already been taken')
499
- end
500
-
501
- it 'notes Rails validation failures' do
502
- expect_any_instance_of(CustomCreateMockUsersController).to receive(:create).once.and_call_original
503
- expect {
504
- post "/CustomCreateUsers", params: {
505
- format: :scim,
506
- userName: MockUser::INVALID_USERNAME
507
- }
508
- }.to_not change { MockUser.count }
509
-
510
- expect(response.status ).to eql(400)
511
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
512
-
513
- result = JSON.parse(response.body)
514
- expect(result['scimType']).to eql('invalidValue')
515
- expect(result['detail']).to include('is reserved')
516
- end
517
- end # "context 'with a block' do"
518
269
  end # "context '#create' do"
519
270
 
520
271
  # ===========================================================================
@@ -525,22 +276,15 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
525
276
  attributes = { userName: '4' } # Minimum required by schema
526
277
  attributes = spec_helper_hupcase(attributes) if force_upper_case
527
278
 
528
- # Prove that certain known pathways are called; can then unit test
529
- # those if need be and be sure that this covers #replace actions.
530
- #
531
279
  expect_any_instance_of(MockUsersController).to receive(:replace).once.and_call_original
532
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
533
-
534
280
  expect {
535
- put "/Users/#{@u2.primary_key}", params: attributes.merge(format: :scim)
281
+ put "/Users/#{@u2.id}", params: attributes.merge(format: :scim)
536
282
  }.to_not change { MockUser.count }
537
283
 
538
- expect(response.status ).to eql(200)
539
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
540
-
284
+ expect(response.status).to eql(200)
541
285
  result = JSON.parse(response.body)
542
286
 
543
- expect(result['id']).to eql(@u2.primary_key.to_s)
287
+ expect(result['id']).to eql(@u2.id.to_s)
544
288
  expect(result['meta']['resourceType']).to eql('User')
545
289
 
546
290
  @u2.reload
@@ -562,17 +306,14 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
562
306
 
563
307
  it 'notes schema validation failures' do
564
308
  expect {
565
- put "/Users/#{@u2.primary_key}", params: {
309
+ put "/Users/#{@u2.id}", params: {
566
310
  format: :scim
567
311
  # userName parameter is required by schema, but missing
568
312
  }
569
313
  }.to_not change { MockUser.count }
570
314
 
571
- expect(response.status ).to eql(400)
572
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
573
-
315
+ expect(response.status).to eql(400)
574
316
  result = JSON.parse(response.body)
575
-
576
317
  expect(result['scimType']).to eql('invalidValue')
577
318
  expect(result['detail']).to include('is required')
578
319
 
@@ -586,15 +327,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
586
327
 
587
328
  it 'notes Rails validation failures' do
588
329
  expect {
589
- put "/Users/#{@u2.primary_key}", params: {
330
+ post "/Users", params: {
590
331
  format: :scim,
591
332
  userName: MockUser::INVALID_USERNAME
592
333
  }
593
334
  }.to_not change { MockUser.count }
594
335
 
595
- expect(response.status ).to eql(400)
596
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
597
-
336
+ expect(response.status).to eql(400)
598
337
  result = JSON.parse(response.body)
599
338
 
600
339
  expect(result['scimType']).to eql('invalidValue')
@@ -616,65 +355,10 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
616
355
  }
617
356
  }.to_not change { MockUser.count }
618
357
 
619
- expect(response.status ).to eql(404)
620
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
621
-
358
+ expect(response.status).to eql(404)
622
359
  result = JSON.parse(response.body)
623
-
624
360
  expect(result['status']).to eql('404')
625
361
  end
626
-
627
- context 'with a block' do
628
- it 'invokes the block' do
629
- attributes = { userName: '4' } # Minimum required by schema
630
-
631
- expect_any_instance_of(CustomReplaceMockUsersController).to receive(:replace).once.and_call_original
632
- expect {
633
- put "/CustomReplaceUsers/#{@u2.primary_key}", params: {
634
- format: :scim,
635
- userName: '4'
636
- }
637
- }.to_not change { MockUser.count }
638
-
639
- expect(response.status ).to eql(200)
640
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
641
-
642
- result = JSON.parse(response.body)
643
-
644
- expect(result['id']).to eql(@u2.primary_key.to_s)
645
- expect(result['meta']['resourceType']).to eql('User')
646
-
647
- @u2.reload
648
-
649
- expect(@u2.username ).to eql('4')
650
- expect(@u2.first_name).to eql(CustomReplaceMockUsersController::OVERRIDDEN_NAME)
651
- end
652
-
653
- it 'notes Rails validation failures' do
654
- expect_any_instance_of(CustomReplaceMockUsersController).to receive(:replace).once.and_call_original
655
- expect {
656
- put "/CustomReplaceUsers/#{@u2.primary_key}", params: {
657
- format: :scim,
658
- userName: MockUser::INVALID_USERNAME
659
- }
660
- }.to_not change { MockUser.count }
661
-
662
- expect(response.status ).to eql(400)
663
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
664
-
665
- result = JSON.parse(response.body)
666
-
667
- expect(result['scimType']).to eql('invalidValue')
668
- expect(result['detail']).to include('is reserved')
669
-
670
- @u2.reload
671
-
672
- expect(@u2.username).to eql('2')
673
- expect(@u2.first_name).to eql('Foo')
674
- expect(@u2.last_name).to eql('Bar')
675
- expect(@u2.home_email_address).to eql('home_2@test.com')
676
- end
677
- end # "context 'with a block' do"
678
362
  end # "context '#replace' do"
679
363
 
680
364
  # ===========================================================================
@@ -699,22 +383,15 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
699
383
 
700
384
  payload = spec_helper_hupcase(payload) if force_upper_case
701
385
 
702
- # Prove that certain known pathways are called; can then unit test
703
- # those if need be and be sure that this covers #update actions.
704
- #
705
386
  expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
706
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
707
-
708
387
  expect {
709
- patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
388
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
710
389
  }.to_not change { MockUser.count }
711
390
 
712
- expect(response.status ).to eql(200)
713
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
714
-
391
+ expect(response.status).to eql(200)
715
392
  result = JSON.parse(response.body)
716
393
 
717
- expect(result['id']).to eql(@u2.primary_key.to_s)
394
+ expect(result['id']).to eql(@u2.id.to_s)
718
395
  expect(result['meta']['resourceType']).to eql('User')
719
396
 
720
397
  @u2.reload
@@ -745,15 +422,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
745
422
 
746
423
  expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
747
424
  expect {
748
- patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
425
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
749
426
  }.to_not change { MockUser.count }
750
427
 
751
- expect(response.status ).to eql(200)
752
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
753
-
428
+ expect(response.status).to eql(200)
754
429
  result = JSON.parse(response.body)
755
430
 
756
- expect(result['id']).to eql(@u2.primary_key.to_s)
431
+ expect(result['id']).to eql(@u2.id.to_s)
757
432
  expect(result['meta']['resourceType']).to eql('User')
758
433
 
759
434
  @u2.reload
@@ -779,15 +454,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
779
454
 
780
455
  expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
781
456
  expect {
782
- patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
457
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
783
458
  }.to_not change { MockUser.count }
784
459
 
785
- expect(response.status ).to eql(200)
786
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
787
-
460
+ expect(response.status).to eql(200)
788
461
  result = JSON.parse(response.body)
789
462
 
790
- expect(result['id']).to eql(@u2.primary_key.to_s)
463
+ expect(result['id']).to eql(@u2.id.to_s)
791
464
  expect(result['meta']['resourceType']).to eql('User')
792
465
 
793
466
  @u2.reload
@@ -813,15 +486,13 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
813
486
 
814
487
  expect_any_instance_of(MockUsersController).to receive(:update).once.and_call_original
815
488
  expect {
816
- patch "/Users/#{@u2.primary_key}", params: payload.merge(format: :scim)
489
+ patch "/Users/#{@u2.id}", params: payload.merge(format: :scim)
817
490
  }.to_not change { MockUser.count }
818
491
 
819
- expect(response.status ).to eql(200)
820
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
821
-
492
+ expect(response.status).to eql(200)
822
493
  result = JSON.parse(response.body)
823
494
 
824
- expect(result['id']).to eql(@u2.primary_key.to_s)
495
+ expect(result['id']).to eql(@u2.id.to_s)
825
496
  expect(result['meta']['resourceType']).to eql('User')
826
497
 
827
498
  @u2.reload
@@ -845,7 +516,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
845
516
 
846
517
  it 'notes Rails validation failures' do
847
518
  expect {
848
- patch "/Users/#{@u2.primary_key}", params: {
519
+ patch "/Users/#{@u2.id}", params: {
849
520
  format: :scim,
850
521
  Operations: [
851
522
  {
@@ -857,9 +528,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
857
528
  }
858
529
  }.to_not change { MockUser.count }
859
530
 
860
- expect(response.status ).to eql(400)
861
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
862
-
531
+ expect(response.status).to eql(400)
863
532
  result = JSON.parse(response.body)
864
533
 
865
534
  expect(result['scimType']).to eql('invalidValue')
@@ -887,329 +556,20 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
887
556
  }
888
557
  }.to_not change { MockUser.count }
889
558
 
890
- expect(response.status ).to eql(404)
891
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
892
-
559
+ expect(response.status).to eql(404)
893
560
  result = JSON.parse(response.body)
894
-
895
561
  expect(result['status']).to eql('404')
896
562
  end
897
-
898
- context 'when removing users from groups' do
899
- before :each do
900
- @g1.mock_users << @u1
901
- @g1.mock_users << @u2
902
- @g1.mock_users << @u3
903
-
904
- # (Self-check) Verify group representation
905
- #
906
- get "/Groups/#{@g1.id}", params: { format: :scim }
907
-
908
- expect(response.status).to eql(200)
909
- result = JSON.parse(response.body)
910
-
911
- expect(result['members'].map { |m| m['value'] }.sort()).to eql(MockUser.pluck(:primary_key).sort())
912
- end
913
-
914
- it 'can remove all users' do
915
- expect {
916
- expect {
917
- patch "/Groups/#{@g1.id}", params: {
918
- format: :scim,
919
- Operations: [
920
- {
921
- op: 'remove',
922
- path: 'members'
923
- }
924
- ]
925
- }
926
- }.to_not change { MockUser.count }
927
- }.to_not change { MockGroup.count }
928
-
929
- get "/Groups/#{@g1.id}", params: { format: :scim }
930
-
931
- expect(response.status ).to eql(200)
932
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
933
-
934
- result = JSON.parse(response.body)
935
-
936
- expect(result['members']).to be_empty
937
- expect(@g1.reload().mock_users).to be_empty
938
- end
939
-
940
- # Define via 'let':
941
- #
942
- # * Hash 'payload', to send via 'patch'
943
- # * MockUser 'removed_user', which is the user that should be removed
944
- #
945
- shared_examples 'a user remover' do
946
- it 'which removes the identified user' do
947
- expect {
948
- expect {
949
- patch "/Groups/#{@g1.id}", params: payload()
950
- }.to_not change { MockUser.count }
951
- }.to_not change { MockGroup.count }
952
-
953
- expected_remaining_user_ids = MockUser
954
- .where.not(primary_key: removed_user().id)
955
- .pluck(:primary_key)
956
- .sort()
957
-
958
- get "/Groups/#{@g1.id}", params: { format: :scim }
959
-
960
- expect(response.status ).to eql(200)
961
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
962
-
963
- result = JSON.parse(response.body)
964
-
965
- expect(result['members'].map { |m| m['value'] }.sort()).to eql(expected_remaining_user_ids)
966
- expect(@g1.reload().mock_users.map(&:primary_key).sort()).to eql(expected_remaining_user_ids)
967
- end
968
- end
969
-
970
- # https://tools.ietf.org/html/rfc7644#section-3.5.2.2
971
- #
972
- context 'and using an RFC-compliant payload' do
973
- let(:removed_user) { @u2 }
974
- let(:payload) do
975
- {
976
- format: :scim,
977
- Operations: [
978
- {
979
- op: 'remove',
980
- path: "members[value eq \"#{removed_user().primary_key}\"]",
981
- }
982
- ]
983
- }
984
- end
985
-
986
- it_behaves_like 'a user remover'
987
- end # context 'and using an RFC-compliant payload' do
988
-
989
- # https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
990
- #
991
- context 'and using a Microsoft variant payload' do
992
- let(:removed_user) { @u2 }
993
- let(:payload) do
994
- {
995
- format: :scim,
996
- Operations: [
997
- {
998
- op: 'remove',
999
- path: 'members',
1000
- value: [{
1001
- '$ref' => nil,
1002
- 'value' => removed_user().primary_key
1003
- }]
1004
- }
1005
- ]
1006
- }
1007
- end
1008
-
1009
- it_behaves_like 'a user remover'
1010
- end # context 'and using a Microsoft variant payload' do
1011
-
1012
- # https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
1013
- #
1014
- context 'and using a Salesforce variant payload' do
1015
- let(:removed_user) { @u2 }
1016
- let(:payload) do
1017
- {
1018
- format: :scim,
1019
- Operations: [
1020
- {
1021
- op: 'remove',
1022
- path: 'members',
1023
- value: {
1024
- 'members' => [{
1025
- '$ref' => nil,
1026
- 'value' => removed_user().primary_key
1027
- }]
1028
- }
1029
- }
1030
- ]
1031
- }
1032
- end
1033
-
1034
- it_behaves_like 'a user remover'
1035
- end # context 'and using a Salesforce variant payload' do
1036
- end # "context 'when removing users from groups' do"
1037
-
1038
- context 'with a block' do
1039
- it 'invokes the block' do
1040
- payload = {
1041
- format: :scim,
1042
- Operations: [
1043
- {
1044
- op: 'add',
1045
- path: 'userName',
1046
- value: '4'
1047
- },
1048
- {
1049
- op: 'replace',
1050
- path: 'emails[type eq "work"]',
1051
- value: { type: 'work', value: 'work_4@test.com' }
1052
- }
1053
- ]
1054
- }
1055
-
1056
- expect_any_instance_of(CustomUpdateMockUsersController).to receive(:update).once.and_call_original
1057
- expect {
1058
- patch "/CustomUpdateUsers/#{@u2.primary_key}", params: payload
1059
- }.to_not change { MockUser.count }
1060
-
1061
- expect(response.status ).to eql(200)
1062
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1063
-
1064
- result = JSON.parse(response.body)
1065
-
1066
- expect(result['id']).to eql(@u2.primary_key.to_s)
1067
- expect(result['meta']['resourceType']).to eql('User')
1068
-
1069
- @u2.reload
1070
-
1071
- expect(@u2.username ).to eql('4')
1072
- expect(@u2.first_name ).to eql(CustomUpdateMockUsersController::OVERRIDDEN_NAME)
1073
- expect(@u2.work_email_address).to eql('work_4@test.com')
1074
- end
1075
-
1076
- it 'notes Rails validation failures' do
1077
- expect_any_instance_of(CustomUpdateMockUsersController).to receive(:update).once.and_call_original
1078
- expect {
1079
- patch "/CustomUpdateUsers/#{@u2.primary_key}", params: {
1080
- format: :scim,
1081
- Operations: [
1082
- {
1083
- op: 'add',
1084
- path: 'userName',
1085
- value: MockUser::INVALID_USERNAME
1086
- }
1087
- ]
1088
- }
1089
- }.to_not change { MockUser.count }
1090
-
1091
- expect(response.status ).to eql(400)
1092
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1093
-
1094
- result = JSON.parse(response.body)
1095
-
1096
- expect(result['scimType']).to eql('invalidValue')
1097
- expect(result['detail']).to include('is reserved')
1098
-
1099
- @u2.reload
1100
-
1101
- expect(@u2.username).to eql('2')
1102
- expect(@u2.first_name).to eql('Foo')
1103
- expect(@u2.last_name).to eql('Bar')
1104
- expect(@u2.home_email_address).to eql('home_2@test.com')
1105
- end
1106
- end # "context 'with a block' do"
1107
563
  end # "context '#update' do"
1108
564
 
1109
- # ===========================================================================
1110
- # In-passing parts of tests above show that #create, #replace and #update all
1111
- # route through #save!, so now add some unit tests for that and for exception
1112
- # handling overrides invoked via #save!.
1113
- # ===========================================================================
1114
-
1115
- context 'overriding #save!' do
1116
- it 'invokes a block if given one' do
1117
- mock_before = MockUser.all.to_a
1118
- attributes = { userName: '5' } # Minimum required by schema
1119
-
1120
- expect_any_instance_of(CustomSaveMockUsersController).to receive(:create).once.and_call_original
1121
- expect {
1122
- post "/CustomSaveUsers", params: attributes.merge(format: :scim)
1123
- }.to change { MockUser.count }.by(1)
1124
-
1125
- mock_after = MockUser.all.to_a
1126
- new_mock = (mock_after - mock_before).first
1127
-
1128
- expect(response.status ).to eql(201)
1129
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1130
-
1131
- expect(new_mock.username).to eql(CustomSaveMockUsersController::CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR)
1132
- end
1133
- end # "context 'overriding #save!' do
1134
-
1135
- context 'custom on-save exceptions' do
1136
- MockUsersController.new.send(:scimitar_rescuable_exceptions).each do | exception_class |
1137
- it "handles out-of-box exception #{exception_class}" do
1138
- expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
1139
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
1140
-
1141
- expect_any_instance_of(MockUser).to receive(:save!).once { raise exception_class }
1142
-
1143
- expect {
1144
- post "/Users", params: { format: :scim, userName: SecureRandom.uuid }
1145
- }.to_not change { MockUser.count }
1146
-
1147
- expected_status, expected_prefix = if exception_class == ActiveRecord::RecordNotUnique
1148
- [409, 'Operation failed due to a uniqueness constraint: ']
1149
- else
1150
- [400, 'Operation failed since record has become invalid: ']
1151
- end
1152
-
1153
- expect(response.status ).to eql(expected_status)
1154
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1155
-
1156
- result = JSON.parse(response.body)
1157
-
1158
- # Check basic SCIM error rendering - good enough given other tests
1159
- # elsewhere. Exact message varies by exception.
1160
- #
1161
- expect(result['detail']).to start_with(expected_prefix)
1162
- end
1163
- end
1164
-
1165
- it 'handles custom exceptions' do
1166
- exception_class = RuntimeError # (for testing only; usually, this would provoke a 500 response)
1167
-
1168
- expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
1169
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
1170
-
1171
- expect_any_instance_of(MockUsersController).to receive(:scimitar_rescuable_exceptions).once { [ exception_class ] }
1172
- expect_any_instance_of(MockUser ).to receive(:save! ).once { raise exception_class }
1173
-
1174
- expect {
1175
- post "/Users", params: { format: :scim, userName: SecureRandom.uuid }
1176
- }.to_not change { MockUser.count }
1177
-
1178
- expect(response.status ).to eql(400)
1179
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1180
-
1181
- result = JSON.parse(response.body)
1182
-
1183
- expect(result['detail']).to start_with('Operation failed since record has become invalid: ')
1184
- end
1185
-
1186
- it 'reports other exceptions as 500s' do
1187
- expect_any_instance_of(MockUsersController).to receive(:create).once.and_call_original
1188
- expect_any_instance_of(MockUsersController).to receive(:save! ).once.and_call_original
1189
-
1190
- expect_any_instance_of(MockUser).to receive(:save!).once { raise RuntimeError }
1191
-
1192
- expect {
1193
- post "/Users", params: { format: :scim, userName: SecureRandom.uuid }
1194
- }.to_not change { MockUser.count }
1195
-
1196
- expect(response.status ).to eql(500)
1197
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1198
-
1199
- result = JSON.parse(response.body)
1200
-
1201
- expect(result['detail']).to eql('RuntimeError')
1202
- end
1203
- end
1204
-
1205
565
  # ===========================================================================
1206
566
 
1207
567
  context '#destroy' do
1208
- it 'deletes an item if given no block' do
568
+ it 'deletes an item if given no blok' do
1209
569
  expect_any_instance_of(MockUsersController).to receive(:destroy).once.and_call_original
1210
570
  expect_any_instance_of(MockUser).to receive(:destroy!).once.and_call_original
1211
571
  expect {
1212
- delete "/Users/#{@u2.primary_key}", params: { format: :scim }
572
+ delete "/Users/#{@u2.id}", params: { format: :scim }
1213
573
  }.to change { MockUser.count }.by(-1)
1214
574
 
1215
575
  expect(response.status).to eql(204)
@@ -1221,7 +581,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
1221
581
  expect_any_instance_of(MockUser).to_not receive(:destroy!)
1222
582
 
1223
583
  expect {
1224
- delete "/CustomDestroyUsers/#{@u2.primary_key}", params: { format: :scim }
584
+ delete "/CustomDestroyUsers/#{@u2.id}", params: { format: :scim }
1225
585
  }.to_not change { MockUser.count }
1226
586
 
1227
587
  expect(response.status).to eql(204)
@@ -1236,11 +596,8 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
1236
596
  delete '/Users/xyz', params: { format: :scim }
1237
597
  }.to_not change { MockUser.count }
1238
598
 
1239
- expect(response.status ).to eql(404)
1240
- expect(response.headers['Content-Type']).to eql('application/scim+json; charset=utf-8')
1241
-
599
+ expect(response.status).to eql(404)
1242
600
  result = JSON.parse(response.body)
1243
-
1244
601
  expect(result['status']).to eql('404')
1245
602
  end
1246
603
  end # "context '#destroy' do"