Skip to content

Commit

Permalink
Fix #74 (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaspoignant authored Jan 28, 2021
1 parent b037a5f commit 70b3424
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scim-patch",
"version": "0.4.2",
"version": "0.4.3",
"description": "SCIM Patch operation (rfc7644).",
"main": "lib/src/scimPatch.js",
"types": "lib/src/scimPatch.d.ts",
Expand Down
8 changes: 4 additions & 4 deletions src/scimPatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,12 @@ function applyAddOrReplaceOperation<T extends ScimResource>(scimResource: T, pat
// Get the list of items who are successful for the search query.
const matchFilter = filterWithQuery<any>(array, valuePath);

// If the target location specifies a complex attribute, a set of sub-attributes SHALL be specified in the "value"
// parameter, which replaces any existing values or adds where an attribute did not previously exist.
// If the target location is a multi-valued attribute for which a value selection filter ("valuePath") has been
// supplied and no record match was made, the service provider SHALL indicate failure by returning HTTP status
// code 400 and a "scimType" error code of "noTarget".
const isReplace = patch.op.toLowerCase() === 'replace';
if (isReplace && matchFilter.length === 0) {
array.push(patch.value);
return scimResource;
throw new NoTarget(patch.value)
}

// We are sure to find an index because matchFilter comes from array.
Expand Down
62 changes: 35 additions & 27 deletions test/scimPatch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,14 @@ describe('SCIM PATCH', () => {
});

it('REPLACE: nested object do not exists', done => {
scimUser.surName = [{value: 'toto', primary: true}];
const expected = '[email protected]';
const patch1: ScimPatchAddReplaceOperation = {
// empty the surName fields.
scimUser.surName = [];
const patch: ScimPatchAddReplaceOperation = {
op: 'replace',
value: {value: expected, primary: false},
path: 'surName[primary eq false]'
path: 'surName[value eq "bogus"]',
value: 'this value should not be added',
};
const afterPatch = scimPatch(scimUser, [patch1]);
expect(afterPatch.surName?.length).to.be.eq(2);
expect(() => scimPatch(scimUser, [patch])).to.throw(NoTarget);
return done();
});

Expand Down Expand Up @@ -185,26 +184,6 @@ describe('SCIM PATCH', () => {
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}};
Expand Down Expand Up @@ -251,6 +230,35 @@ describe('SCIM PATCH', () => {
return done();
});

it("REPLACE: replace add fields in complex object", (done) => {
const expected = [ {primary: true, value: "bogus", additional:"additional"} ];
// empty the surName fields.
scimUser.surName = [{primary: true, value: "bogus"}];
const patch: ScimPatchAddReplaceOperation = {
op: 'replace',
path: 'surName[value eq "bogus"]',
value: {additional:"additional"},
};

const afterPatch = scimPatch(scimUser, [patch]);
expect(afterPatch.surName).to.be.deep.eq(expected);
return done();
});

it("REPLACE: replace add and update fields in complex object", (done) => {
const expected = [ {primary: true, value: "bogus2", additional:"additional"} ];
// empty the surName fields.
scimUser.surName = [{primary: true, value: "bogus"}];
const patch: ScimPatchAddReplaceOperation = {
op: 'replace',
path: 'surName[value eq "bogus"]',
value: {additional:"additional", value: "bogus2"},
};

const afterPatch = scimPatch(scimUser, [patch]);
expect(afterPatch.surName).to.be.deep.eq(expected);
return done();
});
});

describe('add', () => {
Expand Down
1 change: 1 addition & 0 deletions test/types/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface ScimUser extends ScimResource {
surName?: Array<{
value: string;
primary: boolean;
additional?: string;
}>;
name: {
familyName: string;
Expand Down

0 comments on commit 70b3424

Please sign in to comment.