scimitar 1.8.1 → 1.8.2

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.
@@ -81,6 +81,102 @@ 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
+
84
180
  # ===========================================================================
85
181
  # Errant class definitions
86
182
  # ===========================================================================
@@ -362,6 +458,30 @@ RSpec.describe Scimitar::Resources::Mixin do
362
458
  end # "context 'using dynamic lists' do"
363
459
  end # "context 'with arrays' do"
364
460
 
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
+
365
485
  context 'with bad definitions' do
366
486
  it 'complains about non-Hash entries in mapping Arrays' do
367
487
  expect(StaticMapTest).to receive(:scim_attributes_map).and_return({
@@ -702,7 +822,8 @@ RSpec.describe Scimitar::Resources::Mixin do
702
822
  nature: 'add',
703
823
  path: path,
704
824
  value: 'foo',
705
- altering_hash: scim_hash
825
+ altering_hash: scim_hash,
826
+ with_attr_map: { userName: :user_name }
706
827
  )
707
828
 
708
829
  expect(scim_hash['userName']).to eql('foo')
@@ -717,7 +838,8 @@ RSpec.describe Scimitar::Resources::Mixin do
717
838
  nature: 'add',
718
839
  path: path,
719
840
  value: 'Baz',
720
- altering_hash: scim_hash
841
+ altering_hash: scim_hash,
842
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
721
843
  )
722
844
 
723
845
  expect(scim_hash['name']['givenName' ]).to eql('Baz')
@@ -733,7 +855,8 @@ RSpec.describe Scimitar::Resources::Mixin do
733
855
  nature: 'add',
734
856
  path: path,
735
857
  value: 'OTHERORG',
736
- altering_hash: scim_hash
858
+ altering_hash: scim_hash,
859
+ with_attr_map: { organization: :org_name }
737
860
  )
738
861
 
739
862
  expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('OTHERORG')
@@ -763,7 +886,13 @@ RSpec.describe Scimitar::Resources::Mixin do
763
886
  nature: 'add',
764
887
  path: path,
765
888
  value: 'added_over_original@test.com',
766
- altering_hash: scim_hash
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
+ }
767
896
  )
768
897
 
769
898
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -789,7 +918,13 @@ RSpec.describe Scimitar::Resources::Mixin do
789
918
  nature: 'add',
790
919
  path: path,
791
920
  value: 'added_over_original@test.com',
792
- altering_hash: scim_hash
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
+ }
793
928
  )
794
929
 
795
930
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -816,7 +951,13 @@ RSpec.describe Scimitar::Resources::Mixin do
816
951
  nature: 'add',
817
952
  path: path,
818
953
  value: 'added_over_original@test.com',
819
- altering_hash: scim_hash
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
+ }
820
961
  )
821
962
 
822
963
  expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
@@ -840,7 +981,13 @@ RSpec.describe Scimitar::Resources::Mixin do
840
981
  nature: 'add',
841
982
  path: path,
842
983
  value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
843
- altering_hash: scim_hash
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
+ }
844
991
  )
845
992
 
846
993
  expect(scim_hash['emails'].size).to eql(2)
@@ -888,7 +1035,12 @@ RSpec.describe Scimitar::Resources::Mixin do
888
1035
  nature: 'add',
889
1036
  path: ['root'],
890
1037
  value: {'members' => [{'value' => '3'}]},
891
- altering_hash: scim_hash
1038
+ altering_hash: scim_hash,
1039
+ with_attr_map: {
1040
+ members: [
1041
+ { list: :members, using: { value: :id } }
1042
+ ]
1043
+ }
892
1044
  )
893
1045
 
894
1046
  expect(scim_hash['root']['members']).to match_array([{'value' => '1'}, {'value' => '2'}, {'value' => '3'}])
@@ -906,7 +1058,8 @@ RSpec.describe Scimitar::Resources::Mixin do
906
1058
  nature: 'add',
907
1059
  path: path,
908
1060
  value: 'foo',
909
- altering_hash: scim_hash
1061
+ altering_hash: scim_hash,
1062
+ with_attr_map: { userName: :user_name }
910
1063
  )
911
1064
 
912
1065
  expect(scim_hash['userName']).to eql('foo')
@@ -921,7 +1074,8 @@ RSpec.describe Scimitar::Resources::Mixin do
921
1074
  nature: 'add',
922
1075
  path: path,
923
1076
  value: 'Baz',
924
- altering_hash: scim_hash
1077
+ altering_hash: scim_hash,
1078
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
925
1079
  )
926
1080
 
927
1081
  expect(scim_hash['name']['givenName']).to eql('Baz')
@@ -936,7 +1090,8 @@ RSpec.describe Scimitar::Resources::Mixin do
936
1090
  nature: 'add',
937
1091
  path: path,
938
1092
  value: 'SOMEORG',
