Skip to content

Commit

Permalink
Merge pull request #62 from scimmyjs/issue/61-complex-multivalue-pres…
Browse files Browse the repository at this point in the history
…ence-filter

Fix presence filtering of complex multi-value attributes in `SCIMMY.Types.SchemaDefinition`
  • Loading branch information
sleelin authored Dec 11, 2024
2 parents b061460 + 8115cae commit 9717db4
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
9 changes: 6 additions & 3 deletions src/lib/types/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,14 @@ export class SchemaDefinition {
// If the attribute is always returned, add it to the result
if (returned === "always") target[key] = data[key];
// Otherwise, if the attribute was requested and ~can~ be returned, process it
else if (![false, "never"].includes(returned)) {
else if (![false, "never"].includes(returned) && !exclusions.includes(key)) {
// If there's a filter for a complex attribute, evaluate it...
if (key in filter && type === "complex") {
// ...either using Filter instance match method, or by recursing into this filter method to get specified attributes
const value = Array.isArray(filter[key]) ? new Filter(filter[key].filter((expr) => Object.getPrototypeOf(expr).constructor === Object)).match(data[key]) : SchemaDefinition.#filter(definition, filter[key], data[key], key);
const value = Array.isArray(filter[key]) ? !filter[key].some((expr) => typeof expr === "object") ? data[key] :
// ...either using Filter instance match method for complex expressions...
new Filter(filter[key].filter((expr) => Object.getPrototypeOf(expr).constructor === Object)).match(data[key]) :
// ...or by recursing into this filter method to get specified attributes
SchemaDefinition.#filter(definition, filter[key], data[key], key);

// Only set the value if it isn't empty
if ((!multiValued && value !== undefined) || (Array.isArray(value) && value.length))
Expand Down
6 changes: 4 additions & 2 deletions test/lib/types/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,10 @@ describe("SCIMMY.Types.SchemaDefinition", () => {
for (let [target, outcome, unexpected, expected, filter, multiValued] of [
["complex attributes", "filtered positively", "unexpectedly included", {test: {value: "False"}}, "test.value pr"],
["complex attributes", "filtered negatively", "unexpectedly excluded", {test: {name: "Test"}}, "test.value np"],
["complex multi-value attributes", "filtered positively", "unexpectedly included", {test: [{name: "Test"}]}, "test.name pr", true],
["complex multi-value attributes", "filtered negatively", "unexpectedly excluded", {test: [{value: "Test"}, {value: "False"}]}, "test.name np", true],
["complex multi-value attributes", "filtered positively", "unexpectedly included", {test: [{name: "Test", value: "Test"}, {name: undefined, value: "False"}]}, "test pr", true],
["complex multi-value attributes", "filtered negatively", "unexpectedly excluded", {}, "test np", true],
["nested complex multi-value attributes", "filtered positively", "unexpectedly included", {test: [{name: "Test"}]}, "test.name pr", true],
["nested complex multi-value attributes", "filtered negatively", "unexpectedly excluded", {test: [{value: "Test"}, {value: "False"}]}, "test.name np", true],
["complex multi-value attributes", "matched against filter expressions", "unexpectedly excluded", {test: [{name: "Test", value: "Test"}]}, "test[name eq \"Test\"] pr", true]
]) it(`should expect ${target} to be ${outcome}`, () => {
const source = {test: multiValued ? [{name: "Test", value: "Test"}, {value: "False"}] : {name: "Test", value: "False"}};
Expand Down

0 comments on commit 9717db4

Please sign in to comment.