UNPKG

scim-patch-with-remove

Version:
677 lines (612 loc) 31.4 kB
import { InvalidScimPatchOp, InvalidScimPatchRequest, NoPathInScimPatchOp, scimPatch, InvalidScimPatch } from '../src/scimPatch'; import {ScimUser} from './types/types.test'; import {expect} from 'chai'; import {ScimPatchAddReplaceOperation, ScimPatchRemoveOperation} from '../src/types/types'; import {DeepArrayRemovalNotSupported, NoTarget, UnsupportedBlueprintEntities} from "../src/errors/scimErrors"; describe('SCIM PATCH', () => { let scimUser: ScimUser; beforeEach(done => { scimUser = JSON.parse(`{ "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User" ], "id": "tea_4", "userName": "spiderman", "name": { "familyName": "Parker", "givenName": "Peter" }, "active": true, "emails": [ { "value": "spiderman@superheroes.com", "primary": true } ], "roles": [], "meta": { "resourceType": "User", "created": "2019-11-20T09:25:30.208Z", "lastModified": "2019-11-20T09:25:30.208Z", "location": "**REQUIRED**/Users/tea_4" }, "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department": "value" }`); return done(); }); describe('replace', () => { it('REPLACE: first level property with path', done => { const expected = false; const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: expected, path: 'active'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.active).to.be.eq(expected); return done(); }); it('REPLACE: first level property without path', done => { const expected = false; const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: {active: expected}}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.active).to.be.eq(expected); return done(); }); it('REPLACE: 2 level property with path', done => { const expected = 'toto'; const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: expected, path: 'name.familyName'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.familyName).to.be.eq(expected); return done(); }); it('REPLACE: 2 level property without complete path', done => { const expected = 'toto'; const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: {familyName: expected}, path: 'name'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.familyName).to.be.eq(expected); return done(); }); it('REPLACE: multiple at once with path', done => { const expectedFamilyName = 'toto'; const expectedGivenName = 'titi'; const expectedActive = false; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: { givenName: expectedGivenName, familyName: expectedFamilyName }, path: 'name' }; const patch2: ScimPatchAddReplaceOperation = {op: 'replace', value: {active: expectedActive}}; const afterPatch = scimPatch(scimUser, [patch1, patch2]); expect(afterPatch.name.familyName).to.be.eq(expectedFamilyName); expect(afterPatch.name.givenName).to.be.eq(expectedGivenName); expect(afterPatch.active).to.be.eq(expectedActive); return done(); }); it('REPLACE: multiple at once with exact path', done => { const expectedFamilyName = 'toto'; const expectedGivenName = 'titi'; const expectedActive = false; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: expectedGivenName, path: 'name.givenName' }; const patch2: ScimPatchAddReplaceOperation = {op: 'replace', value: {active: expectedActive}}; const patch3: ScimPatchAddReplaceOperation = { op: 'replace', value: expectedFamilyName, path: 'name.familyName' }; const afterPatch = scimPatch(scimUser, [patch1, patch2, patch3]); expect(afterPatch.name.familyName).to.be.eq(expectedFamilyName); expect(afterPatch.name.givenName).to.be.eq(expectedGivenName); expect(afterPatch.active).to.be.eq(expectedActive); return done(); }); it('REPLACE: primary email object', done => { const expected = 'toto@toto.com'; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: {value: expected, primary: true}, path: 'emails[primary eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.emails[0].value).to.be.eq(expected); expect(afterPatch.emails[0].primary).to.be.eq(true); return done(); }); it('REPLACE: nested object do not exists', done => { scimUser.surName = [{value: 'toto', primary: true}]; const expected = 'toto@toto.com'; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: {value: expected, primary: false}, path: 'surName[primary eq false]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.surName?.length).to.be.eq(2); return done(); }); it('REPLACE: primary email value', done => { const expected = 'toto@toto.com'; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: expected, path: 'emails[primary eq true].value' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.emails[0].value).to.be.eq(expected); expect(afterPatch.emails[0].primary).to.be.eq(true); return done(); }); it('REPLACE: nested array element', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}]; const expected = 'value2'; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: { value: expected, primary: true }, path: 'name.nestedArray[primary eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray[0].value).to.be.eq(expected); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray[0].primary).to.be.eq(true); return done(); }); it('REPLACE: replace a non existent element', done => { const expected = true; const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: expected, path: 'unknown.toto'}; const afterPatch: any = scimPatch(scimUser, [patch]); expect(afterPatch.unknown.toto).to.be.eq(expected); return done(); }); it('REPLACE: add a non object value to an object key', done => { const expected = 'BATMAN'; const patch: ScimPatchAddReplaceOperation = {op: 'replace', path: 'name', value: expected}; const afterPatch: any = scimPatch(scimUser, [patch]); expect(afterPatch.name).to.be.eq(expected); return done(); }); it('REPLACE: should not modify anything if element not found', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}]; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: { newProperty1: 'toto' }, path: 'name.nestedArray[toto eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray).to.be.eq(scimUser.name.nestedArray); return done(); }); it('REPLACE: XXX', done => { const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'emails[primary eq true].value'}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.emails[0].value).not.to.exist; expect(afterPatch.emails[0].primary).to.eq(true); return done(); }); it('REPLACE: with capital first letter for operation', done => { const expected = false; const patch: ScimPatchAddReplaceOperation = {op: 'Replace', value: {active: expected}}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.active).to.be.eq(expected); return done(); }); it('REPLACE: with version number in path', done => { const expected = 'newValue'; const path = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'; const patch: ScimPatchAddReplaceOperation = { op: 'replace', value: expected, path: path }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path]).to.be.eq(expected); return done(); }); it('REPLACE: array by another array', done => { const expected = [ { value: 'test2' } ]; const path = 'emails'; const patch: ScimPatchAddReplaceOperation = { op: 'replace', value: expected, path: path }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path]).to.be.eq(expected); return done(); }); it("REPLACE: no record match was made", (done) => { // empty the surName fields. scimUser.surName = []; const patch: ScimPatchAddReplaceOperation = { op: "replace", path: "surName[primary eq true].value", value: "surname" }; expect(() => scimPatch(scimUser, [patch])).to.throw(NoTarget); return done(); }); }); describe('add', () => { it('ADD: first level property without path', done => { const expected = 'newValue'; const patch: ScimPatchAddReplaceOperation = {op: 'add', value: {newProperty: expected}}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.newProperty).to.be.eq(expected); return done(); }); it('ADD: first level property with path', done => { const expected = 'newValue'; const patch: ScimPatchAddReplaceOperation = {op: 'add', value: expected, path: 'newProperty'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.newProperty).to.be.eq(expected); return done(); }); it('ADD: 2 level property with path', done => { const expected = 'toto'; const patch: ScimPatchAddReplaceOperation = {op: 'add', value: expected, path: 'name.newProperty'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.newProperty).to.be.eq(expected); return done(); }); it('ADD: 2 level property without complete path', done => { const expected = 'toto'; const patch: ScimPatchAddReplaceOperation = {op: 'add', value: {newProperty: expected}, path: 'name'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.newProperty).to.be.eq(expected); return done(); }); it('ADD: multiple at once with path', done => { const expectedNewProperty1 = 'toto'; const expectedNewProperty2 = 'titi'; const expectedNewProperty3 = 'tata'; const patch1: ScimPatchAddReplaceOperation = { op: 'add', value: { newProperty1: expectedNewProperty1, newProperty2: expectedNewProperty2 }, path: 'name' }; const patch2: ScimPatchAddReplaceOperation = {op: 'add', value: {newProperty3: expectedNewProperty3}}; const afterPatch = scimPatch(scimUser, [patch1, patch2]); expect(afterPatch.name.newProperty1).to.be.eq(expectedNewProperty1); expect(afterPatch.name.newProperty2).to.be.eq(expectedNewProperty2); expect(afterPatch.newProperty3).to.be.eq(expectedNewProperty3); return done(); }); it('ADD: multiple at once with exact path', done => { const expectedNewProperty1 = 'toto'; const expectedNewProperty2 = 'titi'; const expectedNewProperty3 = 'tata'; const patch1: ScimPatchAddReplaceOperation = { op: 'replace', value: expectedNewProperty1, path: 'name.newProperty1' }; const patch2: ScimPatchAddReplaceOperation = {op: 'replace', value: {newProperty3: expectedNewProperty3}}; const patch3: ScimPatchAddReplaceOperation = { op: 'replace', value: expectedNewProperty2, path: 'name.newProperty2' }; const afterPatch = scimPatch(scimUser, [patch1, patch2, patch3]); expect(afterPatch.name.newProperty1).to.be.eq(expectedNewProperty1); expect(afterPatch.name.newProperty2).to.be.eq(expectedNewProperty2); expect(afterPatch.newProperty3).to.be.eq(expectedNewProperty3); return done(); }); it('ADD: primary email object', done => { const expectedNewProperty1 = 'toto'; const expectedNewProperty2 = 'titi'; const patch1: ScimPatchAddReplaceOperation = { op: 'add', value: { newProperty1: expectedNewProperty1, newProperty2: expectedNewProperty2 }, path: 'emails[primary eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.emails[0].newProperty1).to.be.eq(expectedNewProperty1); expect(afterPatch.emails[0].newProperty2).to.be.eq(expectedNewProperty2); expect(afterPatch.emails[0].value).to.be.eq(scimUser.emails[0].value); return done(); }); it('ADD: primary email newProperty', done => { const expected = 'toto@toto.com'; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: expected, path: 'emails[primary eq true].newProperty' }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.emails[0].newProperty).to.be.eq(expected); expect(afterPatch.emails[0].primary).to.be.eq(true); return done(); }); it('ADD: nested array element', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}]; const expectedNewProperty1 = 'toto'; const expectedNewProperty2 = 'titi'; const patch1: ScimPatchAddReplaceOperation = { op: 'add', value: { newProperty1: expectedNewProperty1, newProperty2: expectedNewProperty2 }, path: 'name.nestedArray[primary eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray[0].newProperty1).to.be.eq(expectedNewProperty1); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray[0].newProperty2).to.be.eq(expectedNewProperty2); return done(); }); it('ADD: If the target location specifies a multi-valued attribute, a new value is added to the attribute.', done => { scimUser.name.surName2 = ['toto', 'titi']; const newSurname = 'tata'; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: newSurname, path: 'name.surName2' }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.surName2).to.contains('toto'); expect(afterPatch.name.surName2).to.contains(newSurname); return done(); }); it('ADD: If the target location specifies a single-valued attribute, the existing value is replaced', done => { scimUser.name.surName3 = 'surName'; const newSurname = 'tata'; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: newSurname, path: 'name.surName3' }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.surName3).to.be.eq(newSurname); return done(); }); it('ADD: If the target location specifies a multi-valued attribute, a new value is added to the attribute.', done => { scimUser.name.surName2 = ['toto', 'titi']; const newSurname = 'tata'; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: newSurname, path: 'name.surName2' }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.surName2).to.contains('toto'); expect(afterPatch.name.surName2).to.contains('titi'); expect(afterPatch.name.surName2).to.contains(newSurname); return done(); }); it('ADD: If the target location specifies a multi-valued attribute, a new value is added to the attribute only if doesn\'t exist already.', done => { scimUser.name.surName2 = ['toto', 'titi']; const newSurname = 'titi'; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: newSurname, path: 'name.surName2' }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.surName2).to.contains('toto'); expect(afterPatch.name.surName2?.filter(s => s === 'titi').length).to.eq(1); return done(); }); it('ADD: impossible to add a non object value to an object key', done => { const patch: ScimPatchAddReplaceOperation = {op: 'add', path: 'name', value: 'titi'}; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatchOp); return done(); }); it('ADD: should not modify anything if element not found', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}]; const patch1: ScimPatchAddReplaceOperation = { op: 'add', value: { newProperty1: 'toto' }, path: 'name.nestedArray[toto eq true]' }; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray).to.be.eq(scimUser.name.nestedArray); return done(); }); it('ADD: with capital first letter for operation', done => { const expected = 'newValue'; const patch: ScimPatchAddReplaceOperation = {op: 'Add', value: {newProperty: expected}}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.newProperty).to.be.eq(expected); return done(); }); it('ADD: with version number in path', done => { const expected = 'newValue'; const path = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'; delete scimUser[path]; const patch: ScimPatchAddReplaceOperation = { op: 'add', value: 'newValue', path: path }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path]).to.be.eq(expected); return done(); }); it("ADD: array", (done) => { const newValue = { value: "test2" }; const newArray = [newValue]; const path = "emails"; const initialArrayLength = scimUser[path].length; const patch: ScimPatchAddReplaceOperation = { op: "Add", value: newArray, path, }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path].length).to.be.eq( initialArrayLength + newArray.length ); expect( afterPatch[path].find((val) => val.value === newValue.value) ).to.eq(newValue); return done(); }); it("ADD: array ignores existing values", (done) => { const path = "emails"; const initialArrayLength = scimUser[path].length; const patch: ScimPatchAddReplaceOperation = { op: "Add", value: scimUser[path], path, }; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path].length).to.be.eq(initialArrayLength); return done(); }); }); describe('remove', () => { it('REMOVE: with no path', done => { const patch = <ScimPatchRemoveOperation>{op: 'remove'}; expect(() => scimPatch(scimUser, [patch])).to.throw(NoPathInScimPatchOp); return done(); }); it('REMOVE: first level property with path', done => { const patch: ScimPatchRemoveOperation = {op: 'remove', path: 'active'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.active).not.to.exist; return done(); }); it('REMOVE: 2 level property with path', done => { const patch: ScimPatchRemoveOperation = {op: 'remove', path: 'name.familyName'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name.familyName).not.to.exist; return done(); }); it('REMOVE: full object', done => { const patch: ScimPatchRemoveOperation = {op: 'remove', path: 'name'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.name).not.to.exist; return done(); }); it('REMOVE: multiple property at once with path', done => { const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name'}; const patch2: ScimPatchRemoveOperation = {op: 'remove', path: 'active'}; const afterPatch = scimPatch(scimUser, [patch1, patch2]); expect(afterPatch.name).not.to.exist; expect(afterPatch.active).not.to.exist; return done(); }); it('REMOVE: primary email value', done => { const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'emails[primary eq true].value'}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.emails[0].value).not.to.exist; expect(afterPatch.emails[0].primary).to.eq(true); return done(); }); it('REMOVE: nested array element', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray[primary eq true]'}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: with path and value but no array-field like exists', done => { const patch = <ScimPatchRemoveOperation>{op: 'remove', 'path': 'name.randomField', value: []}; expect(() => scimPatch(scimUser, [patch])).to.throw(UnsupportedBlueprintEntities); return done(); }); it('REMOVE: with path and value but value is array of arrays', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}]; const patch = <ScimPatchRemoveOperation>{op: 'remove', 'path': 'name.nestedArray', value: [[]]}; expect(() => scimPatch(scimUser, [patch])).to.throw(DeepArrayRemovalNotSupported); return done(); }); it('REMOVE: nested array element with value supplied', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray', value: [{value: 'value2', primary: false}]}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: nested array element with value supplied for multiple entries', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}, {primary: false, value: 'value2'}, {primary: false, value: 'value2'}, {primary: false, value: 'value3'}, {primary: false, value: 'value3'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray', value: [{value: 'value2', primary: false}, {value: 'value3', primary: false}]}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: nested array element with value supplied', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray', value: [{value: 'value2', primary: false}]}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: nested array element with value as object supplied', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray', value: {value: 'value2', primary: false}}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: nested array element with value as object supplied with multiple entries', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}, {primary: false, value: 'value2'}, {primary: false, value: 'value2'}, {primary: false, value: 'value2'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray', value: {value: 'value2', primary: false}}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray && afterPatch.name.nestedArray.length).to.eq(1); return done(); }); it('REMOVE: simple nested array elements with value supplied', done => { scimUser.name.surName2 = ['value1', 'value2']; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.surName2', value: ['value2']}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.surName2 && afterPatch.name.surName2.length).to.eq(1); return done(); }); it('REMOVE: simple nested array elements with non-existing in scope value supplied', done => { scimUser.name.surName2 = ['value1', 'value2']; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.surName2', value: ['value3']}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.surName2 && afterPatch.name.surName2.length).to.eq(2); return done(); }); it('REMOVE: empty array should be unassigned', done => { scimUser.name.nestedArray = [{primary: true, value: 'value1'}]; const patch1: ScimPatchRemoveOperation = {op: 'remove', path: 'name.nestedArray[primary eq true]'}; const afterPatch = scimPatch(scimUser, [patch1]); expect(afterPatch.name.nestedArray).not.to.exist; return done(); }); it('REMOVE: with capital first letter for operation', done => { const patch: ScimPatchRemoveOperation = {op: 'Remove', path: 'active'}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch.active).not.to.exist; return done(); }); it('REMOVE: with version number in path', done => { const path = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department'; const patch: ScimPatchRemoveOperation = {op: 'remove', path: path}; const afterPatch = scimPatch(scimUser, [patch]); expect(afterPatch[path]).not.to.exist; return done(); }) }); describe('invalid requests', () => { it('INVALID: wrong operation name', done => { const patch: any = {op: 'delete', value: true, path: 'active'}; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatchRequest); return done(); }); it('INVALID: path filter invalid', done => { const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: true, path: 'emails[name eq]'}; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatch); return done(); }); it('INVALID: path request missing', done => { const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: true, path: 'emails[name eq "toto"'}; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatchOp); return done(); }); it('INVALID: search on a mono valued attribute', done => { const patch: ScimPatchAddReplaceOperation = {op: 'replace', value: true, path: 'username[name eq "toto"]'}; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatchOp); return done(); }); it('INVALID: invalid parameter in scim filter', done => { const patch: ScimPatchAddReplaceOperation = { op: 'replace', value: true, path: 'emails[\' eq true].value' }; expect(() => scimPatch(scimUser, [patch])).to.throw(InvalidScimPatchOp); return done(); }); }); });