939
- altering_hash: scim_hash
1093
+ altering_hash: scim_hash,
1094
+ with_attr_map: { organization: :org_name }
940
1095
  )
941
1096
 
942
1097
  expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('SOMEORG')
@@ -962,7 +1117,13 @@ RSpec.describe Scimitar::Resources::Mixin do
962
1117
  nature: 'add',
963
1118
  path: path,
964
1119
  value: 'added@test.com',
965
- altering_hash: scim_hash
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
+ }
966
1127
  )
967
1128
 
968
1129
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -987,7 +1148,13 @@ RSpec.describe Scimitar::Resources::Mixin do
987
1148
  nature: 'add',
988
1149
  path: path,
989
1150
  value: 'added@test.com',
990
- altering_hash: scim_hash
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
+ }
991
1158
  )
992
1159
 
993
1160
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -1003,7 +1170,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1003
1170
  nature: 'add',
1004
1171
  path: path,
1005
1172
  value: 'added@test.com',
1006
- altering_hash: scim_hash
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
+ }
1007
1180
  )
1008
1181
 
1009
1182
  expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
@@ -1027,7 +1200,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1027
1200
  nature: 'add',
1028
1201
  path: path,
1029
1202
  value: 'added@test.com',
1030
- altering_hash: scim_hash
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
+ }
1031
1210
  )
1032
1211
 
1033
1212
  expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
@@ -1044,7 +1223,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1044
1223
  nature: 'add',
1045
1224
  path: path,
1046
1225
  value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
1047
- altering_hash: scim_hash
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
+ }
1048
1233
  )
1049
1234
 
1050
1235
  expect(scim_hash['emails'].size).to eql(1)
@@ -1060,7 +1245,7 @@ RSpec.describe Scimitar::Resources::Mixin do
1060
1245
  #
1061
1246
  context 'remove' do
1062
1247
  context 'when prior value already exists' do
1063
- it 'simple value: removes' do
1248
+ it 'simple value: clears to "nil" in order to remove' do
1064
1249
  path = [ 'userName' ]
1065
1250
  scim_hash = { 'userName' => 'bar' }.with_indifferent_case_insensitive_access()
1066
1251
 
@@ -1069,13 +1254,14 @@ RSpec.describe Scimitar::Resources::Mixin do
1069
1254
  nature: 'remove',
1070
1255
  path: path,
1071
1256
  value: nil,
1072
- altering_hash: scim_hash
1257
+ altering_hash: scim_hash,
1258
+ with_attr_map: { userName: :user_name }
1073
1259
  )
1074
1260
 
1075
- expect(scim_hash).to be_empty
1261
+ expect(scim_hash).to eql({ 'userName' => nil })
1076
1262
  end
1077
1263
 
1078
- it 'nested simple value: removes' do
1264
+ it 'nested simple value: clears to "nil" in order to remove' do
1079
1265
  path = [ 'name', 'givenName' ]
1080
1266
  scim_hash = { 'name' => { 'givenName' => 'Foo', 'familyName' => 'Bar' } }.with_indifferent_case_insensitive_access()
1081
1267
 
@@ -1084,15 +1270,15 @@ RSpec.describe Scimitar::Resources::Mixin do
1084
1270
  nature: 'remove',
1085
1271
  path: path,
1086
1272
  value: nil,
1087
- altering_hash: scim_hash
1273
+ altering_hash: scim_hash,
1274
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
1088
1275
  )
1089
1276
 
1090
- expect(scim_hash['name']).to_not have_key('givenName')
1091
- expect(scim_hash['name']['familyName']).to eql('Bar')
1277
+ expect(scim_hash).to eql({ 'name' => { 'givenName' => nil, 'familyName' => 'Bar' } })
1092
1278
  end
1093
1279
 
1094
1280
  context 'with filter mid-path' do
1095
- it 'by string match: removes' do
1281
+ it 'by string match: clears to "nil" in order to remove' do
1096
1282
  path = [ 'emails[type eq "work"]', 'value' ]
1097
1283
  scim_hash = {
1098
1284
  'emails' => [
@@ -1112,14 +1298,30 @@ RSpec.describe Scimitar::Resources::Mixin do
1112
1298
  nature: 'remove',
1113
1299
  path: path,
1114
1300
  value: nil,
1115
- altering_hash: scim_hash
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
+ }
1116
1308
  )
1117
1309
 
1118
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
1119
- expect(scim_hash['emails'][1]).to_not have_key('value')
1310
+ expect(scim_hash).to eql({
1311
+ 'emails' => [
1312
+ {
1313
+ 'type' => 'home',
1314
+ 'value' => 'home@test.com'
1315
+ },
1316
+ {
1317
+ 'type' => 'work',
1318
+ 'value' => nil
1319
+ }
1320
+ ]
1321
+ })
1120
1322
  end
