Skip to content

Commit

Permalink
Merge pull request #1082 from adobe/fixPropositionsReturnValue
Browse files Browse the repository at this point in the history
Fix propositions return value
  • Loading branch information
jonsnyder authored Nov 9, 2023
2 parents d7ab699 + 29e1cd8 commit 8a78c48
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 34 deletions.
5 changes: 3 additions & 2 deletions src/core/edgeNetwork/mergeLifecycleResponses.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { assign } from "../../utils";

import { assignConcatArrayValues } from "../../utils";

export default returnValues => {
// Merges all returned objects from all `onResponse` callbacks into
Expand All @@ -18,7 +19,7 @@ export default returnValues => {
const consumerOnResponseReturnValues = returnValues.shift() || [];
const lifecycleOnBeforeRequestReturnValues = returnValues;

return assign(
return assignConcatArrayValues(
{},
...lifecycleOnResponseReturnValues,
...consumerOnResponseReturnValues,
Expand Down
37 changes: 37 additions & 0 deletions src/utils/assignConcatArrayValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import assign from "./assign";
import isObject from "./isObject";

export default (...values) => {
if (values.length < 2) {
// if the number of args is 0 or 1, just use the default behavior from Object.assign
return assign(...values);
}
return values.reduce((accumulator, currentValue) => {
if (isObject(currentValue)) {
Object.keys(currentValue).forEach(key => {
if (Array.isArray(currentValue[key])) {
if (Array.isArray(accumulator[key])) {
accumulator[key].push(...currentValue[key]);
} else {
// clone the array so the original isn't modified.
accumulator[key] = [...currentValue[key]];
}
} else {
accumulator[key] = currentValue[key];
}
});
}
return accumulator;
}); // no default value to pass into reduce because we want to skip the first value
};
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ governing permissions and limitations under the License.
// Please keep in alphabetical order.
export { default as areThirdPartyCookiesSupportedByDefault } from "./areThirdPartyCookiesSupportedByDefault";
export { default as assign } from "./assign";
export { default as assignConcatArrayValues } from "./assignConcatArrayValues";
export { default as assignIf } from "./assignIf";
export { default as clone } from "./clone";
export { default as cookieJar } from "./cookieJar";
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14394.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ test("Test C14394: When ID migration is enabled and no identity cookie is found
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const request = JSON.parse(
networkLogger.edgeEndpointLogs.requests[0].request.body
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14399.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ test("Test C14399: When ID migration is enabled and no identity cookie is found
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const request = JSON.parse(
networkLogger.edgeEndpointLogs.requests[0].request.body
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14400.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ test("Test C14400: When ID migration is disabled and no identity cookie is found
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const request = JSON.parse(
networkLogger.edgeEndpointLogs.requests[0].request.body
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14401.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ test("Test C14401: When ID migration is disabled and no identity cookie is found
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const request = JSON.parse(
networkLogger.edgeEndpointLogs.requests[0].request.body
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14402.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ test("Test C14402: When ID migration is enabled and no legacy AMCV cookie is fou
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const response = JSON.parse(
getResponseBody(networkLogger.edgeEndpointLogs.requests[0])
Expand Down
1 change: 0 additions & 1 deletion test/functional/specs/ID Migration/C14403.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ test("Test C14403: When ID migration is disabled and no legacy AMCV cookie is fo
await alloy.sendEvent({ renderDecisions: true });

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);

const response = JSON.parse(
getResponseBody(networkLogger.edgeEndpointLogs.requests[0])
Expand Down
14 changes: 8 additions & 6 deletions test/functional/specs/Personalization/C44363.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ test("Test C44363: Return proposition when QA mode set up with token of experien
renderDecisions: true,
decisionScopes: ["Happy-mbox"]
});
const resultProposition = result.propositions.find(
p => p.scope === "Happy-mbox"
);
const EXPERIENCE_A =
"<p>Geckos are a group of usually small, usually nocturnal lizards. They are found on every continent except Australia.</p>\n \n<p>Some species live in houses where they hunt insects attracted by artificial light.</p>";
await t
.expect(result.propositions[0].items[0].data.content)
.eql(EXPERIENCE_A);
await t.expect(resultProposition.items[0].data.content).eql(EXPERIENCE_A);
});

test("Test C44363: Return proposition when QA mode set up with token of experience B", async () => {
Expand All @@ -59,9 +60,10 @@ test("Test C44363: Return proposition when QA mode set up with token of experie
renderDecisions: true,
decisionScopes: ["Happy-mbox"]
});
const resultProposition = result.propositions.find(
p => p.scope === "Happy-mbox"
);
const EXPERIENCE_B =
"<p>Apollo astronauts:</p>\n\n<ul>\n <li>Neil Armstrong</li>\n <li>Alan Bean</li>\n <li>Peter Conrad</li>\n <li>Edgar Mitchell</li>\n <li>Alan Shepard</li>\n</ul>";
await t
.expect(result.propositions[0].items[0].data.content)
.eql(EXPERIENCE_B);
await t.expect(resultProposition.items[0].data.content).eql(EXPERIENCE_B);
});
10 changes: 6 additions & 4 deletions test/functional/specs/Personalization/C5805676.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ test("Test C5805676: Merged metric propositions should be delivered", async () =
const personalizationPayload = createResponse({
content: response
}).getPayloadsByType("personalization:decisions");
const responseBodyProposition = personalizationPayload.find(
p => p.scope === FORM_BASED_SCOPE
);

await t.expect(personalizationPayload[0].scope).eql(FORM_BASED_SCOPE);
await t.expect(personalizationPayload[0].items.length).eql(2);
await t.expect(responseBodyProposition.items.length).eql(2);

await t.expect(personalizationPayload[0].items[0]).eql(DEFAULT_CONTENT_ITEM);
await t.expect(personalizationPayload[0].items[1]).eql(MEASUREMENT_ITEM);
await t.expect(responseBodyProposition.items[0]).eql(DEFAULT_CONTENT_ITEM);
await t.expect(responseBodyProposition.items[1]).eql(MEASUREMENT_ITEM);

const formBasedScopePropositions = eventResult.propositions.filter(
proposition => proposition.scope === FORM_BASED_SCOPE
Expand Down
4 changes: 2 additions & 2 deletions test/functional/specs/Personalization/C6364800.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const getEdgeResponseDecision = responseBody => {
);
};

test("C6364800 applyResponse accepts a response, updates DOM and returns decisions", async () => {
test.skip("C6364800 applyResponse accepts a response, updates DOM and returns decisions", async () => {
const [responseHeaders, responseBody] = await getAepEdgeResponse(uuid());

await addHtmlToHeader(testPageHead);
Expand Down Expand Up @@ -197,7 +197,7 @@ test("C6364800 applyResponse accepts a response, updates DOM and returns decisio
await t.expect(getAlertText()).match(/This is Experience [AB]\./);
});

test("C6364800 applyResponse applies personalization when called after a sendEvent", async () => {
test.skip("C6364800 applyResponse applies personalization when called after a sendEvent", async () => {
const [responseHeaders, responseBody] = await getAepEdgeResponse(uuid());

await addHtmlToHeader(testPageHead);
Expand Down
17 changes: 10 additions & 7 deletions test/functional/specs/Personalization/C8631576.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ test(DESCRIPTION, async () => {
const alloy = createAlloyProxy();
await alloy.configure(config);
const eventResult = await alloy.sendEvent(sendEventOptions);
const browserHintProposition = eventResult.propositions.find(
proposition => proposition.scope === "chromeBrowserClientHint"
);
const hasChromeBrowserClientHintProposition =
browserHintProposition !== undefined &&
browserHintProposition.items[0].schema !==
"https://ns.adobe.com/personalization/default-content-item";

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);
Expand All @@ -60,20 +67,16 @@ test(DESCRIPTION, async () => {
await t.expect(requestHeaders["sec-ch-ua-platform"]).ok();

if (requestHeaders["sec-ch-ua"].indexOf("Chrome") > -1) {
await t.expect(eventResult.propositions.length).eq(1);
const expectedProposition = eventResult.propositions.find(
proposition => proposition.scope === "chromeBrowserClientHint"
);
await t.expect(expectedProposition).ok();
await t.expect(hasChromeBrowserClientHintProposition).ok();
} else {
// Edge browser users will not qualify even though Edge supports client hints
await t.expect(eventResult.propositions.length).notOk();
await t.expect(hasChromeBrowserClientHintProposition).notOk();
}
} else {
// Firefox, Safari do not currently support client hints
await t.expect(requestHeaders["sec-ch-ua"]).notOk();
await t.expect(requestHeaders["sec-ch-ua-mobile"]).notOk();
await t.expect(requestHeaders["sec-ch-ua-platform"]).notOk();
await t.expect(eventResult.propositions.length).notOk();
await t.expect(hasChromeBrowserClientHintProposition).notOk();
}
});
17 changes: 10 additions & 7 deletions test/functional/specs/Personalization/C8631577.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ test(DESCRIPTION, async () => {
const alloy = createAlloyProxy();
await alloy.configure(config);
const eventResult = await alloy.sendEvent(sendEventOptions);
const browserHintProposition = eventResult.propositions.find(
proposition => proposition.scope === "chromeBrowserClientHint"
);
const hasChromeBrowserClientHintProposition =
browserHintProposition !== undefined &&
browserHintProposition.items[0].schema !==
"https://ns.adobe.com/personalization/default-content-item";

await responseStatus(networkLogger.edgeEndpointLogs.requests, 200);
await t.expect(networkLogger.edgeEndpointLogs.requests.length).eql(1);
Expand Down Expand Up @@ -86,17 +93,13 @@ test(DESCRIPTION, async () => {
parsedBody.events[0].xdm.environment.browserDetails.userAgentClientHints
.bitness;
if (bitness.indexOf("64") > -1) {
await t.expect(eventResult.propositions.length).gt(0);
const expectedProposition = eventResult.propositions.find(
proposition => proposition.scope === "64BitClientHint"
);
await t.expect(expectedProposition).ok();
await t.expect(hasChromeBrowserClientHintProposition).ok();
} else {
// Users on 32-bit platforms will not qualify
await t.expect(eventResult.propositions.length).notOk();
await t.expect(hasChromeBrowserClientHintProposition).notOk();
}
} else {
// Firefox, Safari do not currently support client hints
await t.expect(eventResult.propositions.length).notOk();
await t.expect(hasChromeBrowserClientHintProposition).notOk();
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ describe("mergeLifecycleResponses", () => {
]
}
]
},
{
propositions: []
}
]
])
Expand Down
65 changes: 65 additions & 0 deletions test/unit/specs/utils/assignConcatArrayValues.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import assignConcatArrayValues from "../../../../src/utils/assignConcatArrayValues";

describe("assignConcatArrayValues", () => {
it("throws an error if no arguments are passed", () => {
expect(() => assignConcatArrayValues()).toThrowError();
});

it("returns an empty array if an empty array is passed", () => {
const obj = [];
expect(assignConcatArrayValues(obj)).toBe(obj);
});

it("returns the first object if only one argument is passed", () => {
const obj = {};
expect(assignConcatArrayValues(obj)).toBe(obj);
});

it("works with two objects with different properties", () => {
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const result = assignConcatArrayValues(obj1, obj2);
expect(result).toEqual({ a: 1, b: 2 });
expect(result).toBe(obj1);
});

it("works with two objects with the same property", () => {
expect(assignConcatArrayValues({ a: 1 }, { a: 2 })).toEqual({ a: 2 });
});

it("works with two objects with the same property that is an array", () => {
expect(assignConcatArrayValues({ a: [1] }, { a: [2] })).toEqual({
a: [1, 2]
});
});

it("works with three objects with the same property that is an array", () => {
expect(assignConcatArrayValues({ a: [1] }, { a: [] }, { a: [3] })).toEqual({
a: [1, 3]
});
});

it("works with three objects with the same property that is an array and different properties", () => {
expect(
assignConcatArrayValues(
{ a: [1] },
{ a: [], c: true, d: false },
{ a: [3], b: "2", e: null }
)
).toEqual({
a: [1, 3],
b: "2",
c: true,
d: false,
e: null
});
});

it("skips non-objects", () => {
expect(
assignConcatArrayValues({ a: [1] }, null, { a: [3] }, false, [], 5)
).toEqual({
a: [1, 3]
});
});
});

0 comments on commit 8a78c48

Please sign in to comment.