spec/models/scimitar/resources/mixin_spec.rb in scimitar-2.7.1 vs spec/models/scimitar/resources/mixin_spec.rb in scimitar-2.7.2
- old
+ new
@@ -79,10 +79,106 @@
end
include Scimitar::Resources::Mixin
end
+ # A simple schema containing two attributes that looks very like complex
+ # type "name", except shorter and with "familyName" never returned.
+ #
+ NestedReturnedNeverTestNameSchema = Class.new(Scimitar::Schema::Base) do
+ def self.id
+ 'nested-returned-never-name-id'
+ end
+
+ def self.scim_attributes
+ @scim_attributes ||= [
+ Scimitar::Schema::Attribute.new(name: 'familyName', type: 'string', required: true, returned: 'never'),
+ Scimitar::Schema::Attribute.new(name: 'givenName', type: 'string', required: true)
+ ]
+ end
+ end
+
+ # A complex type that uses the above schema, giving us the ability to define
+ # an attribute using this complex type, with therefore the *nested* attribute
+ # "familyName" being never returned.
+ #
+ NestedReturnedNeverTestNameType = Class.new(Scimitar::ComplexTypes::Base) do
+ set_schema NestedReturnedNeverTestNameSchema
+ end
+
+ # A test schema that uses the above type, the standard name type (but that
+ # *entire* top-level attribute is never returned) and a simple String item.
+ #
+ NestedReturnedNeverTestSchema = Class.new(Scimitar::Schema::Base) do
+ def self.id
+ 'nested-returned-never-id'
+ end
+
+ def self.scim_attributes
+ [
+ Scimitar::Schema::Attribute.new(
+ name: 'name', complexType: NestedReturnedNeverTestNameType
+ ),
+ Scimitar::Schema::Attribute.new(
+ name: 'privateName', complexType: Scimitar::ComplexTypes::Name, returned: 'never'
+ ),
+ Scimitar::Schema::Attribute.new(
+ name: 'simpleName', type: 'string'
+ )
+ ]
+ end
+ end
+
+ # Define a resource that is based upon the above schema.
+ #
+ NestedReturnedNeverTestResourse = Class.new(Scimitar::Resources::Base) do
+ set_schema NestedReturnedNeverTestSchema
+ end
+
+ # Create a testable model that is our internal representation of the above
+ # resource.
+ #
+ class NestedReturnedNeverTest
+ include ActiveModel::Model
+
+ def self.scim_resource_type
+ return NestedReturnedNeverTestResourse
+ end
+
+ attr_accessor :given_name,
+ :last_name,
+ :private_given_name,
+ :private_last_name,
+ :simple_name
+
+ def self.scim_attributes_map
+ return {
+ name: {
+ givenName: :given_name,
+ familyName: :last_name
+ },
+
+ privateName: {
+ givenName: :private_given_name,
+ familyName: :private_last_name
+ },
+
+ simpleName: :simple_name
+ }
+ end
+
+ def self.scim_mutable_attributes
+ return nil
+ end
+
+ def self.scim_queryable_attributes
+ return nil
+ end
+
+ include Scimitar::Resources::Mixin
+ end
+
# ===========================================================================
# Errant class definitions
# ===========================================================================
context 'with bad class definitions' do
@@ -360,10 +456,34 @@
})
end
end # "context 'using dynamic lists' do"
end # "context 'with arrays' do"
+ context 'with "returned: \'never\' fields' do
+ it 'hides appropriate top-level and nested attributes' do
+ instance = NestedReturnedNeverTest.new(
+ given_name: 'One',
+ last_name: 'Two',
+ private_given_name: 'Three',
+ private_last_name: 'Four',
+ simple_name: 'Five'
+ )
+
+ scim = instance.to_scim(location: 'https://test.com/never_retutrned_test')
+ json = scim.to_json()
+ hash = JSON.parse(json)
+
+ expect(hash).to eql({
+ 'name' => { 'givenName' => 'One' },
+ 'simpleName' => 'Five',
+
+ 'meta' => {'location'=>'https://test.com/never_retutrned_test', 'resourceType'=>'NestedReturnedNeverTestResourse'},
+ 'schemas' => ['nested-returned-never-id']
+ })
+ end
+ end # "context 'with "returned: \'never\' fields' do"
+
context 'with bad definitions' do
it 'complains about non-Hash entries in mapping Arrays' do
expect(StaticMapTest).to receive(:scim_attributes_map).and_return({
emails: [
'this is not Hash'
@@ -700,11 +820,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'foo',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
expect(scim_hash['userName']).to eql('foo')
end
@@ -715,11 +836,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'Baz',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
expect(scim_hash['name']['givenName' ]).to eql('Baz')
expect(scim_hash['name']['familyName']).to eql('Bar')
end
@@ -731,11 +853,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'OTHERORG',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { organization: :org_name }
)
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('OTHERORG')
end
@@ -761,11 +884,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -787,11 +916,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -814,11 +949,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -838,11 +979,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(2)
expect(scim_hash['emails'][1]['type' ]).to eql('work')
expect(scim_hash['emails'][1]['value']).to eql('work@test.com')
@@ -886,11 +1033,16 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: ['root'],
value: {'members' => [{'value' => '3'}]},
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id } }
+ ]
+ }
)
expect(scim_hash['root']['members']).to match_array([{'value' => '1'}, {'value' => '2'}, {'value' => '3'}])
end
end # "context 'with complex value addition' do"
@@ -904,11 +1056,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'foo',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
expect(scim_hash['userName']).to eql('foo')
end
@@ -919,11 +1072,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'Baz',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
expect(scim_hash['name']['givenName']).to eql('Baz')
end
@@ -934,11 +1088,12 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'SOMEORG',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { organization: :org_name }
)
expect(scim_hash['urn:ietf:params:scim:schemas:extension:enterprise:2.0:User']['organization' ]).to eql('SOMEORG')
end
@@ -960,11 +1115,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -985,11 +1146,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -1001,11 +1168,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
end
@@ -1025,11 +1198,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -1042,11 +1221,17 @@
@instance.send(
:from_patch_backend!,
nature: 'add',
path: path,
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['type' ]).to eql('work')
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
@@ -1058,43 +1243,44 @@
# Internal: #from_patch_backend - remove
# -------------------------------------------------------------------
#
context 'remove' do
context 'when prior value already exists' do
- it 'simple value: removes' do
+ it 'simple value: clears to "nil" in order to remove' do
path = [ 'userName' ]
scim_hash = { 'userName' => 'bar' }.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
- expect(scim_hash).to be_empty
+ expect(scim_hash).to eql({ 'userName' => nil })
end
- it 'nested simple value: removes' do
+ it 'nested simple value: clears to "nil" in order to remove' do
path = [ 'name', 'givenName' ]
scim_hash = { 'name' => { 'givenName' => 'Foo', 'familyName' => 'Bar' } }.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
- expect(scim_hash['name']).to_not have_key('givenName')
- expect(scim_hash['name']['familyName']).to eql('Bar')
+ expect(scim_hash).to eql({ 'name' => { 'givenName' => nil, 'familyName' => 'Bar' } })
end
context 'with filter mid-path' do
- it 'by string match: removes' do
+ it 'by string match: clears to "nil" in order to remove' do
path = [ 'emails[type eq "work"]', 'value' ]
scim_hash = {
'emails' => [
{
'type' => 'home',
@@ -1110,18 +1296,34 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
- expect(scim_hash['emails'][1]).to_not have_key('value')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'type' => 'home',
+ 'value' => 'home@test.com'
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
+ }
+ ]
+ })
end
- it 'by boolean match: removes' do
+ it 'by boolean match: clears to "nil" in order to remove' do
path = [ 'emails[primary eq true]', 'value' ]
scim_hash = {
'emails' => [
{
'value' => 'home@test.com'
@@ -1136,47 +1338,86 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
- expect(scim_hash['emails'][1]).to_not have_key('value')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'value' => 'home@test.com'
+ },
+ {
+ 'value' => nil,
+ 'primary' => true
+ }
+ ]
+ })
end
- it 'multiple matches: removes all' do
+ it 'multiple matches: clears all to "nil" in order to remove' do
path = [ 'emails[type eq "work"]', 'value' ]
scim_hash = {
'emails' => [
{
'type' => 'work',
'value' => 'work_1@test.com'
},
{
'type' => 'work',
'value' => 'work_2@test.com'
- }
+ },
+ {
+ 'type' => 'home',
+ 'value' => 'home@test.com'
+ },
]
}.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'][0]).to_not have_key('value')
- expect(scim_hash['emails'][1]).to_not have_key('value')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'type' => 'work',
+ 'value' => nil
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
+ },
+ {
+ 'type' => 'home',
+ 'value' => 'home@test.com'
+ },
+ ]
+ })
end
end # "context 'with filter mid-path' do"
context 'with filter at end of path' do
- it 'by string match: removes entire matching array entry' do
+ it 'by string match: clears to "nil" in order to remove' do
path = [ 'emails[type eq "work"]' ]
scim_hash = {
'emails' => [
{
'type' => 'home',
@@ -1192,44 +1433,75 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'].size).to eql(1)
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'type' => 'home',
+ 'value' => 'home@test.com'
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
+ }
+ ]
+ })
end
- it 'by boolean match: removes entire matching array entry' do
+ it 'by boolean match: clears to "nil" in order to remove' do
path = [ 'emails[primary eq true]' ]
scim_hash = {
'emails' => [
{
- 'value' => 'home@test.com'
+ 'value' => 'home@test.com',
+ 'primary' => true
},
{
- 'value' => 'work@test.com',
- 'primary' => true
+ 'value' => 'work@test.com'
}
]
}.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'].size).to eql(1)
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'value' => nil,
+ 'primary' => true
+ },
+ {
+ 'value' => 'work@test.com'
+ }
+ ]
+ })
end
- it 'multiple matches: removes all matching array entries' do
+ it 'multiple matches: clears all to "nil" in order to remove' do
path = [ 'emails[type eq "work"]' ]
scim_hash = {
'emails' => [
{
'type' => 'work',
@@ -1249,38 +1521,79 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash['emails'].size).to eql(1)
- expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'type' => 'work',
+ 'value' => nil
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
+ },
+ {
+ 'type' => 'home',
+ 'value' => 'home@test.com'
+ },
+ ]
+ })
end
end # "context 'with filter at end of path' do"
- it 'whole array: removes' do
+ it 'whole array: clears mapped values to "nil" to remove them' do
path = [ 'emails' ]
scim_hash = {
'emails' => [
{
'type' => 'home',
'value' => 'home@test.com'
+ },
+ {
+ 'type' => 'work',
+ 'value' => 'work@test.com'
}
]
}.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
- expect(scim_hash).to_not have_key('emails')
+ expect(scim_hash).to eql({
+ 'emails' => [
+ {
+ 'type' => 'home',
+ 'value' => nil
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
+ }
+ ]
+ })
end
# What we expect:
#
# https://tools.ietf.org/html/rfc7644#section-3.5.2.2
@@ -1322,11 +1635,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => [
@@ -1374,11 +1692,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => [
@@ -1408,11 +1731,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => []
@@ -1436,11 +1764,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => []
@@ -1464,11 +1797,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
# The 'value' mismatched, so the user was not removed.
#
expect(scim_hash).to eql({
@@ -1500,11 +1838,16 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
# Type 'Group' mismatches 'User', so the user was not
# removed.
#
@@ -1518,11 +1861,11 @@
}
]
})
end
- it 'matches keys case-insensitive' do
+ it 'matches keys case-insensitive (but preserves case in response)' do
path = [ 'members' ]
value = [ { '$ref' => nil, 'VALUe' => 'f648f8d5ea4e4cd38e9c' } ]
scim_hash = {
'displayname' => 'Mock group',
'memBERS' => [
@@ -1537,24 +1880,29 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
- 'members' => []
+ 'memBERS' => []
})
end
it 'matches values case-sensitive' do
path = [ 'members' ]
value = [ { '$ref' => nil, 'value' => 'f648f8d5ea4e4cd38e9c', 'type' => 'USER' } ]
scim_hash = {
- 'displayname' => 'Mock group',
+ 'displayName' => 'Mock group',
'members' => [
{
'value' => 'f648f8d5ea4e4cd38e9c',
'display' => 'Fred Smith',
'type' => 'User'
@@ -1565,17 +1913,22 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ members: [
+ { list: :members, using: { value: :id, display: :full_name, type: 'User' } }
+ ]
+ }
)
- # USER mismatchs User, so the user was not removed.
+ # USER mismatches User, so the user was not removed.
#
expect(scim_hash).to eql({
- 'displayname' => 'Mock group',
+ 'displayName' => 'Mock group',
'members' => [
{
'value' => 'f648f8d5ea4e4cd38e9c',
'display' => 'Fred Smith',
'type' => 'User'
@@ -1584,11 +1937,11 @@
})
end
end # "context 'removing a user from a group' do"
context 'generic use' do
- it 'removes matched items' do
+ it 'clears static map matched items to "nil" in order to remove' do
path = [ 'emails' ]
value = [ { 'type' => 'work' } ]
scim_hash = {
'emails' => [
{
@@ -1605,18 +1958,28 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash).to eql({
'emails' => [
{
'type' => 'home',
'value' => 'home@test.com'
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
}
]
})
end
@@ -1639,11 +2002,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash).to eql({
'emails' => [
{
@@ -1671,23 +2040,45 @@
'value' => 12
},
{
'active' => false,
'value' => '42'
+ },
+ {
+ 'active' => 'hello',
+ 'value' => 'world'
}
]
}.with_indifferent_case_insensitive_access()
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ test: [
+ {
+ list: :test,
+ using: {
+ active: :active,
+ value: :value
+ }
+ }
+ ]
+ }
)
- expect(scim_hash).to eql({'test' => []})
+ expect(scim_hash).to eql({
+ 'test' => [
+ {
+ 'active' => 'hello',
+ 'value' => 'world'
+ }
+ ]
+ })
end
it 'handles a singular to-remove value rather than an array' do
path = [ 'emails' ]
value = { 'type' => 'work' }
@@ -1707,18 +2098,28 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash).to eql({
'emails' => [
{
'type' => 'home',
'value' => 'home@test.com'
+ },
+ {
+ 'type' => 'work',
+ 'value' => nil
}
]
})
end
@@ -1736,11 +2137,14 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ test: []
+ }
)
expect(scim_hash).to eql({
'test' => [
'21',
@@ -1776,11 +2180,22 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ displayName: :name,
+ members: [
+ list: :members,
+ using: {
+ value: :id,
+ display: :full_name,
+ type: 'User'
+ }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => [
@@ -1815,11 +2230,22 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ displayName: :name,
+ members: [
+ list: :members,
+ using: {
+ value: :id,
+ display: :full_name,
+ type: 'User'
+ }
+ ]
+ }
)
expect(scim_hash).to eql({
'displayname' => 'Mock group',
'members' => [
@@ -1849,11 +2275,22 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: value,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ displayName: :name,
+ members: [
+ list: :members,
+ using: {
+ value: :id,
+ display: :full_name,
+ type: 'User'
+ }
+ ]
+ }
)
# The 'value' mismatched, so the user was not removed.
#
expect(scim_hash).to eql({
@@ -1879,11 +2316,12 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
expect(scim_hash).to be_empty
end
@@ -1894,11 +2332,12 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
expect(scim_hash['name']).to_not have_key('givenName')
expect(scim_hash['name']['familyName']).to eql('Bar')
end
@@ -1918,11 +2357,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
end
@@ -1940,11 +2385,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
end
@@ -1963,11 +2414,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
end
@@ -1981,11 +2438,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash).to be_empty
end
@@ -2003,11 +2466,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
end
@@ -2020,11 +2489,17 @@
@instance.send(
:from_patch_backend!,
nature: 'remove',
path: path,
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash).to_not have_key('emails')
end
end # context 'when value is not present' do
@@ -2046,11 +2521,12 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'foo',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
expect(scim_hash['userName']).to eql('foo')
end
@@ -2061,11 +2537,12 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'Baz',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
expect(scim_hash['name']['givenName' ]).to eql('Baz')
expect(scim_hash['name']['familyName']).to eql('Bar')
end
@@ -2089,11 +2566,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -2115,11 +2598,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -2142,11 +2631,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added_over_original@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('added_over_original@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added_over_original@test.com')
end
@@ -2171,11 +2666,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: {'type' => 'home', 'primary' => true, 'value' => 'home@test.com'},
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(2)
expect(scim_hash['emails'][0]['type' ]).to eql('holiday') # unchanged
expect(scim_hash['emails'][1]['type' ]).to eql('home') # "work" became "home"
@@ -2205,11 +2706,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: {'type' => 'workinate', 'value' => 'replaced@test.com'},
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(3)
expect(scim_hash['emails'][0]['type' ]).to eql('workinate')
expect(scim_hash['emails'][0]['value']).to eql('replaced@test.com')
@@ -2234,11 +2741,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['type' ]).to eql('work')
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
@@ -2253,11 +2766,12 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'foo',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
expect(scim_hash['userName']).to eql('foo')
end
@@ -2268,11 +2782,12 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'Baz',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { name: { givenName: :first_name, familyName: :last_name } }
)
expect(scim_hash['name']['givenName']).to eql('Baz')
end
@@ -2294,11 +2809,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -2319,11 +2840,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -2344,11 +2871,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'added@test.com',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'][0]['value']).to eql('added@test.com')
expect(scim_hash['emails'][1]['value']).to eql('added@test.com')
end
@@ -2362,11 +2895,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: {'type' => 'work', 'value' => 'work@test.com'},
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['type' ]).to eql('work')
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
@@ -2386,11 +2925,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: {'type' => 'work', 'value' => 'work@test.com'},
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(2)
expect(scim_hash['emails'][0]['value']).to eql('home@test.com')
expect(scim_hash['emails'][1]['type' ]).to eql('work')
@@ -2405,11 +2950,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: [ { 'type' => 'work', 'value' => 'work@test.com' } ], # NOTE - to-add value is an Array (and must be)
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
expect(scim_hash['emails'].size).to eql(1)
expect(scim_hash['emails'][0]['type' ]).to eql('work')
expect(scim_hash['emails'][0]['value']).to eql('work@test.com')
@@ -2423,11 +2974,15 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: { 'active' => false }.with_indifferent_case_insensitive_access(),
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ userName: :user_name,
+ active: :active
+ }
)
expect(scim_hash['root']['userName']).to eql('bar')
expect(scim_hash['root']['active']).to eql(false)
end
@@ -2544,11 +3099,12 @@
contrived_instance.send(
:from_patch_backend!,
nature: 'add',
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
value: [{ 'deeper' => 'addition' }],
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: @contrived_class.scim_attributes_map()
)
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info').count).to eql(2) # One new item
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'info').count).to eql(2) # One new item
@@ -2567,11 +3123,12 @@
contrived_instance.send(
:from_patch_backend!,
nature: 'replace',
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
value: [{ 'deeper' => 'addition' }],
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: @contrived_class.scim_attributes_map()
)
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged?
expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info').count).to eql(1)
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'info').count).to eql(1)
@@ -2584,28 +3141,29 @@
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info', 0, 'deep')).to eql('nature2deep3') # Unchanged
end
- it 'removes across multiple deep matching points' do
+ it 'removes via clearing to "nil" or empty Array across multiple deep matching points' do
scim_hash = @original_hash.deep_dup().with_indifferent_case_insensitive_access()
contrived_instance = @contrived_class.new
contrived_instance.send(
:from_patch_backend!,
nature: 'remove',
path: ['complex[type eq "type1"]', 'data', 'nested[nature eq "nature2"]', 'info'],
value: nil,
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: @contrived_class.scim_attributes_map()
)
expect(scim_hash.dig('complex', 0, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
- expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
+ expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to eql([])
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
- expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to be_nil
+ expect(scim_hash.dig('complex', 0, 'data', 'nested', 1, 'info')).to eql([])
expect(scim_hash.dig('complex', 0, 'data', 'nested', 2, 'nature')).to be_present
- expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to be_nil
+ expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'info')).to eql([])
expect(scim_hash.dig('complex', 1, 'data', 'nested', 0, 'nature')).to be_present
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info').count).to eql(1) # Unchanged
expect(scim_hash.dig('complex', 2, 'data', 'nested', 0, 'info', 0, 'deep')).to eql('nature2deep3') # Unchanged
end
@@ -2635,11 +3193,17 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'ignored',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
end
it 'when filters are specified for non-array types' do
@@ -2652,11 +3216,12 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'ignored',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: { userName: :user_name }
)
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
end
it 'when a filter tries to match an array which does not contain Hashes' do
@@ -2672,10 +3237,16 @@
@instance.send(
:from_patch_backend!,
nature: 'replace',
path: path,
value: 'ignored',
- altering_hash: scim_hash
+ altering_hash: scim_hash,
+ with_attr_map: {
+ emails: [
+ { match: 'type', with: 'home', using: { value: :home_email, primary: true } },
+ { match: 'type', with: 'work', using: { value: :work_email } },
+ ]
+ }
)
end.to raise_error(Scimitar::ErrorResponse) { |e| expect(e.as_json['scimType']).to eql('invalidSyntax') }
end
end # context 'with bad patches, raises errors' do
end # "context '#from_patch_backend!' do"