1121
1323
 
1122
- it 'by boolean match: removes' do
1324
+ it 'by boolean match: clears to "nil" in order to remove' do
1123
1325
  path = [ 'emails[primary eq true]', 'value' ]
1124
1326
  scim_hash = {
1125
1327
  'emails' => [
@@ -1138,14 +1340,29 @@ RSpec.describe Scimitar::Resources::Mixin do
1138
1340
  nature: 'remove',
1139
1341
  path: path,
1140
1342
  value: nil,
1141
- altering_hash: scim_hash
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
+ }
1142
1350
  )
1143
1351
 
1144
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
1145
- expect(scim_hash['emails'][1]).to_not have_key('value')
1352
+ expect(scim_hash).to eql({
1353
+ 'emails' => [
1354
+ {
1355
+ 'value' => 'home@test.com'
1356
+ },
1357
+ {
1358
+ 'value' => nil,
1359
+ 'primary' => true
1360
+ }
1361
+ ]
1362
+ })
1146
1363
  end
1147
1364
 
1148
- it 'multiple matches: removes all' do
1365
+ it 'multiple matches: clears all to "nil" in order to remove' do
1149
1366
  path = [ 'emails[type eq "work"]', 'value' ]
1150
1367
  scim_hash = {
1151
1368
  'emails' => [
@@ -1156,7 +1373,11 @@ RSpec.describe Scimitar::Resources::Mixin do
1156
1373
  {
1157
1374
  'type' => 'work',
1158
1375
  'value' => 'work_2@test.com'
1159
- }
1376
+ },
1377
+ {
1378
+ 'type' => 'home',
1379
+ 'value' => 'home@test.com'
1380
+ },
1160
1381
  ]
1161
1382
  }.with_indifferent_case_insensitive_access()
1162
1383
 
@@ -1165,16 +1386,36 @@ RSpec.describe Scimitar::Resources::Mixin do
1165
1386
  nature: 'remove',
1166
1387
  path: path,
1167
1388
  value: nil,
1168
- altering_hash: scim_hash
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
+ }
1169
1396
  )
1170
1397
 
1171
- expect(scim_hash['emails'][0]).to_not have_key('value')
1172
- expect(scim_hash['emails'][1]).to_not have_key('value')
1398
+ expect(scim_hash).to eql({
1399
+ 'emails' => [
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
+ })
1173
1414
  end
1174
1415
  end # "context 'with filter mid-path' do"
1175
1416
 
1176
1417
  context 'with filter at end of path' do
1177
- it 'by string match: removes entire matching array entry' do
1418
+ it 'by string match: clears to "nil" in order to remove' do
1178
1419
  path = [ 'emails[type eq "work"]' ]
1179
1420
  scim_hash = {
1180
1421
  'emails' => [
@@ -1194,23 +1435,39 @@ RSpec.describe Scimitar::Resources::Mixin do
1194
1435
  nature: 'remove',
1195
1436
  path: path,
1196
1437
  value: nil,
1197
- altering_hash: scim_hash
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
+ }
1198
1445
  )
1199
1446
 
1200
- expect(scim_hash['emails'].size).to eql(1)
1201
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
1447
+ expect(scim_hash).to eql({
1448
+ 'emails' => [
1449
+ {
1450
+ 'type' => 'home',
1451
+ 'value' => 'home@test.com'
1452
+ },
1453
+ {
1454
+ 'type' => 'work',
1455
+ 'value' => nil
1456
+ }
1457
+ ]
1458
+ })
1202
1459
  end
1203
1460
 
1204
- it 'by boolean match: removes entire matching array entry' do
1461
+ it 'by boolean match: clears to "nil" in order to remove' do
1205
1462
  path = [ 'emails[primary eq true]' ]
1206
1463
  scim_hash = {
1207
1464
  'emails' => [
1208
1465
  {
1209
- 'value' => 'home@test.com'
1466
+ 'value' => 'home@test.com',
1467
+ 'primary' => true
1210
1468
  },
1211
1469
  {
1212
- 'value' => 'work@test.com',
1213
- 'primary' => true
1470
+ 'value' => 'work@test.com'
1214
1471
  }
1215
1472
  ]
1216
1473
  }.with_indifferent_case_insensitive_access()
@@ -1220,14 +1477,29 @@ RSpec.describe Scimitar::Resources::Mixin do
1220
1477
  nature: 'remove',
1221
1478
  path: path,
1222
1479
  value: nil,
1223
- altering_hash: scim_hash
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
+ }
1224
1487
  )
1225
1488
 
1226
- expect(scim_hash['emails'].size).to eql(1)
1227
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
1489
+ expect(scim_hash).to eql({
1490
+ 'emails' => [
1491
+ {
1492
+ 'value' => nil,
1493
+ 'primary' => true
1494
+ },
1495
+ {
1496
+ 'value' => 'work@test.com'
1497
+ }
1498
+ ]
1499
+ })
1228
1500
  end
