scimitar 1.8.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/scimitar/active_record_backed_resources_controller.rb +20 -94
- data/app/controllers/scimitar/application_controller.rb +13 -41
- data/app/controllers/scimitar/schemas_controller.rb +0 -5
- data/app/models/scimitar/complex_types/address.rb +6 -0
- data/app/models/scimitar/engine_configuration.rb +5 -13
- data/app/models/scimitar/error_response.rb +0 -12
- data/app/models/scimitar/lists/query_parser.rb +10 -25
- data/app/models/scimitar/resource_invalid_error.rb +1 -1
- data/app/models/scimitar/resources/base.rb +4 -17
- data/app/models/scimitar/resources/mixin.rb +42 -539
- data/app/models/scimitar/schema/address.rb +0 -1
- data/app/models/scimitar/schema/attribute.rb +5 -14
- data/app/models/scimitar/schema/base.rb +1 -1
- data/app/models/scimitar/schema/vdtp.rb +1 -1
- data/app/models/scimitar/service_provider_configuration.rb +3 -14
- data/config/initializers/scimitar.rb +3 -28
- data/lib/scimitar/support/hash_with_indifferent_case_insensitive_access.rb +10 -140
- data/lib/scimitar/version.rb +2 -2
- data/lib/scimitar.rb +2 -7
- 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 +8 -36
- data/spec/apps/dummy/config/application.rb +1 -0
- data/spec/apps/dummy/config/environments/test.rb +28 -5
- data/spec/apps/dummy/config/initializers/scimitar.rb +10 -61
- data/spec/apps/dummy/config/routes.rb +7 -28
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -10
- data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
- data/spec/apps/dummy/db/schema.rb +4 -11
- data/spec/controllers/scimitar/application_controller_spec.rb +3 -126
- data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
- data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -10
- data/spec/models/scimitar/complex_types/address_spec.rb +4 -3
- data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
- data/spec/models/scimitar/lists/query_parser_spec.rb +9 -76
- data/spec/models/scimitar/resources/base_spec.rb +70 -216
- data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
- data/spec/models/scimitar/resources/mixin_spec.rb +129 -1447
- data/spec/models/scimitar/schema/attribute_spec.rb +3 -22
- data/spec/models/scimitar/schema/base_spec.rb +1 -1
- data/spec/models/scimitar/schema/user_spec.rb +0 -10
- data/spec/requests/active_record_backed_resources_controller_spec.rb +68 -787
- data/spec/requests/application_controller_spec.rb +3 -16
- data/spec/spec_helper.rb +0 -8
- data/spec/support/hash_with_indifferent_case_insensitive_access_spec.rb +0 -108
- metadata +14 -25
- data/LICENSE.txt +0 -21
- data/README.md +0 -710
- data/lib/scimitar/support/utilities.rb +0 -51
- data/spec/apps/dummy/app/controllers/custom_create_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_replace_mock_users_controller.rb +0 -25
- data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +0 -24
- data/spec/apps/dummy/app/controllers/custom_update_mock_users_controller.rb +0 -25
@@ -81,102 +81,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
81
81
|
include Scimitar::Resources::Mixin
|
82
82
|
end
|
83
83
|
|
84
|
-
# A simple schema containing two attributes that looks very like complex
|
85
|
-
# type "name", except shorter and with "familyName" never returned.
|
86
|
-
#
|
87
|
-
NestedReturnedNeverTestNameSchema = Class.new(Scimitar::Schema::Base) do
|
88
|
-
def self.id
|
89
|
-
'nested-returned-never-name-id'
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.scim_attributes
|
93
|
-
@scim_attributes ||= [
|
94
|
-
Scimitar::Schema::Attribute.new(name: 'familyName', type: 'string', required: true, returned: 'never'),
|
95
|
-
Scimitar::Schema::Attribute.new(name: 'givenName', type: 'string', required: true)
|
96
|
-
]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
# A complex type that uses the above schema, giving us the ability to define
|
101
|
-
# an attribute using this complex type, with therefore the *nested* attribute
|
102
|
-
# "familyName" being never returned.
|
103
|
-
#
|
104
|
-
NestedReturnedNeverTestNameType = Class.new(Scimitar::ComplexTypes::Base) do
|
105
|
-
set_schema NestedReturnedNeverTestNameSchema
|
106
|
-
end
|
107
|
-
|
108
|
-
# A test schema that uses the above type, the standard name type (but that
|
109
|
-
# *entire* top-level attribute is never returned) and a simple String item.
|
110
|
-
#
|
111
|
-
NestedReturnedNeverTestSchema = Class.new(Scimitar::Schema::Base) do
|
112
|
-
def self.id
|
113
|
-
'nested-returned-never-id'
|
114
|
-
end
|
115
|
-
|
116
|
-
def self.scim_attributes
|
117
|
-
[
|
118
|
-
Scimitar::Schema::Attribute.new(
|
119
|
-
name: 'name', complexType: NestedReturnedNeverTestNameType
|
120
|
-
),
|
121
|
-
Scimitar::Schema::Attribute.new(
|
122
|
-
name: 'privateName', complexType: Scimitar::ComplexTypes::Name, returned: 'never'
|
123
|
-
),
|
124
|
-
Scimitar::Schema::Attribute.new(
|
125
|
-
name: 'simpleName', type: 'string'
|
126
|
-
)
|
127
|
-
]
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Define a resource that is based upon the above schema.
|
132
|
-
#
|
133
|
-
NestedReturnedNeverTestResourse = Class.new(Scimitar::Resources::Base) do
|
134
|
-
set_schema NestedReturnedNeverTestSchema
|
135
|
-
end
|
136
|
-
|
137
|
-
# Create a testable model that is our internal representation of the above
|
138
|
-
# resource.
|
139
|
-
#
|
140
|
-
class NestedReturnedNeverTest
|
141
|
-
include ActiveModel::Model
|
142
|
-
|
143
|
-
def self.scim_resource_type
|
144
|
-
return NestedReturnedNeverTestResourse
|
145
|
-
end
|
146
|
-
|
147
|
-
attr_accessor :given_name,
|
148
|
-
:last_name,
|
149
|
-
:private_given_name,
|
150
|
-
:private_last_name,
|
151
|
-
:simple_name
|
152
|
-
|
153
|
-
def self.scim_attributes_map
|
154
|
-
return {
|
155
|
-
name: {
|
156
|
-
givenName: :given_name,
|
157
|
-
familyName: :last_name
|
158
|
-
},
|
159
|
-
|
160
|
-
privateName: {
|
161
|
-
givenName: :private_given_name,
|
162
|
-
familyName: :private_last_name
|
163
|
-
},
|
164
|
-
|
165
|
-
simpleName: :simple_name
|
166
|
-
}
|
167
|
-
end
|
168
|
-
|
169
|
-
def self.scim_mutable_attributes
|
170
|
-
return nil
|
171
|
-
end
|
172
|
-
|
173
|
-
def self.scim_queryable_attributes
|
174
|
-
return nil
|
175
|
-
end
|
176
|
-
|
177
|
-
include Scimitar::Resources::Mixin
|
178
|
-
end
|
179
|
-
|
180
84
|
# ===========================================================================
|
181
85
|
# Errant class definitions
|
182
86
|
# ===========================================================================
|
@@ -255,74 +159,41 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
255
159
|
# =========================================================================
|
256
160
|
|
257
161
|
context '#to_scim' do
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
'groups' => [{'display'=>g1.display_name, 'value'=>g1.id.to_s}, {'display'=>g3.display_name, 'value'=>g3.id.to_s}],
|
294
|
-
'meta' => {'location'=>"https://test.com/mock_users/#{uuid}", 'resourceType'=>'User'},
|
295
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User', 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'],
|
296
|
-
|
297
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {
|
298
|
-
'organization' => 'SOMEORG',
|
299
|
-
'department' => nil
|
300
|
-
}
|
301
|
-
})
|
302
|
-
end
|
303
|
-
end # "context 'with a UUID, renamed primary key column' do"
|
304
|
-
|
305
|
-
context 'with an integer, conventionally named primary key column' do
|
306
|
-
it 'compiles instance attribute values into a SCIM representation' do
|
307
|
-
instance = MockGroup.new
|
308
|
-
instance.id = 42
|
309
|
-
instance.scim_uid = 'GG02984'
|
310
|
-
instance.display_name = 'Some group'
|
311
|
-
|
312
|
-
scim = instance.to_scim(location: 'https://test.com/mock_groups/42')
|
313
|
-
json = scim.to_json()
|
314
|
-
hash = JSON.parse(json)
|
315
|
-
|
316
|
-
expect(hash).to eql({
|
317
|
-
'displayName' => 'Some group',
|
318
|
-
'id' => '42', # Note, String
|
319
|
-
'externalId' => 'GG02984',
|
320
|
-
'members' => [],
|
321
|
-
'meta' => {'location'=>'https://test.com/mock_groups/42', 'resourceType'=>'Group'},
|
322
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:Group']
|
323
|
-
})
|
324
|
-
end
|
325
|
-
end # "context 'with an integer, conventionally named primary key column' do"
|
162
|
+
it 'compiles instance attribute values into a SCIM representation' do
|
163
|
+
instance = MockUser.new
|
164
|
+
instance.id = 42
|
165
|
+
instance.scim_uid = 'AA02984'
|
166
|
+
instance.username = 'foo'
|
167
|
+
instance.first_name = 'Foo'
|
168
|
+
instance.last_name = 'Bar'
|
169
|
+
instance.work_email_address = 'foo.bar@test.com'
|
170
|
+
instance.home_email_address = nil
|
171
|
+
instance.work_phone_number = '+642201234567'
|
172
|
+
|
173
|
+
g1 = MockGroup.create!(display_name: 'Group 1')
|
174
|
+
g2 = MockGroup.create!(display_name: 'Group 2')
|
175
|
+
g3 = MockGroup.create!(display_name: 'Group 3')
|
176
|
+
|
177
|
+
g1.mock_users << instance
|
178
|
+
g3.mock_users << instance
|
179
|
+
|
180
|
+
scim = instance.to_scim(location: 'https://test.com/mock_users/42')
|
181
|
+
json = scim.to_json()
|
182
|
+
hash = JSON.parse(json)
|
183
|
+
|
184
|
+
expect(hash).to eql({
|
185
|
+
'userName' => 'foo',
|
186
|
+
'name' => {'givenName'=>'Foo', 'familyName'=>'Bar'},
|
187
|
+
'active' => true,
|
188
|
+
'emails' => [{'type'=>'work', 'primary'=>true, 'value'=>'foo.bar@test.com'}, {"primary"=>false, "type"=>"home", "value"=>nil}],
|
189
|
+
'phoneNumbers'=> [{'type'=>'work', 'primary'=>false, 'value'=>'+642201234567'}],
|
190
|
+
'id' => '42', # Note, String
|
191
|
+
'externalId' => 'AA02984',
|
192
|
+
'groups' => [{'display'=>g1.display_name, 'value'=>g1.id.to_s}, {'display'=>g3.display_name, 'value'=>g3.id.to_s}],
|
193
|
+
'meta' => {'location'=>'https://test.com/mock_users/42', 'resourceType'=>'User'},
|
194
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
195
|
+
})
|
196
|
+
end
|
326
197
|
|
327
198
|
context 'with optional timestamps' do
|
328
199
|
context 'creation only' do
|
@@ -421,9 +292,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
421
292
|
],
|
422
293
|
|
423
294
|
'meta' => {'location'=>'https://test.com/static_map_test', 'resourceType'=>'User'},
|
424
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User'
|
425
|
-
|
426
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {}
|
295
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
427
296
|
})
|
428
297
|
end
|
429
298
|
end # "context 'using static mappings' do"
|
@@ -450,38 +319,12 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
450
319
|
],
|
451
320
|
|
452
321
|
'meta' => {'location'=>'https://test.com/dynamic_map_test', 'resourceType'=>'User'},
|
453
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User'
|
454
|
-
|
455
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {}
|
322
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
456
323
|
})
|
457
324
|
end
|
458
325
|
end # "context 'using dynamic lists' do"
|
459
326
|
end # "context 'with arrays' do"
|
460
327
|
|
461
|
-
context 'with "returned: \'never\' fields' do
|
462
|
-
it 'hides appropriate top-level and nested attributes' do
|
463
|
-
instance = NestedReturnedNeverTest.new(
|
464
|
-
given_name: 'One',
|
465
|
-
last_name: 'Two',
|
466
|
-
private_given_name: 'Three',
|
467
|
-
private_last_name: 'Four',
|
468
|
-
simple_name: 'Five'
|
469
|
-
)
|
470
|
-
|
471
|
-
scim = instance.to_scim(location: 'https://test.com/never_retutrned_test')
|
472
|
-
json = scim.to_json()
|
473
|
-
hash = JSON.parse(json)
|
474
|
-
|
475
|
-
expect(hash).to eql({
|
476
|
-
'name' => { 'givenName' => 'One' },
|
477
|
-
'simpleName' => 'Five',
|
478
|
-
|
479
|
-
'meta' => {'location'=>'https://test.com/never_retutrned_test', 'resourceType'=>'NestedReturnedNeverTestResourse'},
|
480
|
-
'schemas' => ['nested-returned-never-id']
|
481
|
-
})
|
482
|
-
end
|
483
|
-
end # "context 'with "returned: \'never\' fields' do"
|
484
|
-
|
485
328
|
context 'with bad definitions' do
|
486
329
|
it 'complains about non-Hash entries in mapping Arrays' do
|
487
330
|
expect(StaticMapTest).to receive(:scim_attributes_map).and_return({
|
@@ -525,7 +368,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
525
368
|
it 'ignoring read-only lists' do
|
526
369
|
hash = {
|
527
370
|
'userName' => 'foo',
|
528
|
-
'password' => 'staplebatteryhorsecorrect',
|
529
371
|
'name' => {'givenName' => 'Foo', 'familyName' => 'Bar'},
|
530
372
|
'active' => true,
|
531
373
|
'emails' => [{'type' => 'work', 'primary' => true, 'value' => 'foo.bar@test.com'}],
|
@@ -534,12 +376,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
534
376
|
'id' => '42', # Note, String
|
535
377
|
'externalId' => 'AA02984',
|
536
378
|
'meta' => {'location' => 'https://test.com/mock_users/42', 'resourceType' => 'User'},
|
537
|
-
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User'
|
538
|
-
|
539
|
-
'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => {
|
540
|
-
'organization' => 'SOMEORG',
|
541
|
-
'DEPARTMENT' => 'SOMEDPT'
|
542
|
-
}
|
379
|
+
'schemas' => ['urn:ietf:params:scim:schemas:core:2.0:User']
|
543
380
|
}
|
544
381
|
|
545
382
|
hash = spec_helper_hupcase(hash) if force_upper_case
|
@@ -550,14 +387,11 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
550
387
|
|
551
388
|
expect(instance.scim_uid ).to eql('AA02984')
|
552
389
|
expect(instance.username ).to eql('foo')
|
553
|
-
expect(instance.password ).to eql('staplebatteryhorsecorrect')
|
554
390
|
expect(instance.first_name ).to eql('Foo')
|
555
391
|
expect(instance.last_name ).to eql('Bar')
|
556
392
|
expect(instance.work_email_address).to eql('foo.bar@test.com')
|
557
393
|
expect(instance.home_email_address).to be_nil
|
558
394
|
expect(instance.work_phone_number ).to eql('+642201234567')
|
559
|
-
expect(instance.organization ).to eql('SOMEORG')
|
560
|
-
expect(instance.department ).to eql('SOMEDPT')
|
561
395
|
end
|
562
396
|
|
563
397
|
it 'honouring read-write lists' do
|
@@ -571,8 +405,8 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
571
405
|
'displayName' => 'Foo Group',
|
572
406
|
'members' => [
|
573
407
|
{'type' => 'Group', 'value' => g1.id.to_s},
|
574
|
-
{'type' => 'User', 'value' => u1.
|
575
|
-
{'type' => 'User', 'value' => u3.
|
408
|
+
{'type' => 'User', 'value' => u1.id.to_s},
|
409
|
+
{'type' => 'User', 'value' => u3.id.to_s}
|
576
410
|
],
|
577
411
|
'externalId' => 'GG01536',
|
578
412
|
'meta' => {'location'=>'https://test.com/mock_groups/1', 'resourceType'=>'Group'},
|
@@ -619,10 +453,8 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
619
453
|
end # "context 'using upper case' do"
|
620
454
|
|
621
455
|
it 'clears things not present in input' do
|
622
|
-
uuid = SecureRandom.uuid
|
623
|
-
|
624
456
|
instance = MockUser.new
|
625
|
-
instance.
|
457
|
+
instance.id = 42
|
626
458
|
instance.scim_uid = 'AA02984'
|
627
459
|
instance.username = 'foo'
|
628
460
|
instance.first_name = 'Foo'
|
@@ -633,7 +465,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
633
465
|
|
634
466
|
instance.from_scim!(scim_hash: {})
|
635
467
|
|
636
|
-
expect(instance.
|
468
|
+
expect(instance.id ).to eql(42)
|
637
469
|
expect(instance.scim_uid ).to be_nil
|
638
470
|
expect(instance.username ).to be_nil
|
639
471
|
expect(instance.first_name ).to be_nil
|
@@ -822,8 +654,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
822
654
|
nature: 'add',
|
823
655
|
path: path,
|
824
656
|
value: 'foo',
|
825
|
-
altering_hash: scim_hash
|
826
|
-
with_attr_map: { userName: :user_name }
|
657
|
+
altering_hash: scim_hash
|
827
658
|
)
|
828
659
|
|
829
660
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -838,30 +669,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
838
669
|
nature: 'add',
|
839
670
|
path: path,
|
840
671
|
value: 'Baz',
|
841
|
-
altering_hash: scim_hash
|
842
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
672
|
+
altering_hash: scim_hash
|
843
673
|
)
|
844
674
|
|
845
675
|
expect(scim_hash['name']['givenName' ]).to eql('Baz')
|
846
676
|
expect(scim_hash['name']['familyName']).to eql('Bar')
|
847
677
|
end
|
848
678
|
|
849
|
-
it 'with schema extensions: overwrites' do
|
850
|
-
path = [ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User', 'organization' ]
|
851
|
-
scim_hash = { 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User' => { 'organization' => 'SOMEORG' } }.with_indifferent_case_insensitive_access()
|
852
|
-
|
853
|
-
@instance.send(
|
854
|
-
:from_patch_backend!,
|
855
|
-
nature: 'add',
|
856
|
-
path: path,
|
857
|
-
value: 'OTHERORG',
|
858
|
-
altering_hash: scim_hash,
|
859
|
-
with_attr_map: { organization: :org_name }
|
860
|
-
)
|
861
|
-
|
862
|
-
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('OTHERORG')
|
863
|
-
end
|
864
|
-
|
865
679
|
# For 'add', filter at end-of-path is nonsensical and not
|
866
680
|
# supported by spec or Scimitar; we only test mid-path filters.
|
867
681
|
#
|
@@ -886,13 +700,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
886
700
|
nature: 'add',
|
887
701
|
path: path,
|
888
702
|
value: 'added_over_original@test.com',
|
889
|
-
altering_hash: scim_hash
|
890
|
-
with_attr_map: {
|
891
|
-
emails: [
|
892
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
893
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
894
|
-
]
|
895
|
-
}
|
703
|
+
altering_hash: scim_hash
|
896
704
|
)
|
897
705
|
|
898
706
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -918,13 +726,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
918
726
|
nature: 'add',
|
919
727
|
path: path,
|
920
728
|
value: 'added_over_original@test.com',
|
921
|
-
altering_hash: scim_hash
|
922
|
-
with_attr_map: {
|
923
|
-
emails: [
|
924
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
925
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
926
|
-
]
|
927
|
-
}
|
729
|
+
altering_hash: scim_hash
|
928
730
|
)
|
929
731
|
|
930
732
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -951,13 +753,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
951
753
|
nature: 'add',
|
952
754
|
path: path,
|
953
755
|
value: 'added_over_original@test.com',
|
954
|
-
altering_hash: scim_hash
|
955
|
-
with_attr_map: {
|
956
|
-
emails: [
|
957
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
958
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
959
|
-
]
|
960
|
-
}
|
756
|
+
altering_hash: scim_hash
|
961
757
|
)
|
962
758
|
|
963
759
|
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
|
@@ -981,13 +777,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
981
777
|
nature: 'add',
|
982
778
|
path: path,
|
983
779
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
984
|
-
altering_hash: scim_hash
|
985
|
-
with_attr_map: {
|
986
|
-
emails: [
|
987
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
988
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
989
|
-
]
|
990
|
-
}
|
780
|
+
altering_hash: scim_hash
|
991
781
|
)
|
992
782
|
|
993
783
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -1035,12 +825,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1035
825
|
nature: 'add',
|
1036
826
|
path: ['root'],
|
1037
827
|
value: {'members' => [{'value' => '3'}]},
|
1038
|
-
altering_hash: scim_hash
|
1039
|
-
with_attr_map: {
|
1040
|
-
members: [
|
1041
|
-
{ list: :members, using: { value: :id } }
|
1042
|
-
]
|
1043
|
-
}
|
828
|
+
altering_hash: scim_hash
|
1044
829
|
)
|
1045
830
|
|
1046
831
|
expect(scim_hash['root']['members']).to match_array([{'value' => '1'}, {'value' => '2'}, {'value' => '3'}])
|
@@ -1058,8 +843,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1058
843
|
nature: 'add',
|
1059
844
|
path: path,
|
1060
845
|
value: 'foo',
|
1061
|
-
altering_hash: scim_hash
|
1062
|
-
with_attr_map: { userName: :user_name }
|
846
|
+
altering_hash: scim_hash
|
1063
847
|
)
|
1064
848
|
|
1065
849
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -1074,29 +858,12 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1074
858
|
nature: 'add',
|
1075
859
|
path: path,
|
1076
860
|
value: 'Baz',
|
1077
|
-
altering_hash: scim_hash
|
1078
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
861
|
+
altering_hash: scim_hash
|
1079
862
|
)
|
1080
863
|
|
1081
864
|
expect(scim_hash['name']['givenName']).to eql('Baz')
|
1082
865
|
end
|
1083
866
|
|
1084
|
-
it 'with schema extensions: adds' do
|
1085
|
-
path = [ 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User', 'organization' ]
|
1086
|
-
scim_hash = {}.with_indifferent_case_insensitive_access()
|
1087
|
-
|
1088
|
-
@instance.send(
|
1089
|
-
:from_patch_backend!,
|
1090
|
-
nature: 'add',
|
1091
|
-
path: path,
|
1092
|
-
value: 'SOMEORG',
|
1093
|
-
altering_hash: scim_hash,
|
1094
|
-
with_attr_map: { organization: :org_name }
|
1095
|
-
)
|
1096
|
-
|
1097
|
-
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('SOMEORG')
|
1098
|
-
end
|
1099
|
-
|
1100
867
|
context 'with filter mid-path: adds' do
|
1101
868
|
it 'by string match' do
|
1102
869
|
path = [ 'emails[type eq "work"]', 'value' ]
|
@@ -1117,13 +884,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1117
884
|
nature: 'add',
|
1118
885
|
path: path,
|
1119
886
|
value: 'added@test.com',
|
1120
|
-
altering_hash: scim_hash
|
1121
|
-
with_attr_map: {
|
1122
|
-
emails: [
|
1123
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1124
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1125
|
-
]
|
1126
|
-
}
|
887
|
+
altering_hash: scim_hash
|
1127
888
|
)
|
1128
889
|
|
1129
890
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -1148,13 +909,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1148
909
|
nature: 'add',
|
1149
910
|
path: path,
|
1150
911
|
value: 'added@test.com',
|
1151
|
-
altering_hash: scim_hash
|
1152
|
-
with_attr_map: {
|
1153
|
-
emails: [
|
1154
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1155
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1156
|
-
]
|
1157
|
-
}
|
912
|
+
altering_hash: scim_hash
|
1158
913
|
)
|
1159
914
|
|
1160
915
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -1170,13 +925,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1170
925
|
nature: 'add',
|
1171
926
|
path: path,
|
1172
927
|
value: 'added@test.com',
|
1173
|
-
altering_hash: scim_hash
|
1174
|
-
with_attr_map: {
|
1175
|
-
emails: [
|
1176
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1177
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1178
|
-
]
|
1179
|
-
}
|
928
|
+
altering_hash: scim_hash
|
1180
929
|
)
|
1181
930
|
|
1182
931
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -1200,13 +949,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1200
949
|
nature: 'add',
|
1201
950
|
path: path,
|
1202
951
|
value: 'added@test.com',
|
1203
|
-
altering_hash: scim_hash
|
1204
|
-
with_attr_map: {
|
1205
|
-
emails: [
|
1206
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1207
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1208
|
-
]
|
1209
|
-
}
|
952
|
+
altering_hash: scim_hash
|
1210
953
|
)
|
1211
954
|
|
1212
955
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -1223,13 +966,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1223
966
|
nature: 'add',
|
1224
967
|
path: path,
|
1225
968
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
1226
|
-
altering_hash: scim_hash
|
1227
|
-
with_attr_map: {
|
1228
|
-
emails: [
|
1229
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1230
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1231
|
-
]
|
1232
|
-
}
|
969
|
+
altering_hash: scim_hash
|
1233
970
|
)
|
1234
971
|
|
1235
972
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -1245,7 +982,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1245
982
|
#
|
1246
983
|
context 'remove' do
|
1247
984
|
context 'when prior value already exists' do
|
1248
|
-
it 'simple value:
|
985
|
+
it 'simple value: removes' do
|
1249
986
|
path = [ 'userName' ]
|
1250
987
|
scim_hash = { 'userName' => 'bar' }.with_indifferent_case_insensitive_access()
|
1251
988
|
|
@@ -1254,14 +991,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1254
991
|
nature: 'remove',
|
1255
992
|
path: path,
|
1256
993
|
value: nil,
|
1257
|
-
altering_hash: scim_hash
|
1258
|
-
with_attr_map: { userName: :user_name }
|
994
|
+
altering_hash: scim_hash
|
1259
995
|
)
|
1260
996
|
|
1261
|
-
expect(scim_hash).to
|
997
|
+
expect(scim_hash).to be_empty
|
1262
998
|
end
|
1263
999
|
|
1264
|
-
it 'nested simple value:
|
1000
|
+
it 'nested simple value: removes' do
|
1265
1001
|
path = [ 'name', 'givenName' ]
|
1266
1002
|
scim_hash = { 'name' => { 'givenName' => 'Foo', 'familyName' => 'Bar' } }.with_indifferent_case_insensitive_access()
|
1267
1003
|
|
@@ -1270,15 +1006,15 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1270
1006
|
nature: 'remove',
|
1271
1007
|
path: path,
|
1272
1008
|
value: nil,
|
1273
|
-
altering_hash: scim_hash
|
1274
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1009
|
+
altering_hash: scim_hash
|
1275
1010
|
)
|
1276
1011
|
|
1277
|
-
expect(scim_hash).
|
1012
|
+
expect(scim_hash['name']).to_not have_key('givenName')
|
1013
|
+
expect(scim_hash['name']['familyName']).to eql('Bar')
|
1278
1014
|
end
|
1279
1015
|
|
1280
1016
|
context 'with filter mid-path' do
|
1281
|
-
it 'by string match:
|
1017
|
+
it 'by string match: removes' do
|
1282
1018
|
path = [ 'emails[type eq "work"]', 'value' ]
|
1283
1019
|
scim_hash = {
|
1284
1020
|
'emails' => [
|
@@ -1298,30 +1034,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1298
1034
|
nature: 'remove',
|
1299
1035
|
path: path,
|
1300
1036
|
value: nil,
|
1301
|
-
altering_hash: scim_hash
|
1302
|
-
with_attr_map: {
|
1303
|
-
emails: [
|
1304
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1305
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1306
|
-
]
|
1307
|
-
}
|
1037
|
+
altering_hash: scim_hash
|
1308
1038
|
)
|
1309
1039
|
|
1310
|
-
expect(scim_hash).to eql(
|
1311
|
-
|
1312
|
-
{
|
1313
|
-
'type' => 'home',
|
1314
|
-
'value' => 'home@test.com'
|
1315
|
-
},
|
1316
|
-
{
|
1317
|
-
'type' => 'work',
|
1318
|
-
'value' => nil
|
1319
|
-
}
|
1320
|
-
]
|
1321
|
-
})
|
1040
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1041
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1322
1042
|
end
|
1323
1043
|
|
1324
|
-
it 'by boolean match:
|
1044
|
+
it 'by boolean match: removes' do
|
1325
1045
|
path = [ 'emails[primary eq true]', 'value' ]
|
1326
1046
|
scim_hash = {
|
1327
1047
|
'emails' => [
|
@@ -1340,29 +1060,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1340
1060
|
nature: 'remove',
|
1341
1061
|
path: path,
|
1342
1062
|
value: nil,
|
1343
|
-
altering_hash: scim_hash
|
1344
|
-
with_attr_map: {
|
1345
|
-
emails: [
|
1346
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1347
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1348
|
-
]
|
1349
|
-
}
|
1063
|
+
altering_hash: scim_hash
|
1350
1064
|
)
|
1351
1065
|
|
1352
|
-
expect(scim_hash).to eql(
|
1353
|
-
|
1354
|
-
{
|
1355
|
-
'value' => 'home@test.com'
|
1356
|
-
},
|
1357
|
-
{
|
1358
|
-
'value' => nil,
|
1359
|
-
'primary' => true
|
1360
|
-
}
|
1361
|
-
]
|
1362
|
-
})
|
1066
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1067
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1363
1068
|
end
|
1364
1069
|
|
1365
|
-
it 'multiple matches:
|
1070
|
+
it 'multiple matches: removes all' do
|
1366
1071
|
path = [ 'emails[type eq "work"]', 'value' ]
|
1367
1072
|
scim_hash = {
|
1368
1073
|
'emails' => [
|
@@ -1373,11 +1078,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1373
1078
|
{
|
1374
1079
|
'type' => 'work',
|
1375
1080
|
'value' => 'work_2@test.com'
|
1376
|
-
}
|
1377
|
-
{
|
1378
|
-
'type' => 'home',
|
1379
|
-
'value' => 'home@test.com'
|
1380
|
-
},
|
1081
|
+
}
|
1381
1082
|
]
|
1382
1083
|
}.with_indifferent_case_insensitive_access()
|
1383
1084
|
|
@@ -1386,36 +1087,16 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1386
1087
|
nature: 'remove',
|
1387
1088
|
path: path,
|
1388
1089
|
value: nil,
|
1389
|
-
altering_hash: scim_hash
|
1390
|
-
with_attr_map: {
|
1391
|
-
emails: [
|
1392
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1393
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1394
|
-
]
|
1395
|
-
}
|
1090
|
+
altering_hash: scim_hash
|
1396
1091
|
)
|
1397
1092
|
|
1398
|
-
expect(scim_hash).
|
1399
|
-
|
1400
|
-
{
|
1401
|
-
'type' => 'work',
|
1402
|
-
'value' => nil
|
1403
|
-
},
|
1404
|
-
{
|
1405
|
-
'type' => 'work',
|
1406
|
-
'value' => nil
|
1407
|
-
},
|
1408
|
-
{
|
1409
|
-
'type' => 'home',
|
1410
|
-
'value' => 'home@test.com'
|
1411
|
-
},
|
1412
|
-
]
|
1413
|
-
})
|
1093
|
+
expect(scim_hash['emails'][0]).to_not have_key('value')
|
1094
|
+
expect(scim_hash['emails'][1]).to_not have_key('value')
|
1414
1095
|
end
|
1415
1096
|
end # "context 'with filter mid-path' do"
|
1416
1097
|
|
1417
1098
|
context 'with filter at end of path' do
|
1418
|
-
it 'by string match:
|
1099
|
+
it 'by string match: removes entire matching array entry' do
|
1419
1100
|
path = [ 'emails[type eq "work"]' ]
|
1420
1101
|
scim_hash = {
|
1421
1102
|
'emails' => [
|
@@ -1435,39 +1116,23 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1435
1116
|
nature: 'remove',
|
1436
1117
|
path: path,
|
1437
1118
|
value: nil,
|
1438
|
-
altering_hash: scim_hash
|
1439
|
-
with_attr_map: {
|
1440
|
-
emails: [
|
1441
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1442
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1443
|
-
]
|
1444
|
-
}
|
1119
|
+
altering_hash: scim_hash
|
1445
1120
|
)
|
1446
1121
|
|
1447
|
-
expect(scim_hash).to eql(
|
1448
|
-
|
1449
|
-
{
|
1450
|
-
'type' => 'home',
|
1451
|
-
'value' => 'home@test.com'
|
1452
|
-
},
|
1453
|
-
{
|
1454
|
-
'type' => 'work',
|
1455
|
-
'value' => nil
|
1456
|
-
}
|
1457
|
-
]
|
1458
|
-
})
|
1122
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1123
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1459
1124
|
end
|
1460
1125
|
|
1461
|
-
it 'by boolean match:
|
1126
|
+
it 'by boolean match: removes entire matching array entry' do
|
1462
1127
|
path = [ 'emails[primary eq true]' ]
|
1463
1128
|
scim_hash = {
|
1464
1129
|
'emails' => [
|
1465
1130
|
{
|
1466
|
-
'value' => 'home@test.com'
|
1467
|
-
'primary' => true
|
1131
|
+
'value' => 'home@test.com'
|
1468
1132
|
},
|
1469
1133
|
{
|
1470
|
-
'value' => 'work@test.com'
|
1134
|
+
'value' => 'work@test.com',
|
1135
|
+
'primary' => true
|
1471
1136
|
}
|
1472
1137
|
]
|
1473
1138
|
}.with_indifferent_case_insensitive_access()
|
@@ -1477,29 +1142,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1477
1142
|
nature: 'remove',
|
1478
1143
|
path: path,
|
1479
1144
|
value: nil,
|
1480
|
-
altering_hash: scim_hash
|
1481
|
-
with_attr_map: {
|
1482
|
-
emails: [
|
1483
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1484
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1485
|
-
]
|
1486
|
-
}
|
1145
|
+
altering_hash: scim_hash
|
1487
1146
|
)
|
1488
1147
|
|
1489
|
-
expect(scim_hash).to eql(
|
1490
|
-
|
1491
|
-
{
|
1492
|
-
'value' => nil,
|
1493
|
-
'primary' => true
|
1494
|
-
},
|
1495
|
-
{
|
1496
|
-
'value' => 'work@test.com'
|
1497
|
-
}
|
1498
|
-
]
|
1499
|
-
})
|
1148
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1149
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1500
1150
|
end
|
1501
1151
|
|
1502
|
-
it 'multiple matches:
|
1152
|
+
it 'multiple matches: removes all matching array entries' do
|
1503
1153
|
path = [ 'emails[type eq "work"]' ]
|
1504
1154
|
scim_hash = {
|
1505
1155
|
'emails' => [
|
@@ -1523,45 +1173,21 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1523
1173
|
nature: 'remove',
|
1524
1174
|
path: path,
|
1525
1175
|
value: nil,
|
1526
|
-
altering_hash: scim_hash
|
1527
|
-
with_attr_map: {
|
1528
|
-
emails: [
|
1529
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1530
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1531
|
-
]
|
1532
|
-
}
|
1176
|
+
altering_hash: scim_hash
|
1533
1177
|
)
|
1534
1178
|
|
1535
|
-
expect(scim_hash).to eql(
|
1536
|
-
|
1537
|
-
{
|
1538
|
-
'type' => 'work',
|
1539
|
-
'value' => nil
|
1540
|
-
},
|
1541
|
-
{
|
1542
|
-
'type' => 'work',
|
1543
|
-
'value' => nil
|
1544
|
-
},
|
1545
|
-
{
|
1546
|
-
'type' => 'home',
|
1547
|
-
'value' => 'home@test.com'
|
1548
|
-
},
|
1549
|
-
]
|
1550
|
-
})
|
1179
|
+
expect(scim_hash['emails'].size).to eql(1)
|
1180
|
+
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
1551
1181
|
end
|
1552
1182
|
end # "context 'with filter at end of path' do"
|
1553
1183
|
|
1554
|
-
it 'whole array:
|
1184
|
+
it 'whole array: removes' do
|
1555
1185
|
path = [ 'emails' ]
|
1556
1186
|
scim_hash = {
|
1557
1187
|
'emails' => [
|
1558
1188
|
{
|
1559
1189
|
'type' => 'home',
|
1560
1190
|
'value' => 'home@test.com'
|
1561
|
-
},
|
1562
|
-
{
|
1563
|
-
'type' => 'work',
|
1564
|
-
'value' => 'work@test.com'
|
1565
1191
|
}
|
1566
1192
|
]
|
1567
1193
|
}.with_indifferent_case_insensitive_access()
|
@@ -1571,741 +1197,11 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
1571
1197
|
nature: 'remove',
|
1572
1198
|
path: path,
|
1573
1199
|
value: nil,
|
1574
|
-
altering_hash: scim_hash
|
1575
|
-
with_attr_map: {
|
1576
|
-
emails: [
|
1577
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1578
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1579
|
-
]
|
1580
|
-
}
|
1200
|
+
altering_hash: scim_hash
|
1581
1201
|
)
|
1582
1202
|
|
1583
|
-
expect(scim_hash).
|
1584
|
-
'emails' => [
|
1585
|
-
{
|
1586
|
-
'type' => 'home',
|
1587
|
-
'value' => nil
|
1588
|
-
},
|
1589
|
-
{
|
1590
|
-
'type' => 'work',
|
1591
|
-
'value' => nil
|
1592
|
-
}
|
1593
|
-
]
|
1594
|
-
})
|
1203
|
+
expect(scim_hash).to_not have_key('emails')
|
1595
1204
|
end
|
1596
|
-
|
1597
|
-
# What we expect:
|
1598
|
-
#
|
1599
|
-
# https://tools.ietf.org/html/rfc7644#section-3.5.2.2
|
1600
|
-
# https://docs.snowflake.com/en/user-guide/scim-intro.html#patch-scim-v2-groups-id
|
1601
|
-
#
|
1602
|
-
# ...vs accounting for the unusual payloads we sometimes get,
|
1603
|
-
# tested here.
|
1604
|
-
#
|
1605
|
-
context 'special cases' do
|
1606
|
-
|
1607
|
-
# https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
|
1608
|
-
#
|
1609
|
-
context 'Microsoft-style payload' do
|
1610
|
-
context 'removing a user from a group' do
|
1611
|
-
it 'removes identified user' do
|
1612
|
-
path = [ 'members' ]
|
1613
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
|
1614
|
-
scim_hash = {
|
1615
|
-
'displayname' => 'Mock group',
|
1616
|
-
'members' => [
|
1617
|
-
{
|
1618
|
-
'value' => '50ca93d04ab0c2de4772',
|
1619
|
-
'display' => 'Ingrid Smith',
|
1620
|
-
'type' => 'User'
|
1621
|
-
},
|
1622
|
-
{
|
1623
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1624
|
-
'display' => 'Fred Smith',
|
1625
|
-
'type' => 'User'
|
1626
|
-
},
|
1627
|
-
{
|
1628
|
-
'value' => 'a774d480e8112101375b',
|
1629
|
-
'display' => 'Taylor Smith',
|
1630
|
-
'type' => 'User'
|
1631
|
-
}
|
1632
|
-
]
|
1633
|
-
}.with_indifferent_case_insensitive_access()
|
1634
|
-
|
1635
|
-
@instance.send(
|
1636
|
-
:from_patch_backend!,
|
1637
|
-
nature: 'remove',
|
1638
|
-
path: path,
|
1639
|
-
value: value,
|
1640
|
-
altering_hash: scim_hash,
|
1641
|
-
with_attr_map: {
|
1642
|
-
members: [
|
1643
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1644
|
-
]
|
1645
|
-
}
|
1646
|
-
)
|
1647
|
-
|
1648
|
-
expect(scim_hash).to eql({
|
1649
|
-
'displayname' => 'Mock group',
|
1650
|
-
'members' => [
|
1651
|
-
{
|
1652
|
-
'value' => '50ca93d04ab0c2de4772',
|
1653
|
-
'display' => 'Ingrid Smith',
|
1654
|
-
'type' => 'User'
|
1655
|
-
},
|
1656
|
-
{
|
1657
|
-
'value' => 'a774d480e8112101375b',
|
1658
|
-
'display' => 'Taylor Smith',
|
1659
|
-
'type' => 'User'
|
1660
|
-
}
|
1661
|
-
]
|
1662
|
-
})
|
1663
|
-
end
|
1664
|
-
|
1665
|
-
it 'removes multiple identified users' do
|
1666
|
-
path = [ 'members' ]
|
1667
|
-
value = [
|
1668
|
-
{ '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' },
|
1669
|
-
{ '$ref' => nil, 'value' => '50ca93d04ab0c2de4772' }
|
1670
|
-
]
|
1671
|
-
scim_hash = {
|
1672
|
-
'displayname' => 'Mock group',
|
1673
|
-
'members' => [
|
1674
|
-
{
|
1675
|
-
'value' => '50ca93d04ab0c2de4772',
|
1676
|
-
'display' => 'Ingrid Smith',
|
1677
|
-
'type' => 'User'
|
1678
|
-
},
|
1679
|
-
{
|
1680
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1681
|
-
'display' => 'Fred Smith',
|
1682
|
-
'type' => 'User'
|
1683
|
-
},
|
1684
|
-
{
|
1685
|
-
'value' => 'a774d480e8112101375b',
|
1686
|
-
'display' => 'Taylor Smith',
|
1687
|
-
'type' => 'User'
|
1688
|
-
}
|
1689
|
-
]
|
1690
|
-
}.with_indifferent_case_insensitive_access()
|
1691
|
-
|
1692
|
-
@instance.send(
|
1693
|
-
:from_patch_backend!,
|
1694
|
-
nature: 'remove',
|
1695
|
-
path: path,
|
1696
|
-
value: value,
|
1697
|
-
altering_hash: scim_hash,
|
1698
|
-
with_attr_map: {
|
1699
|
-
members: [
|
1700
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1701
|
-
]
|
1702
|
-
}
|
1703
|
-
)
|
1704
|
-
|
1705
|
-
expect(scim_hash).to eql({
|
1706
|
-
'displayname' => 'Mock group',
|
1707
|
-
'members' => [
|
1708
|
-
{
|
1709
|
-
'value' => 'a774d480e8112101375b',
|
1710
|
-
'display' => 'Taylor Smith',
|
1711
|
-
'type' => 'User'
|
1712
|
-
}
|
1713
|
-
]
|
1714
|
-
})
|
1715
|
-
end
|
1716
|
-
|
1717
|
-
it 'removes all users individually without error' do
|
1718
|
-
path = [ 'members' ]
|
1719
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ]
|
1720
|
-
scim_hash = {
|
1721
|
-
'displayname' => 'Mock group',
|
1722
|
-
'members' => [
|
1723
|
-
{
|
1724
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1725
|
-
'display' => 'Fred Smith',
|
1726
|
-
'type' => 'User'
|
1727
|
-
}
|
1728
|
-
]
|
1729
|
-
}.with_indifferent_case_insensitive_access()
|
1730
|
-
|
1731
|
-
@instance.send(
|
1732
|
-
:from_patch_backend!,
|
1733
|
-
nature: 'remove',
|
1734
|
-
path: path,
|
1735
|
-
value: value,
|
1736
|
-
altering_hash: scim_hash,
|
1737
|
-
with_attr_map: {
|
1738
|
-
members: [
|
1739
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1740
|
-
]
|
1741
|
-
}
|
1742
|
-
)
|
1743
|
-
|
1744
|
-
expect(scim_hash).to eql({
|
1745
|
-
'displayname' => 'Mock group',
|
1746
|
-
'members' => []
|
1747
|
-
})
|
1748
|
-
end
|
1749
|
-
|
1750
|
-
it 'can match on multiple attributes' do
|
1751
|
-
path = [ 'members' ]
|
1752
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'User' } ]
|
1753
|
-
scim_hash = {
|
1754
|
-
'displayname' => 'Mock group',
|
1755
|
-
'members' => [
|
1756
|
-
{
|
1757
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1758
|
-
'display' => 'Fred Smith',
|
1759
|
-
'type' => 'User'
|
1760
|
-
}
|
1761
|
-
]
|
1762
|
-
}.with_indifferent_case_insensitive_access()
|
1763
|
-
|
1764
|
-
@instance.send(
|
1765
|
-
:from_patch_backend!,
|
1766
|
-
nature: 'remove',
|
1767
|
-
path: path,
|
1768
|
-
value: value,
|
1769
|
-
altering_hash: scim_hash,
|
1770
|
-
with_attr_map: {
|
1771
|
-
members: [
|
1772
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1773
|
-
]
|
1774
|
-
}
|
1775
|
-
)
|
1776
|
-
|
1777
|
-
expect(scim_hash).to eql({
|
1778
|
-
'displayname' => 'Mock group',
|
1779
|
-
'members' => []
|
1780
|
-
})
|
1781
|
-
end
|
1782
|
-
|
1783
|
-
it 'ignores unrecognised users' do
|
1784
|
-
path = [ 'members' ]
|
1785
|
-
value = [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ]
|
1786
|
-
scim_hash = {
|
1787
|
-
'displayname' => 'Mock group',
|
1788
|
-
'members' => [
|
1789
|
-
{
|
1790
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1791
|
-
'display' => 'Fred Smith',
|
1792
|
-
'type' => 'User'
|
1793
|
-
}
|
1794
|
-
]
|
1795
|
-
}.with_indifferent_case_insensitive_access()
|
1796
|
-
|
1797
|
-
@instance.send(
|
1798
|
-
:from_patch_backend!,
|
1799
|
-
nature: 'remove',
|
1800
|
-
path: path,
|
1801
|
-
value: value,
|
1802
|
-
altering_hash: scim_hash,
|
1803
|
-
with_attr_map: {
|
1804
|
-
members: [
|
1805
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1806
|
-
]
|
1807
|
-
}
|
1808
|
-
)
|
1809
|
-
|
1810
|
-
# The 'value' mismatched, so the user was not removed.
|
1811
|
-
#
|
1812
|
-
expect(scim_hash).to eql({
|
1813
|
-
'displayname' => 'Mock group',
|
1814
|
-
'members' => [
|
1815
|
-
{
|
1816
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1817
|
-
'display' => 'Fred Smith',
|
1818
|
-
'type' => 'User'
|
1819
|
-
}
|
1820
|
-
]
|
1821
|
-
})
|
1822
|
-
end
|
1823
|
-
|
1824
|
-
it 'ignores a mismatch on (for example) "type"' do
|
1825
|
-
path = [ 'members' ]
|
1826
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'Group' } ]
|
1827
|
-
scim_hash = {
|
1828
|
-
'displayname' => 'Mock group',
|
1829
|
-
'members' => [
|
1830
|
-
{
|
1831
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1832
|
-
'display' => 'Fred Smith',
|
1833
|
-
'type' => 'User'
|
1834
|
-
}
|
1835
|
-
]
|
1836
|
-
}.with_indifferent_case_insensitive_access()
|
1837
|
-
|
1838
|
-
@instance.send(
|
1839
|
-
:from_patch_backend!,
|
1840
|
-
nature: 'remove',
|
1841
|
-
path: path,
|
1842
|
-
value: value,
|
1843
|
-
altering_hash: scim_hash,
|
1844
|
-
with_attr_map: {
|
1845
|
-
members: [
|
1846
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1847
|
-
]
|
1848
|
-
}
|
1849
|
-
)
|
1850
|
-
|
1851
|
-
# Type 'Group' mismatches 'User', so the user was not
|
1852
|
-
# removed.
|
1853
|
-
#
|
1854
|
-
expect(scim_hash).to eql({
|
1855
|
-
'displayname' => 'Mock group',
|
1856
|
-
'members' => [
|
1857
|
-
{
|
1858
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1859
|
-
'display' => 'Fred Smith',
|
1860
|
-
'type' => 'User'
|
1861
|
-
}
|
1862
|
-
]
|
1863
|
-
})
|
1864
|
-
end
|
1865
|
-
|
1866
|
-
it 'matches keys case-insensitive (but preserves case in response)' do
|
1867
|
-
path = [ 'members' ]
|
1868
|
-
value = [ { '$ref' => nil, 'VALUe' => 'f648f8d5ea4e4cd38e9c' } ]
|
1869
|
-
scim_hash = {
|
1870
|
-
'displayname' => 'Mock group',
|
1871
|
-
'memBERS' => [
|
1872
|
-
{
|
1873
|
-
'vaLUe' => 'f648f8d5ea4e4cd38e9c',
|
1874
|
-
'display' => 'Fred Smith',
|
1875
|
-
'type' => 'User'
|
1876
|
-
}
|
1877
|
-
]
|
1878
|
-
}.with_indifferent_case_insensitive_access()
|
1879
|
-
|
1880
|
-
@instance.send(
|
1881
|
-
:from_patch_backend!,
|
1882
|
-
nature: 'remove',
|
1883
|
-
path: path,
|
1884
|
-
value: value,
|
1885
|
-
altering_hash: scim_hash,
|
1886
|
-
with_attr_map: {
|
1887
|
-
members: [
|
1888
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1889
|
-
]
|
1890
|
-
}
|
1891
|
-
)
|
1892
|
-
|
1893
|
-
expect(scim_hash).to eql({
|
1894
|
-
'displayname' => 'Mock group',
|
1895
|
-
'memBERS' => []
|
1896
|
-
})
|
1897
|
-
end
|
1898
|
-
|
1899
|
-
it 'matches values case-sensitive' do
|
1900
|
-
path = [ 'members' ]
|
1901
|
-
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'USER' } ]
|
1902
|
-
scim_hash = {
|
1903
|
-
'displayName' => 'Mock group',
|
1904
|
-
'members' => [
|
1905
|
-
{
|
1906
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1907
|
-
'display' => 'Fred Smith',
|
1908
|
-
'type' => 'User'
|
1909
|
-
}
|
1910
|
-
]
|
1911
|
-
}.with_indifferent_case_insensitive_access()
|
1912
|
-
|
1913
|
-
@instance.send(
|
1914
|
-
:from_patch_backend!,
|
1915
|
-
nature: 'remove',
|
1916
|
-
path: path,
|
1917
|
-
value: value,
|
1918
|
-
altering_hash: scim_hash,
|
1919
|
-
with_attr_map: {
|
1920
|
-
members: [
|
1921
|
-
{ list: :members, using: { value: :id, display: :full_name, type: 'User' } }
|
1922
|
-
]
|
1923
|
-
}
|
1924
|
-
)
|
1925
|
-
|
1926
|
-
# USER mismatches User, so the user was not removed.
|
1927
|
-
#
|
1928
|
-
expect(scim_hash).to eql({
|
1929
|
-
'displayName' => 'Mock group',
|
1930
|
-
'members' => [
|
1931
|
-
{
|
1932
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
1933
|
-
'display' => 'Fred Smith',
|
1934
|
-
'type' => 'User'
|
1935
|
-
}
|
1936
|
-
]
|
1937
|
-
})
|
1938
|
-
end
|
1939
|
-
end # "context 'removing a user from a group' do"
|
1940
|
-
|
1941
|
-
context 'generic use' do
|
1942
|
-
it 'clears static map matched items to "nil" in order to remove' do
|
1943
|
-
path = [ 'emails' ]
|
1944
|
-
value = [ { 'type' => 'work' } ]
|
1945
|
-
scim_hash = {
|
1946
|
-
'emails' => [
|
1947
|
-
{
|
1948
|
-
'type' => 'home',
|
1949
|
-
'value' => 'home@test.com'
|
1950
|
-
},
|
1951
|
-
{
|
1952
|
-
'type' => 'work',
|
1953
|
-
'value' => 'work@test.com'
|
1954
|
-
}
|
1955
|
-
]
|
1956
|
-
}.with_indifferent_case_insensitive_access()
|
1957
|
-
|
1958
|
-
@instance.send(
|
1959
|
-
:from_patch_backend!,
|
1960
|
-
nature: 'remove',
|
1961
|
-
path: path,
|
1962
|
-
value: value,
|
1963
|
-
altering_hash: scim_hash,
|
1964
|
-
with_attr_map: {
|
1965
|
-
emails: [
|
1966
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
1967
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
1968
|
-
]
|
1969
|
-
}
|
1970
|
-
)
|
1971
|
-
|
1972
|
-
expect(scim_hash).to eql({
|
1973
|
-
'emails' => [
|
1974
|
-
{
|
1975
|
-
'type' => 'home',
|
1976
|
-
'value' => 'home@test.com'
|
1977
|
-
},
|
1978
|
-
{
|
1979
|
-
'type' => 'work',
|
1980
|
-
'value' => nil
|
1981
|
-
}
|
1982
|
-
]
|
1983
|
-
})
|
1984
|
-
end
|
1985
|
-
|
1986
|
-
it 'ignores unmatched items' do
|
1987
|
-
path = [ 'emails' ]
|
1988
|
-
value = [ { 'type' => 'missing' } ]
|
1989
|
-
scim_hash = {
|
1990
|
-
'emails' => [
|
1991
|
-
{
|
1992
|
-
'type' => 'home',
|
1993
|
-
'value' => 'home@test.com'
|
1994
|
-
},
|
1995
|
-
{
|
1996
|
-
'type' => 'work',
|
1997
|
-
'value' => 'work@test.com'
|
1998
|
-
}
|
1999
|
-
]
|
2000
|
-
}.with_indifferent_case_insensitive_access()
|
2001
|
-
|
2002
|
-
@instance.send(
|
2003
|
-
:from_patch_backend!,
|
2004
|
-
nature: 'remove',
|
2005
|
-
path: path,
|
2006
|
-
value: value,
|
2007
|
-
altering_hash: scim_hash,
|
2008
|
-
with_attr_map: {
|
2009
|
-
emails: [
|
2010
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2011
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2012
|
-
]
|
2013
|
-
}
|
2014
|
-
)
|
2015
|
-
|
2016
|
-
expect(scim_hash).to eql({
|
2017
|
-
'emails' => [
|
2018
|
-
{
|
2019
|
-
'type' => 'home',
|
2020
|
-
'value' => 'home@test.com'
|
2021
|
-
},
|
2022
|
-
{
|
2023
|
-
'type' => 'work',
|
2024
|
-
'value' => 'work@test.com'
|
2025
|
-
}
|
2026
|
-
]
|
2027
|
-
})
|
2028
|
-
end
|
2029
|
-
|
2030
|
-
it 'compares string forms' do
|
2031
|
-
path = [ 'test' ]
|
2032
|
-
value = [
|
2033
|
-
{ 'active' => true, 'value' => '12' },
|
2034
|
-
{ 'active' => 'false', 'value' => 42 }
|
2035
|
-
]
|
2036
|
-
scim_hash = {
|
2037
|
-
'test' => [
|
2038
|
-
{
|
2039
|
-
'active' => 'true',
|
2040
|
-
'value' => 12
|
2041
|
-
},
|
2042
|
-
{
|
2043
|
-
'active' => false,
|
2044
|
-
'value' => '42'
|
2045
|
-
},
|
2046
|
-
{
|
2047
|
-
'active' => 'hello',
|
2048
|
-
'value' => 'world'
|
2049
|
-
}
|
2050
|
-
]
|
2051
|
-
}.with_indifferent_case_insensitive_access()
|
2052
|
-
|
2053
|
-
@instance.send(
|
2054
|
-
:from_patch_backend!,
|
2055
|
-
nature: 'remove',
|
2056
|
-
path: path,
|
2057
|
-
value: value,
|
2058
|
-
altering_hash: scim_hash,
|
2059
|
-
with_attr_map: {
|
2060
|
-
test: [
|
2061
|
-
{
|
2062
|
-
list: :test,
|
2063
|
-
using: {
|
2064
|
-
active: :active,
|
2065
|
-
value: :value
|
2066
|
-
}
|
2067
|
-
}
|
2068
|
-
]
|
2069
|
-
}
|
2070
|
-
)
|
2071
|
-
|
2072
|
-
expect(scim_hash).to eql({
|
2073
|
-
'test' => [
|
2074
|
-
{
|
2075
|
-
'active' => 'hello',
|
2076
|
-
'value' => 'world'
|
2077
|
-
}
|
2078
|
-
]
|
2079
|
-
})
|
2080
|
-
end
|
2081
|
-
|
2082
|
-
it 'handles a singular to-remove value rather than an array' do
|
2083
|
-
path = [ 'emails' ]
|
2084
|
-
value = { 'type' => 'work' }
|
2085
|
-
scim_hash = {
|
2086
|
-
'emails' => [
|
2087
|
-
{
|
2088
|
-
'type' => 'home',
|
2089
|
-
'value' => 'home@test.com'
|
2090
|
-
},
|
2091
|
-
{
|
2092
|
-
'type' => 'work',
|
2093
|
-
'value' => 'work@test.com'
|
2094
|
-
}
|
2095
|
-
]
|
2096
|
-
}.with_indifferent_case_insensitive_access()
|
2097
|
-
|
2098
|
-
@instance.send(
|
2099
|
-
:from_patch_backend!,
|
2100
|
-
nature: 'remove',
|
2101
|
-
path: path,
|
2102
|
-
value: value,
|
2103
|
-
altering_hash: scim_hash,
|
2104
|
-
with_attr_map: {
|
2105
|
-
emails: [
|
2106
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2107
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2108
|
-
]
|
2109
|
-
}
|
2110
|
-
)
|
2111
|
-
|
2112
|
-
expect(scim_hash).to eql({
|
2113
|
-
'emails' => [
|
2114
|
-
{
|
2115
|
-
'type' => 'home',
|
2116
|
-
'value' => 'home@test.com'
|
2117
|
-
},
|
2118
|
-
{
|
2119
|
-
'type' => 'work',
|
2120
|
-
'value' => nil
|
2121
|
-
}
|
2122
|
-
]
|
2123
|
-
})
|
2124
|
-
end
|
2125
|
-
|
2126
|
-
it 'handles simple values rather than object (Hash) values' do
|
2127
|
-
path = [ 'test' ]
|
2128
|
-
value = 42
|
2129
|
-
scim_hash = {
|
2130
|
-
'test' => [
|
2131
|
-
'21',
|
2132
|
-
'42',
|
2133
|
-
'15'
|
2134
|
-
]
|
2135
|
-
}.with_indifferent_case_insensitive_access()
|
2136
|
-
|
2137
|
-
@instance.send(
|
2138
|
-
:from_patch_backend!,
|
2139
|
-
nature: 'remove',
|
2140
|
-
path: path,
|
2141
|
-
value: value,
|
2142
|
-
altering_hash: scim_hash,
|
2143
|
-
with_attr_map: {
|
2144
|
-
test: []
|
2145
|
-
}
|
2146
|
-
)
|
2147
|
-
|
2148
|
-
expect(scim_hash).to eql({
|
2149
|
-
'test' => [
|
2150
|
-
'21',
|
2151
|
-
'15'
|
2152
|
-
]
|
2153
|
-
})
|
2154
|
-
end
|
2155
|
-
end
|
2156
|
-
end # "context 'Microsoft-style payload' do"
|
2157
|
-
|
2158
|
-
# https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
|
2159
|
-
#
|
2160
|
-
context 'Salesforce-style payload' do
|
2161
|
-
it 'removes identified user' do
|
2162
|
-
path = [ 'members' ]
|
2163
|
-
value = { 'members' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
|
2164
|
-
scim_hash = {
|
2165
|
-
'displayname' => 'Mock group',
|
2166
|
-
'members' => [
|
2167
|
-
{
|
2168
|
-
'value' => '50ca93d04ab0c2de4772',
|
2169
|
-
'display' => 'Ingrid Smith',
|
2170
|
-
'type' => 'User'
|
2171
|
-
},
|
2172
|
-
{
|
2173
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2174
|
-
'display' => 'Fred Smith',
|
2175
|
-
'type' => 'User'
|
2176
|
-
}
|
2177
|
-
]
|
2178
|
-
}.with_indifferent_case_insensitive_access()
|
2179
|
-
|
2180
|
-
@instance.send(
|
2181
|
-
:from_patch_backend!,
|
2182
|
-
nature: 'remove',
|
2183
|
-
path: path,
|
2184
|
-
value: value,
|
2185
|
-
altering_hash: scim_hash,
|
2186
|
-
with_attr_map: {
|
2187
|
-
displayName: :name,
|
2188
|
-
members: [
|
2189
|
-
list: :members,
|
2190
|
-
using: {
|
2191
|
-
value: :id,
|
2192
|
-
display: :full_name,
|
2193
|
-
type: 'User'
|
2194
|
-
}
|
2195
|
-
]
|
2196
|
-
}
|
2197
|
-
)
|
2198
|
-
|
2199
|
-
expect(scim_hash).to eql({
|
2200
|
-
'displayname' => 'Mock group',
|
2201
|
-
'members' => [
|
2202
|
-
{
|
2203
|
-
'value' => '50ca93d04ab0c2de4772',
|
2204
|
-
'display' => 'Ingrid Smith',
|
2205
|
-
'type' => 'User'
|
2206
|
-
}
|
2207
|
-
]
|
2208
|
-
})
|
2209
|
-
end
|
2210
|
-
|
2211
|
-
it 'matches the "members" key case-insensitive' do
|
2212
|
-
path = [ 'members' ]
|
2213
|
-
value = { 'MEMBERS' => [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c' } ] }
|
2214
|
-
scim_hash = {
|
2215
|
-
'displayname' => 'Mock group',
|
2216
|
-
'members' => [
|
2217
|
-
{
|
2218
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2219
|
-
'display' => 'Fred Smith',
|
2220
|
-
'type' => 'User'
|
2221
|
-
},
|
2222
|
-
{
|
2223
|
-
'value' => 'a774d480e8112101375b',
|
2224
|
-
'display' => 'Taylor Smith',
|
2225
|
-
'type' => 'User'
|
2226
|
-
}
|
2227
|
-
]
|
2228
|
-
}.with_indifferent_case_insensitive_access()
|
2229
|
-
|
2230
|
-
@instance.send(
|
2231
|
-
:from_patch_backend!,
|
2232
|
-
nature: 'remove',
|
2233
|
-
path: path,
|
2234
|
-
value: value,
|
2235
|
-
altering_hash: scim_hash,
|
2236
|
-
with_attr_map: {
|
2237
|
-
displayName: :name,
|
2238
|
-
members: [
|
2239
|
-
list: :members,
|
2240
|
-
using: {
|
2241
|
-
value: :id,
|
2242
|
-
display: :full_name,
|
2243
|
-
type: 'User'
|
2244
|
-
}
|
2245
|
-
]
|
2246
|
-
}
|
2247
|
-
)
|
2248
|
-
|
2249
|
-
expect(scim_hash).to eql({
|
2250
|
-
'displayname' => 'Mock group',
|
2251
|
-
'members' => [
|
2252
|
-
{
|
2253
|
-
'value' => 'a774d480e8112101375b',
|
2254
|
-
'display' => 'Taylor Smith',
|
2255
|
-
'type' => 'User'
|
2256
|
-
}
|
2257
|
-
]
|
2258
|
-
})
|
2259
|
-
end
|
2260
|
-
|
2261
|
-
it 'ignores unrecognised users' do
|
2262
|
-
path = [ 'members' ]
|
2263
|
-
value = { 'members' => [ { '$ref' => nil, 'value' => '11b054a9c85216ed9356' } ] }
|
2264
|
-
scim_hash = {
|
2265
|
-
'displayname' => 'Mock group',
|
2266
|
-
'members' => [
|
2267
|
-
{
|
2268
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2269
|
-
'display' => 'Fred Smith',
|
2270
|
-
'type' => 'User'
|
2271
|
-
}
|
2272
|
-
]
|
2273
|
-
}.with_indifferent_case_insensitive_access()
|
2274
|
-
|
2275
|
-
@instance.send(
|
2276
|
-
:from_patch_backend!,
|
2277
|
-
nature: 'remove',
|
2278
|
-
path: path,
|
2279
|
-
value: value,
|
2280
|
-
altering_hash: scim_hash,
|
2281
|
-
with_attr_map: {
|
2282
|
-
displayName: :name,
|
2283
|
-
members: [
|
2284
|
-
list: :members,
|
2285
|
-
using: {
|
2286
|
-
value: :id,
|
2287
|
-
display: :full_name,
|
2288
|
-
type: 'User'
|
2289
|
-
}
|
2290
|
-
]
|
2291
|
-
}
|
2292
|
-
)
|
2293
|
-
|
2294
|
-
# The 'value' mismatched, so the user was not removed.
|
2295
|
-
#
|
2296
|
-
expect(scim_hash).to eql({
|
2297
|
-
'displayname' => 'Mock group',
|
2298
|
-
'members' => [
|
2299
|
-
{
|
2300
|
-
'value' => 'f648f8d5ea4e4cd38e9c',
|
2301
|
-
'display' => 'Fred Smith',
|
2302
|
-
'type' => 'User'
|
2303
|
-
}
|
2304
|
-
]
|
2305
|
-
})
|
2306
|
-
end
|
2307
|
-
end # "context 'Salesforce-style payload' do"
|
2308
|
-
end # "context 'special cases' do"
|
2309
1205
|
end # context 'when prior value already exists' do
|
2310
1206
|
|
2311
1207
|
context 'when value is not present' do
|
@@ -2318,8 +1214,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2318
1214
|
nature: 'remove',
|
2319
1215
|
path: path,
|
2320
1216
|
value: nil,
|
2321
|
-
altering_hash: scim_hash
|
2322
|
-
with_attr_map: { userName: :user_name }
|
1217
|
+
altering_hash: scim_hash
|
2323
1218
|
)
|
2324
1219
|
|
2325
1220
|
expect(scim_hash).to be_empty
|
@@ -2334,8 +1229,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2334
1229
|
nature: 'remove',
|
2335
1230
|
path: path,
|
2336
1231
|
value: nil,
|
2337
|
-
altering_hash: scim_hash
|
2338
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1232
|
+
altering_hash: scim_hash
|
2339
1233
|
)
|
2340
1234
|
|
2341
1235
|
expect(scim_hash['name']).to_not have_key('givenName')
|
@@ -2359,13 +1253,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2359
1253
|
nature: 'remove',
|
2360
1254
|
path: path,
|
2361
1255
|
value: nil,
|
2362
|
-
altering_hash: scim_hash
|
2363
|
-
with_attr_map: {
|
2364
|
-
emails: [
|
2365
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2366
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2367
|
-
]
|
2368
|
-
}
|
1256
|
+
altering_hash: scim_hash
|
2369
1257
|
)
|
2370
1258
|
|
2371
1259
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2387,13 +1275,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2387
1275
|
nature: 'remove',
|
2388
1276
|
path: path,
|
2389
1277
|
value: nil,
|
2390
|
-
altering_hash: scim_hash
|
2391
|
-
with_attr_map: {
|
2392
|
-
emails: [
|
2393
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2394
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2395
|
-
]
|
2396
|
-
}
|
1278
|
+
altering_hash: scim_hash
|
2397
1279
|
)
|
2398
1280
|
|
2399
1281
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2416,13 +1298,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2416
1298
|
nature: 'remove',
|
2417
1299
|
path: path,
|
2418
1300
|
value: nil,
|
2419
|
-
altering_hash: scim_hash
|
2420
|
-
with_attr_map: {
|
2421
|
-
emails: [
|
2422
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2423
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2424
|
-
]
|
2425
|
-
}
|
1301
|
+
altering_hash: scim_hash
|
2426
1302
|
)
|
2427
1303
|
|
2428
1304
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2440,13 +1316,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2440
1316
|
nature: 'remove',
|
2441
1317
|
path: path,
|
2442
1318
|
value: nil,
|
2443
|
-
altering_hash: scim_hash
|
2444
|
-
with_attr_map: {
|
2445
|
-
emails: [
|
2446
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2447
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2448
|
-
]
|
2449
|
-
}
|
1319
|
+
altering_hash: scim_hash
|
2450
1320
|
)
|
2451
1321
|
|
2452
1322
|
expect(scim_hash).to be_empty
|
@@ -2468,13 +1338,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2468
1338
|
nature: 'remove',
|
2469
1339
|
path: path,
|
2470
1340
|
value: nil,
|
2471
|
-
altering_hash: scim_hash
|
2472
|
-
with_attr_map: {
|
2473
|
-
emails: [
|
2474
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2475
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2476
|
-
]
|
2477
|
-
}
|
1341
|
+
altering_hash: scim_hash
|
2478
1342
|
)
|
2479
1343
|
|
2480
1344
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2491,13 +1355,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2491
1355
|
nature: 'remove',
|
2492
1356
|
path: path,
|
2493
1357
|
value: nil,
|
2494
|
-
altering_hash: scim_hash
|
2495
|
-
with_attr_map: {
|
2496
|
-
emails: [
|
2497
|
-
{ match: 'type', with: 'home', using: { value: :home_email } },
|
2498
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2499
|
-
]
|
2500
|
-
}
|
1358
|
+
altering_hash: scim_hash
|
2501
1359
|
)
|
2502
1360
|
|
2503
1361
|
expect(scim_hash).to_not have_key('emails')
|
@@ -2523,8 +1381,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2523
1381
|
nature: 'replace',
|
2524
1382
|
path: path,
|
2525
1383
|
value: 'foo',
|
2526
|
-
altering_hash: scim_hash
|
2527
|
-
with_attr_map: { userName: :user_name }
|
1384
|
+
altering_hash: scim_hash
|
2528
1385
|
)
|
2529
1386
|
|
2530
1387
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -2539,8 +1396,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2539
1396
|
nature: 'replace',
|
2540
1397
|
path: path,
|
2541
1398
|
value: 'Baz',
|
2542
|
-
altering_hash: scim_hash
|
2543
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1399
|
+
altering_hash: scim_hash
|
2544
1400
|
)
|
2545
1401
|
|
2546
1402
|
expect(scim_hash['name']['givenName' ]).to eql('Baz')
|
@@ -2568,13 +1424,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2568
1424
|
nature: 'replace',
|
2569
1425
|
path: path,
|
2570
1426
|
value: 'added_over_original@test.com',
|
2571
|
-
altering_hash: scim_hash
|
2572
|
-
with_attr_map: {
|
2573
|
-
emails: [
|
2574
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2575
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2576
|
-
]
|
2577
|
-
}
|
1427
|
+
altering_hash: scim_hash
|
2578
1428
|
)
|
2579
1429
|
|
2580
1430
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2600,13 +1450,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2600
1450
|
nature: 'replace',
|
2601
1451
|
path: path,
|
2602
1452
|
value: 'added_over_original@test.com',
|
2603
|
-
altering_hash: scim_hash
|
2604
|
-
with_attr_map: {
|
2605
|
-
emails: [
|
2606
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2607
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2608
|
-
]
|
2609
|
-
}
|
1453
|
+
altering_hash: scim_hash
|
2610
1454
|
)
|
2611
1455
|
|
2612
1456
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2633,13 +1477,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2633
1477
|
nature: 'replace',
|
2634
1478
|
path: path,
|
2635
1479
|
value: 'added_over_original@test.com',
|
2636
|
-
altering_hash: scim_hash
|
2637
|
-
with_attr_map: {
|
2638
|
-
emails: [
|
2639
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2640
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2641
|
-
]
|
2642
|
-
}
|
1480
|
+
altering_hash: scim_hash
|
2643
1481
|
)
|
2644
1482
|
|
2645
1483
|
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
|
@@ -2668,13 +1506,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2668
1506
|
nature: 'replace',
|
2669
1507
|
path: path,
|
2670
1508
|
value: {'type' => 'home', 'primary' => true, 'value' => 'home@test.com'},
|
2671
|
-
altering_hash: scim_hash
|
2672
|
-
with_attr_map: {
|
2673
|
-
emails: [
|
2674
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2675
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2676
|
-
]
|
2677
|
-
}
|
1509
|
+
altering_hash: scim_hash
|
2678
1510
|
)
|
2679
1511
|
|
2680
1512
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -2708,13 +1540,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2708
1540
|
nature: 'replace',
|
2709
1541
|
path: path,
|
2710
1542
|
value: {'type' => 'workinate', 'value' => 'replaced@test.com'},
|
2711
|
-
altering_hash: scim_hash
|
2712
|
-
with_attr_map: {
|
2713
|
-
emails: [
|
2714
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2715
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2716
|
-
]
|
2717
|
-
}
|
1543
|
+
altering_hash: scim_hash
|
2718
1544
|
)
|
2719
1545
|
|
2720
1546
|
expect(scim_hash['emails'].size).to eql(3)
|
@@ -2743,13 +1569,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2743
1569
|
nature: 'replace',
|
2744
1570
|
path: path,
|
2745
1571
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
2746
|
-
altering_hash: scim_hash
|
2747
|
-
with_attr_map: {
|
2748
|
-
emails: [
|
2749
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2750
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2751
|
-
]
|
2752
|
-
}
|
1572
|
+
altering_hash: scim_hash
|
2753
1573
|
)
|
2754
1574
|
|
2755
1575
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2768,8 +1588,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2768
1588
|
nature: 'replace',
|
2769
1589
|
path: path,
|
2770
1590
|
value: 'foo',
|
2771
|
-
altering_hash: scim_hash
|
2772
|
-
with_attr_map: { userName: :user_name }
|
1591
|
+
altering_hash: scim_hash
|
2773
1592
|
)
|
2774
1593
|
|
2775
1594
|
expect(scim_hash['userName']).to eql('foo')
|
@@ -2784,8 +1603,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2784
1603
|
nature: 'replace',
|
2785
1604
|
path: path,
|
2786
1605
|
value: 'Baz',
|
2787
|
-
altering_hash: scim_hash
|
2788
|
-
with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
|
1606
|
+
altering_hash: scim_hash
|
2789
1607
|
)
|
2790
1608
|
|
2791
1609
|
expect(scim_hash['name']['givenName']).to eql('Baz')
|
@@ -2811,13 +1629,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2811
1629
|
nature: 'replace',
|
2812
1630
|
path: path,
|
2813
1631
|
value: 'added@test.com',
|
2814
|
-
altering_hash: scim_hash
|
2815
|
-
with_attr_map: {
|
2816
|
-
emails: [
|
2817
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2818
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2819
|
-
]
|
2820
|
-
}
|
1632
|
+
altering_hash: scim_hash
|
2821
1633
|
)
|
2822
1634
|
|
2823
1635
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2842,13 +1654,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2842
1654
|
nature: 'replace',
|
2843
1655
|
path: path,
|
2844
1656
|
value: 'added@test.com',
|
2845
|
-
altering_hash: scim_hash
|
2846
|
-
with_attr_map: {
|
2847
|
-
emails: [
|
2848
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2849
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2850
|
-
]
|
2851
|
-
}
|
1657
|
+
altering_hash: scim_hash
|
2852
1658
|
)
|
2853
1659
|
|
2854
1660
|
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
|
@@ -2873,13 +1679,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2873
1679
|
nature: 'replace',
|
2874
1680
|
path: path,
|
2875
1681
|
value: 'added@test.com',
|
2876
|
-
altering_hash: scim_hash
|
2877
|
-
with_attr_map: {
|
2878
|
-
emails: [
|
2879
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2880
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2881
|
-
]
|
2882
|
-
}
|
1682
|
+
altering_hash: scim_hash
|
2883
1683
|
)
|
2884
1684
|
|
2885
1685
|
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
|
@@ -2897,13 +1697,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2897
1697
|
nature: 'replace',
|
2898
1698
|
path: path,
|
2899
1699
|
value: {'type' => 'work', 'value' => 'work@test.com'},
|
2900
|
-
altering_hash: scim_hash
|
2901
|
-
with_attr_map: {
|
2902
|
-
emails: [
|
2903
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2904
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2905
|
-
]
|
2906
|
-
}
|
1700
|
+
altering_hash: scim_hash
|
2907
1701
|
)
|
2908
1702
|
|
2909
1703
|
expect(scim_hash['emails'].size).to eql(1)
|
@@ -2927,13 +1721,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2927
1721
|
nature: 'replace',
|
2928
1722
|
path: path,
|
2929
1723
|
value: {'type' => 'work', 'value' => 'work@test.com'},
|
2930
|
-
altering_hash: scim_hash
|
2931
|
-
with_attr_map: {
|
2932
|
-
emails: [
|
2933
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2934
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2935
|
-
]
|
2936
|
-
}
|
1724
|
+
altering_hash: scim_hash
|
2937
1725
|
)
|
2938
1726
|
|
2939
1727
|
expect(scim_hash['emails'].size).to eql(2)
|
@@ -2952,41 +1740,13 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
2952
1740
|
nature: 'replace',
|
2953
1741
|
path: path,
|
2954
1742
|
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
|
2955
|
-
altering_hash: scim_hash
|
2956
|
-
with_attr_map: {
|
2957
|
-
emails: [
|
2958
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
2959
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
2960
|
-
]
|
2961
|
-
}
|
1743
|
+
altering_hash: scim_hash
|
2962
1744
|
)
|
2963
1745
|
|
2964
1746
|
expect(scim_hash['emails'].size).to eql(1)
|
2965
1747
|
expect(scim_hash['emails'][0]['type' ]).to eql('work')
|
2966
1748
|
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
|
2967
1749
|
end
|
2968
|
-
|
2969
|
-
context 'when prior value already exists, and no path' do
|
2970
|
-
it 'simple value: overwrites' do
|
2971
|
-
path = [ 'root' ]
|
2972
|
-
scim_hash = { 'root' => { 'userName' => 'bar', 'active' => true } }.with_indifferent_case_insensitive_access()
|
2973
|
-
|
2974
|
-
@instance.send(
|
2975
|
-
:from_patch_backend!,
|
2976
|
-
nature: 'replace',
|
2977
|
-
path: path,
|
2978
|
-
value: { 'active' => false }.with_indifferent_case_insensitive_access(),
|
2979
|
-
altering_hash: scim_hash,
|
2980
|
-
with_attr_map: {
|
2981
|
-
userName: :user_name,
|
2982
|
-
active: :active
|
2983
|
-
}
|
2984
|
-
)
|
2985
|
-
|
2986
|
-
expect(scim_hash['root']['userName']).to eql('bar')
|
2987
|
-
expect(scim_hash['root']['active']).to eql(false)
|
2988
|
-
end
|
2989
|
-
end
|
2990
1750
|
end # context 'when value is not present' do
|
2991
1751
|
end # "context 'replace' do"
|
2992
1752
|
|
@@ -3101,8 +1861,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3101
1861
|
nature: 'add',
|
3102
1862
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3103
1863
|
value: [{ 'deeper' => 'addition' }],
|
3104
|
-
altering_hash: scim_hash
|
3105
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1864
|
+
altering_hash: scim_hash
|
3106
1865
|
)
|
3107
1866
|
|
3108
1867
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
@@ -3125,8 +1884,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3125
1884
|
nature: 'replace',
|
3126
1885
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3127
1886
|
value: [{ 'deeper' => 'addition' }],
|
3128
|
-
altering_hash: scim_hash
|
3129
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1887
|
+
altering_hash: scim_hash
|
3130
1888
|
)
|
3131
1889
|
|
3132
1890
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged?
|
@@ -3143,25 +1901,24 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3143
1901
|
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info', 0, 'deep')).to eql('nature2deep3') # Unchanged
|
3144
1902
|
end
|
3145
1903
|
|
3146
|
-
it 'removes
|
1904
|
+
it 'removes across multiple deep matching points' do
|
3147
1905
|
scim_hash = @original_hash.deep_dup().with_indifferent_case_insensitive_access()
|
3148
1906
|
contrived_instance = @contrived_class.new
|
3149
1907
|
contrived_instance.send(
|
3150
1908
|
:from_patch_backend!,
|
3151
1909
|
nature: 'remove',
|
3152
1910
|
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
|
3153
|
-
value:
|
3154
|
-
altering_hash: scim_hash
|
3155
|
-
with_attr_map: @contrived_class.scim_attributes_map()
|
1911
|
+
value: [{ 'deeper' => 'addition' }],
|
1912
|
+
altering_hash: scim_hash
|
3156
1913
|
)
|
3157
1914
|
|
3158
1915
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
3159
|
-
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to
|
1916
|
+
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
|
3160
1917
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
|
3161
|
-
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to
|
1918
|
+
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
|
3162
1919
|
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
|
3163
1920
|
|
3164
|
-
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to
|
1921
|
+
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to be_nil
|
3165
1922
|
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'nature')).to be_present
|
3166
1923
|
|
3167
1924
|
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
|
@@ -3195,13 +1952,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3195
1952
|
nature: 'replace',
|
3196
1953
|
path: path,
|
3197
1954
|
value: 'ignored',
|
3198
|
-
altering_hash: scim_hash
|
3199
|
-
with_attr_map: {
|
3200
|
-
emails: [
|
3201
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
3202
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
3203
|
-
]
|
3204
|
-
}
|
1955
|
+
altering_hash: scim_hash
|
3205
1956
|
)
|
3206
1957
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3207
1958
|
end
|
@@ -3218,8 +1969,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3218
1969
|
nature: 'replace',
|
3219
1970
|
path: path,
|
3220
1971
|
value: 'ignored',
|
3221
|
-
altering_hash: scim_hash
|
3222
|
-
with_attr_map: { userName: :user_name }
|
1972
|
+
altering_hash: scim_hash
|
3223
1973
|
)
|
3224
1974
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3225
1975
|
end
|
@@ -3239,13 +1989,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3239
1989
|
nature: 'replace',
|
3240
1990
|
path: path,
|
3241
1991
|
value: 'ignored',
|
3242
|
-
altering_hash: scim_hash
|
3243
|
-
with_attr_map: {
|
3244
|
-
emails: [
|
3245
|
-
{ match: 'type', with: 'home', using: { value: :home_email, primary: true } },
|
3246
|
-
{ match: 'type', with: 'work', using: { value: :work_email } },
|
3247
|
-
]
|
3248
|
-
}
|
1992
|
+
altering_hash: scim_hash
|
3249
1993
|
)
|
3250
1994
|
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
|
3251
1995
|
end
|
@@ -3259,14 +2003,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3259
2003
|
#
|
3260
2004
|
context 'public interface' do
|
3261
2005
|
shared_examples 'a patcher' do | force_upper_case: |
|
3262
|
-
it 'gives the user a comprehensible error when operations are missing' do
|
3263
|
-
patch = { 'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'] }
|
3264
|
-
|
3265
|
-
expect do
|
3266
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3267
|
-
end.to raise_error Scimitar::InvalidSyntaxError, "Missing PATCH \"operations\""
|
3268
|
-
end
|
3269
|
-
|
3270
2006
|
it 'which updates simple values' do
|
3271
2007
|
@instance.update!(username: 'foo')
|
3272
2008
|
|
@@ -3288,28 +2024,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3288
2024
|
expect(@instance.username).to eql('1234')
|
3289
2025
|
end
|
3290
2026
|
|
3291
|
-
it 'which updates nested values using root syntax' do
|
3292
|
-
@instance.update!(first_name: 'Foo', last_name: 'Bar')
|
3293
|
-
|
3294
|
-
path = 'name.givenName'
|
3295
|
-
path = path.upcase if force_upper_case
|
3296
|
-
|
3297
|
-
patch = {
|
3298
|
-
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
|
3299
|
-
'Operations' => [
|
3300
|
-
{
|
3301
|
-
'op' => 'replace',
|
3302
|
-
'value' => {
|
3303
|
-
path => 'Baz'
|
3304
|
-
}
|
3305
|
-
}
|
3306
|
-
]
|
3307
|
-
}
|
3308
|
-
|
3309
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3310
|
-
expect(@instance.first_name).to eql('Baz')
|
3311
|
-
end
|
3312
|
-
|
3313
2027
|
it 'which updates nested values' do
|
3314
2028
|
@instance.update!(first_name: 'Foo', last_name: 'Bar')
|
3315
2029
|
|
@@ -3331,38 +2045,6 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
3331
2045
|
expect(@instance.first_name).to eql('Baz')
|
3332
2046
|
end
|
3333
2047
|
|
3334
|
-
# Note odd ":" separating schema ID from first attribute, although
|
3335
|
-
# the nature of JSON rendering / other payloads might lead you to
|
3336
|
-
# expect a "." as with any other path component.
|
3337
|
-
#
|
3338
|
-
# Note the ":" separating the schema ID (URN) from the attribute.
|
3339
|
-
# The nature of JSON rendering / other payloads might lead you to
|
3340
|
-
# expect a "." as with any complex types, but that's not the case;
|
3341
|
-
# see https://tools.ietf.org/html/rfc7644#section-3.10, or
|
3342
|
-
# https://tools.ietf.org/html/rfc7644#section-3.5.2 of which in
|
3343
|
-
# particular, https://tools.ietf.org/html/rfc7644#page-35.
|
3344
|
-
#
|
3345
|
-
it 'which updates attributes defined by extension schema' do
|
3346
|
-
@instance.update!(department: 'SOMEDPT')
|
3347
|
-
|
3348
|
-
path = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'
|
3349
|
-
path = path.upcase if force_upper_case
|
3350
|
-
|
3351
|
-
patch = {
|
3352
|
-
'schemas' => ['urn:ietf:params:scim:api:messages:2.0:PatchOp'],
|
3353
|
-
'Operations' => [
|
3354
|
-
{
|
3355
|
-
'op' => 'replace',
|
3356
|
-
'path' => path,
|
3357
|
-
'value' => 'OTHERDPT'
|
3358
|
-
}
|
3359
|
-
]
|
3360
|
-
}
|
3361
|
-
|
3362
|
-
@instance.from_scim_patch!(patch_hash: patch)
|
3363
|
-
expect(@instance.department).to eql('OTHERDPT')
|
3364
|
-
end
|
3365
|
-
|
3366
2048
|
it 'which updates with filter match' do
|
3367
2049
|
@instance.update!(work_email_address: 'work@test.com', home_email_address: 'home@test.com')
|
3368
2050
|
|