1229
1501
 
1230
- it 'multiple matches: removes all matching array entries' do
1502
+ it 'multiple matches: clears all to "nil" in order to remove' do
1231
1503
  path = [ 'emails[type eq "work"]' ]
1232
1504
  scim_hash = {
1233
1505
  'emails' => [
@@ -1251,21 +1523,45 @@ RSpec.describe Scimitar::Resources::Mixin do
1251
1523
  nature: 'remove',
1252
1524
  path: path,
1253
1525
  value: nil,
1254
- altering_hash: scim_hash
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
+ }
1255
1533
  )
1256
1534
 
1257
- expect(scim_hash['emails'].size).to eql(1)
1258
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
1535
+ expect(scim_hash).to eql({
1536
+ 'emails' => [
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
+ })
1259
1551
  end
1260
1552
  end # "context 'with filter at end of path' do"
1261
1553
 
1262
- it 'whole array: removes' do
1554
+ it 'whole array: clears mapped values to "nil" to remove them' do
1263
1555
  path = [ 'emails' ]
1264
1556
  scim_hash = {
1265
1557
  'emails' => [
1266
1558
  {
1267
1559
  'type' => 'home',
1268
1560
  'value' => 'home@test.com'
1561
+ },
1562
+ {
1563
+ 'type' => 'work',
1564
+ 'value' => 'work@test.com'
1269
1565
  }
1270
1566
  ]
1271
1567
  }.with_indifferent_case_insensitive_access()
@@ -1275,10 +1571,27 @@ RSpec.describe Scimitar::Resources::Mixin do
1275
1571
  nature: 'remove',
1276
1572
  path: path,
1277
1573
  value: nil,
1278
- altering_hash: scim_hash
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
+ }
1279
1581
  )
1280
1582
 
1281
- expect(scim_hash).to_not have_key('emails')
1583
+ expect(scim_hash).to eql({
1584
+ 'emails' => [
1585
+ {
1586
+ 'type' => 'home',
1587
+ 'value' => nil
1588
+ },
1589
+ {
1590
+ 'type' => 'work',
1591
+ 'value' => nil
1592
+ }
1593
+ ]
1594
+ })
1282
1595
  end
1283
1596
 
1284
1597
  # What we expect:
@@ -1324,7 +1637,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1324
1637
  nature: 'remove',
1325
1638
  path: path,
1326
1639
  value: value,
1327
- altering_hash: scim_hash
1640
+ altering_hash: scim_hash,
1641
+ with_attr_map: {
1642
+ members: [
1643
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1644
+ ]
1645
+ }
1328
1646
  )
1329
1647
 
1330
1648
  expect(scim_hash).to eql({
@@ -1376,7 +1694,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1376
1694
  nature: 'remove',
1377
1695
  path: path,
1378
1696
  value: value,
1379
- altering_hash: scim_hash
1697
+ altering_hash: scim_hash,
1698
+ with_attr_map: {
1699
+ members: [
1700
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1701
+ ]
1702
+ }
1380
1703
  )
1381
1704
 
1382
1705
  expect(scim_hash).to eql({
@@ -1410,7 +1733,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1410
1733
  nature: 'remove',
1411
1734
  path: path,
1412
1735
  value: value,
1413
- altering_hash: scim_hash
1736
+ altering_hash: scim_hash,
1737
+ with_attr_map: {
1738
+ members: [
1739
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1740
+ ]
1741
+ }
1414
1742
  )
1415
1743
 
1416
1744
  expect(scim_hash).to eql({
@@ -1438,7 +1766,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1438
1766
  nature: 'remove',
1439
1767
  path: path,
1440
1768
  value: value,
1441
- altering_hash: scim_hash
1769
+ altering_hash: scim_hash,
1770
+ with_attr_map: {
1771
+ members: [
1772
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1773
+ ]
1774
+ }
1442
1775
  )
1443
1776
 
1444
1777
  expect(scim_hash).to eql({
@@ -1466,7 +1799,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1466
1799
  nature: 'remove',
1467
1800
  path: path,
1468
1801
  value: value,
1469
- altering_hash: scim_hash
1802
+ altering_hash: scim_hash,
1803
+ with_attr_map: {
1804
+ members: [
1805
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1806
+ ]
1807
+ }
1470
1808
  )
1471
1809
 
1472
1810
  # The 'value' mismatched, so the user was not removed.
@@ -1502,7 +1840,12 @@ RSpec.describe Scimitar::Resources::Mixin do
1502
1840
  nature: 'remove',
1503
1841
  path: path,
1504
1842
  value: value,
1505
- altering_hash: scim_hash
1843
+ altering_hash: scim_hash,
1844
+ with_attr_map: {
1845
+ members: [
1846
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1847
+ ]
1848
+ }
1506
1849
  )
1507
1850
 
1508
1851
  # Type 'Group' mismatches 'User', so the user was not
@@ -1520,7 +1863,7 @@ RSpec.describe Scimitar::Resources::Mixin do
1520
1863
  })
1521
1864
  end
1522
1865
 
1523
- it 'matches keys case-insensitive' do
1866
+ it 'matches keys case-insensitive (but preserves case in response)' do
1524
1867
  path = [ 'members' ]
1525
1868
  value = [ { '$ref' => nil, 'VALUe' => 'f648f8d5ea4e4cd38e9c' } ]
1526
1869
  scim_hash = {
@@ -1539,12 +1882,17 @@ RSpec.describe Scimitar::Resources::Mixin do
1539
1882
  nature: 'remove',
1540
1883
  path: path,
1541
1884
  value: value,
1542
- altering_hash: scim_hash
1885
+ altering_hash: scim_hash,
1886
+ with_attr_map: {
1887
+ members: [
1888
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1889
+ ]
1890
+ }
1543
1891
  )
1544
1892
 
1545
1893
  expect(scim_hash).to eql({
1546
1894
  'displayname' => 'Mock group',
1547
- 'members' => []
1895
+ 'memBERS' => []
1548
1896
  })
1549
1897
  end
1550
1898
 
@@ -1552,7 +1900,7 @@ RSpec.describe Scimitar::Resources::Mixin do
1552
1900
  path = [ 'members' ]
1553
1901
  value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'USER' } ]
1554
1902
  scim_hash = {
1555
- 'displayname' => 'Mock group',
1903
+ 'displayName' => 'Mock group',
1556
1904
  'members' => [
1557
1905
  {
1558
1906
  'value' => 'f648f8d5ea4e4cd38e9c',
@@ -1567,13 +1915,18 @@ RSpec.describe Scimitar::Resources::Mixin do
1567
1915
  nature: 'remove',
1568
1916
  path: path,
1569
1917
  value: value,
1570
- altering_hash: scim_hash
1918
+ altering_hash: scim_hash,
1919
+ with_attr_map: {
1920
+ members: [
1921
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
1922
+ ]
1923
+ }
1571
1924
  )
1572
1925
 
1573
- # USER mismatchs User, so the user was not removed.
1926
+ # USER mismatches User, so the user was not removed.
1574
1927
  #
1575
1928
  expect(scim_hash).to eql({
1576
- 'displayname' => 'Mock group',
1929
+ 'displayName' => 'Mock group',
1577
1930
  'members' => [
1578
1931
  {
1579
1932
  'value' => 'f648f8d5ea4e4cd38e9c',
@@ -1586,7 +1939,7 @@ RSpec.describe Scimitar::Resources::Mixin do
1586
1939
  end # "context 'removing a user from a group' do"
1587
1940
 
1588
1941
  context 'generic use' do
1589
- it 'removes matched items' do
1942
+ it 'clears static map matched items to "nil" in order to remove' do
1590
1943
  path = [ 'emails' ]
1591
1944
  value = [ { 'type' => 'work' } ]
1592
1945
  scim_hash = {
@@ -1607,7 +1960,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1607
1960
  nature: 'remove',
1608
1961
  path: path,
1609
1962
  value: value,
1610
- altering_hash: scim_hash
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
+ }
1611
1970
  )
1612
1971
 
1613
1972
  expect(scim_hash).to eql({
@@ -1615,6 +1974,10 @@ RSpec.describe Scimitar::Resources::Mixin do
1615
1974
  {
1616
1975
  'type' => 'home',
1617
1976
  'value' => 'home@test.com'
1977
+ },
1978
+ {
1979
+ 'type' => 'work',
1980
+ 'value' => nil
1618
1981
  }
1619
1982
  ]
1620
1983
  })
@@ -1641,7 +2004,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1641
2004
  nature: 'remove',
1642
2005
  path: path,
1643
2006
  value: value,
1644
- altering_hash: scim_hash
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
+ }
1645
2014
  )
1646
2015
 
1647
2016
  expect(scim_hash).to eql({
@@ -1673,6 +2042,10 @@ RSpec.describe Scimitar::Resources::Mixin do
1673
2042
  {
1674
2043
  'active' => false,
1675
2044
  'value' => '42'
2045
+ },
2046
+ {
2047
+ 'active' => 'hello',
2048
+ 'value' => 'world'
1676
2049
  }
1677
2050
  ]
1678
2051
  }.with_indifferent_case_insensitive_access()
@@ -1682,10 +2055,28 @@ RSpec.describe Scimitar::Resources::Mixin do
1682
2055
  nature: 'remove',
1683
2056
  path: path,
1684
2057
  value: value,
1685
- altering_hash: scim_hash
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
+ }
1686
2070
  )
1687
2071
 
1688
- expect(scim_hash).to eql({'test' => []})
2072
+ expect(scim_hash).to eql({
2073
+ 'test' => [
2074
+ {
2075
+ 'active' => 'hello',
2076
+ 'value' => 'world'
2077
+ }
2078
+ ]
2079
+ })
1689
2080
  end
1690
2081
 
1691
2082
  it 'handles a singular to-remove value rather than an array' do
@@ -1709,7 +2100,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1709
2100
  nature: 'remove',
1710
2101
  path: path,
1711
2102
  value: value,
1712
- altering_hash: scim_hash
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
+ }
1713
2110
  )
1714
2111
 
1715
2112
  expect(scim_hash).to eql({
@@ -1717,6 +2114,10 @@ RSpec.describe Scimitar::Resources::Mixin do
1717
2114
  {
1718
2115
  'type' => 'home',
1719
2116
  'value' => 'home@test.com'
2117
+ },
2118
+ {
2119
+ 'type' => 'work',
2120
+ 'value' => nil
1720
2121
  }
1721
2122
  ]
1722
2123
  })
@@ -1738,7 +2139,10 @@ RSpec.describe Scimitar::Resources::Mixin do
1738
2139
  nature: 'remove',
1739
2140
  path: path,
1740
2141
  value: value,
1741
- altering_hash: scim_hash
2142
+ altering_hash: scim_hash,
2143
+ with_attr_map: {
2144
+ test: []
2145
+ }
1742
2146
  )
1743
2147
 
1744
2148
  expect(scim_hash).to eql({
@@ -1778,7 +2182,18 @@ RSpec.describe Scimitar::Resources::Mixin do
1778
2182
  nature: 'remove',
1779
2183
  path: path,
1780
2184
  value: value,
1781
- altering_hash: scim_hash
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
+ }
1782
2197
  )
1783
2198
 
1784
2199
  expect(scim_hash).to eql({
@@ -1817,7 +2232,18 @@ RSpec.describe Scimitar::Resources::Mixin do
1817
2232
  nature: 'remove',
1818
2233
  path: path,
1819
2234
  value: value,
1820
- altering_hash: scim_hash
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
+ }
1821
2247
  )
1822
2248
 
1823
2249
  expect(scim_hash).to eql({
@@ -1851,7 +2277,18 @@ RSpec.describe Scimitar::Resources::Mixin do
1851
2277
  nature: 'remove',
1852
2278
  path: path,
1853
2279
  value: value,
1854
- altering_hash: scim_hash
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
+ }
1855
2292
  )
1856
2293
 
1857
2294
  # The 'value' mismatched, so the user was not removed.
@@ -1881,7 +2318,8 @@ RSpec.describe Scimitar::Resources::Mixin do
1881
2318
  nature: 'remove',
1882
2319
  path: path,
1883
2320
  value: nil,
1884
- altering_hash: scim_hash
2321
+ altering_hash: scim_hash,
2322
+ with_attr_map: { userName: :user_name }
1885
2323
  )
1886
2324
 
1887
2325
  expect(scim_hash).to be_empty
@@ -1896,7 +2334,8 @@ RSpec.describe Scimitar::Resources::Mixin do
1896
2334
  nature: 'remove',
1897
2335
  path: path,
1898
2336
  value: nil,
1899
- altering_hash: scim_hash
2337
+ altering_hash: scim_hash,
2338
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
1900
2339
  )
1901
2340
 
1902
2341
  expect(scim_hash['name']).to_not have_key('givenName')
@@ -1920,7 +2359,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1920
2359
  nature: 'remove',
1921
2360
  path: path,
1922
2361
  value: nil,
1923
- altering_hash: scim_hash
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
+ }
1924
2369
  )
1925
2370
 
1926
2371
  expect(scim_hash['emails'].size).to eql(1)
@@ -1942,7 +2387,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1942
2387
  nature: 'remove',
1943
2388
  path: path,
1944
2389
  value: nil,
1945
- altering_hash: scim_hash
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
+ }
1946
2397
  )
1947
2398
 
1948
2399
  expect(scim_hash['emails'].size).to eql(1)
@@ -1965,7 +2416,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1965
2416
  nature: 'remove',
1966
2417
  path: path,
1967
2418
  value: nil,
1968
- altering_hash: scim_hash
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
+ }
1969
2426
  )
1970
2427
 
1971
2428
  expect(scim_hash['emails'].size).to eql(1)
@@ -1983,7 +2440,13 @@ RSpec.describe Scimitar::Resources::Mixin do
1983
2440
  nature: 'remove',
1984
2441
  path: path,
1985
2442
  value: nil,
1986
- altering_hash: scim_hash
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
+ }
1987
2450
  )
1988
2451
 
1989
2452
  expect(scim_hash).to be_empty
@@ -2005,7 +2468,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2005
2468
  nature: 'remove',
2006
2469
  path: path,
2007
2470
  value: nil,
2008
- altering_hash: scim_hash
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
+ }
2009
2478
  )
2010
2479
 
2011
2480
  expect(scim_hash['emails'].size).to eql(1)
@@ -2022,7 +2491,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2022
2491
  nature: 'remove',
2023
2492
  path: path,
2024
2493
  value: nil,
2025
- altering_hash: scim_hash
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
+ }
2026
2501
  )
2027
2502
 
2028
2503
  expect(scim_hash).to_not have_key('emails')
@@ -2048,7 +2523,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2048
2523
  nature: 'replace',
2049
2524
  path: path,
2050
2525
  value: 'foo',
2051
- altering_hash: scim_hash
2526
+ altering_hash: scim_hash,
2527
+ with_attr_map: { userName: :user_name }
2052
2528
  )
2053
2529
 
2054
2530
  expect(scim_hash['userName']).to eql('foo')
@@ -2063,7 +2539,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2063
2539
  nature: 'replace',
2064
2540
  path: path,
2065
2541
  value: 'Baz',
2066
- altering_hash: scim_hash
2542
+ altering_hash: scim_hash,
2543
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
2067
2544
  )
2068
2545
 
2069
2546
  expect(scim_hash['name']['givenName' ]).to eql('Baz')
@@ -2091,7 +2568,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2091
2568
  nature: 'replace',
2092
2569
  path: path,
2093
2570
  value: 'added_over_original@test.com',
2094
- altering_hash: scim_hash
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
+ }
2095
2578
  )
2096
2579
 
2097
2580
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -2117,7 +2600,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2117
2600
  nature: 'replace',
2118
2601
  path: path,
2119
2602
  value: 'added_over_original@test.com',
2120
- altering_hash: scim_hash
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
+ }
2121
2610
  )
2122
2611
 
2123
2612
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -2144,7 +2633,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2144
2633
  nature: 'replace',
2145
2634
  path: path,
2146
2635
  value: 'added_over_original@test.com',
2147
- altering_hash: scim_hash
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
+ }
2148
2643
  )
2149
2644
 
2150
2645
  expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
@@ -2173,7 +2668,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2173
2668
  nature: 'replace',
2174
2669
  path: path,
2175
2670
  value: {'type' => 'home', 'primary' => true, 'value' => 'home@test.com'},
2176
- altering_hash: scim_hash
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
+ }
2177
2678
  )
2178
2679
 
2179
2680
  expect(scim_hash['emails'].size).to eql(2)
@@ -2207,7 +2708,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2207
2708
  nature: 'replace',
2208
2709
  path: path,
2209
2710
  value: {'type' => 'workinate', 'value' => 'replaced@test.com'},
2210
- altering_hash: scim_hash
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
+ }
2211
2718
  )
2212
2719
 
2213
2720
  expect(scim_hash['emails'].size).to eql(3)
@@ -2236,7 +2743,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2236
2743
  nature: 'replace',
2237
2744
  path: path,
2238
2745
  value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
2239
- altering_hash: scim_hash
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
+ }
2240
2753
  )
2241
2754
 
2242
2755
  expect(scim_hash['emails'].size).to eql(1)
@@ -2255,7 +2768,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2255
2768
  nature: 'replace',
2256
2769
  path: path,
2257
2770
  value: 'foo',
2258
- altering_hash: scim_hash
2771
+ altering_hash: scim_hash,
2772
+ with_attr_map: { userName: :user_name }
2259
2773
  )
2260
2774
 
2261
2775
  expect(scim_hash['userName']).to eql('foo')
@@ -2270,7 +2784,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2270
2784
  nature: 'replace',
2271
2785
  path: path,
2272
2786
  value: 'Baz',
2273
- altering_hash: scim_hash
2787
+ altering_hash: scim_hash,
2788
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
2274
2789
  )
2275
2790
 
2276
2791
  expect(scim_hash['name']['givenName']).to eql('Baz')
@@ -2296,7 +2811,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2296
2811
  nature: 'replace',
2297
2812
  path: path,
2298
2813
  value: 'added@test.com',
2299
- altering_hash: scim_hash
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
+ }
2300
2821
  )
2301
2822
 
2302
2823
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -2321,7 +2842,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2321
2842
  nature: 'replace',
2322
2843
  path: path,
2323
2844
  value: 'added@test.com',
2324
- altering_hash: scim_hash
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
+ }
2325
2852
  )
2326
2853
 
2327
2854
  expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
@@ -2346,7 +2873,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2346
2873
  nature: 'replace',
2347
2874
  path: path,
2348
2875
  value: 'added@test.com',
2349
- altering_hash: scim_hash
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
+ }
2350
2883
  )
2351
2884
 
2352
2885
  expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
@@ -2364,7 +2897,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2364
2897
  nature: 'replace',
2365
2898
  path: path,
2366
2899
  value: {'type' => 'work', 'value' => 'work@test.com'},
2367
- altering_hash: scim_hash
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
+ }
2368
2907
  )
2369
2908
 
2370
2909
  expect(scim_hash['emails'].size).to eql(1)
@@ -2388,7 +2927,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2388
2927
  nature: 'replace',
2389
2928
  path: path,
2390
2929
  value: {'type' => 'work', 'value' => 'work@test.com'},
2391
- altering_hash: scim_hash
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
+ }
2392
2937
  )
2393
2938
 
2394
2939
  expect(scim_hash['emails'].size).to eql(2)
@@ -2407,7 +2952,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2407
2952
  nature: 'replace',
2408
2953
  path: path,
2409
2954
  value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
2410
- altering_hash: scim_hash
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
+ }
2411
2962
  )
2412
2963
 
2413
2964
  expect(scim_hash['emails'].size).to eql(1)
@@ -2425,7 +2976,11 @@ RSpec.describe Scimitar::Resources::Mixin do
2425
2976
  nature: 'replace',
2426
2977
  path: path,
2427
2978
  value: { 'active' => false }.with_indifferent_case_insensitive_access(),
2428
- altering_hash: scim_hash
2979
+ altering_hash: scim_hash,
2980
+ with_attr_map: {
2981
+ userName: :user_name,
2982
+ active: :active
2983
+ }
2429
2984
  )
2430
2985
 
2431
2986
  expect(scim_hash['root']['userName']).to eql('bar')
@@ -2546,7 +3101,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2546
3101
  nature: 'add',
2547
3102
  path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
2548
3103
  value: [{ 'deeper' => 'addition' }],
2549
- altering_hash: scim_hash
3104
+ altering_hash: scim_hash,
3105
+ with_attr_map: @contrived_class.scim_attributes_map()
2550
3106
  )
2551
3107
 
2552
3108
  expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
@@ -2569,7 +3125,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2569
3125
  nature: 'replace',
2570
3126
  path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
2571
3127
  value: [{ 'deeper' => 'addition' }],
2572
- altering_hash: scim_hash
3128
+ altering_hash: scim_hash,
3129
+ with_attr_map: @contrived_class.scim_attributes_map()
2573
3130
  )
2574
3131
 
2575
3132
  expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged?
@@ -2586,7 +3143,7 @@ RSpec.describe Scimitar::Resources::Mixin do
2586
3143
  expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info', 0, 'deep')).to eql('nature2deep3') # Unchanged
2587
3144
  end
2588
3145
 
2589
- it 'removes across multiple deep matching points' do
3146
+ it 'removes via clearing to "nil" or empty Array across multiple deep matching points' do
2590
3147
  scim_hash = @original_hash.deep_dup().with_indifferent_case_insensitive_access()
2591
3148
  contrived_instance = @contrived_class.new
2592
3149
  contrived_instance.send(
@@ -2594,16 +3151,17 @@ RSpec.describe Scimitar::Resources::Mixin do
2594
3151
  nature: 'remove',
2595
3152
  path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
2596
3153
  value: nil,
2597
- altering_hash: scim_hash
3154
+ altering_hash: scim_hash,
3155
+ with_attr_map: @contrived_class.scim_attributes_map()
2598
3156
  )
2599
3157
 
2600
3158
  expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
2601
- expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
3159
+ expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to eql([])
2602
3160
  expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
2603
- expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
3161
+ expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to eql([])
2604
3162
  expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
2605
3163
 
2606
- expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to be_nil
3164
+ expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to eql([])
2607
3165
  expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'nature')).to be_present
2608
3166
 
2609
3167
  expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
@@ -2637,7 +3195,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2637
3195
  nature: 'replace',
2638
3196
  path: path,
2639
3197
  value: 'ignored',
2640
- altering_hash: scim_hash
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
+ }
2641
3205
  )
2642
3206
  end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
2643
3207
  end
@@ -2654,7 +3218,8 @@ RSpec.describe Scimitar::Resources::Mixin do
2654
3218
  nature: 'replace',
2655
3219
  path: path,
2656
3220
  value: 'ignored',
2657
- altering_hash: scim_hash
3221
+ altering_hash: scim_hash,
3222
+ with_attr_map: { userName: :user_name }
2658
3223
  )
2659
3224
  end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
2660
3225
  end
@@ -2674,7 +3239,13 @@ RSpec.describe Scimitar::Resources::Mixin do
2674
3239
  nature: 'replace',
2675
3240
  path: path,
2676
3241
  value: 'ignored',
2677
- altering_hash: scim_hash
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
+ }
2678
3249
  )
2679
3250
  end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
2680
3251
  end