diff --git a/src/components/Personalization/createOnClickHandler.js b/src/components/Personalization/createOnClickHandler.js index f2a0fdb1b..1063f8771 100644 --- a/src/components/Personalization/createOnClickHandler.js +++ b/src/components/Personalization/createOnClickHandler.js @@ -10,10 +10,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -import { isNonEmptyArray, isNonEmptyString } from "../../utils"; +import { isNonEmptyArray } from "../../utils"; import { INTERACT } from "./constants/eventType"; import { PropositionEventType } from "./constants/propositionEventType"; -import PAGE_WIDE_SCOPE from "../../constants/pageWideScope"; export default ({ mergeDecisionsMeta, @@ -25,7 +24,7 @@ export default ({ return ({ event, clickedElement }) => { const selectors = getClickSelectors(); if (isNonEmptyArray(selectors)) { - const { decisionsMeta, eventLabel } = collectClicks( + const { decisionsMeta, eventLabel, viewName } = collectClicks( clickedElement, selectors, getClickMetasBySelector @@ -33,12 +32,11 @@ export default ({ if (isNonEmptyArray(decisionsMeta)) { const xdm = { eventType: INTERACT }; - const scope = decisionsMeta[0].scope; - if (isNonEmptyString(scope) && scope !== PAGE_WIDE_SCOPE) { + if (viewName) { xdm.web = { webPageDetails: { - viewName: scope.toLowerCase() + viewName } }; } diff --git a/src/components/Personalization/dom-actions/clicks/collectClicks.js b/src/components/Personalization/dom-actions/clicks/collectClicks.js index 4e45b6974..ea8fceda4 100644 --- a/src/components/Personalization/dom-actions/clicks/collectClicks.js +++ b/src/components/Personalization/dom-actions/clicks/collectClicks.js @@ -24,17 +24,22 @@ const getMetasIfMatches = ( while (element && element !== documentElement) { if (matchesSelectorWithEq(selector, element)) { const matchedMetas = getClickMetasBySelector(selector); + const returnValue = { + metas: matchedMetas + }; const foundMetaWithLabel = matchedMetas.find(meta => meta.trackingLabel); if (foundMetaWithLabel) { - return { - metas: matchedMetas, - label: foundMetaWithLabel.trackingLabel, - weight: i - }; + returnValue.label = foundMetaWithLabel.trackingLabel; + returnValue.weight = i; } - return { - metas: matchedMetas - }; + const foundMetaWithScopeTypeView = matchedMetas.find( + meta => meta.scopeType === "view" + ); + if (foundMetaWithScopeTypeView) { + returnValue.viewName = foundMetaWithScopeTypeView.scope; + returnValue.weight = i; + } + return returnValue; } element = element.parentNode; @@ -48,8 +53,8 @@ const getMetasIfMatches = ( const cleanMetas = metas => metas.map(meta => { - delete meta.trackingLabel; - return meta; + const { trackingLabel, scopeType, ...rest } = meta; + return rest; }); const dedupMetas = metas => @@ -67,10 +72,12 @@ export default (clickedElement, selectors, getClickMetasBySelector) => { const result = []; let resultLabel = ""; let resultLabelWeight = Number.MAX_SAFE_INTEGER; + let resultViewName; + let resultViewNameWeight = Number.MAX_SAFE_INTEGER; /* eslint-disable no-continue */ for (let i = 0; i < selectors.length; i += 1) { - const { metas, label, weight } = getMetasIfMatches( + const { metas, label, weight, viewName } = getMetasIfMatches( clickedElement, selectors[i], getClickMetasBySelector @@ -84,11 +91,16 @@ export default (clickedElement, selectors, getClickMetasBySelector) => { resultLabel = label; resultLabelWeight = weight; } + if (viewName && weight <= resultViewNameWeight) { + resultViewName = viewName; + resultViewNameWeight = weight; + } result.push(...cleanMetas(metas)); } return { decisionsMeta: dedupMetas(result), - eventLabel: resultLabel + eventLabel: resultLabel, + viewName: resultViewName }; }; diff --git a/src/components/Personalization/handlers/createProcessDomAction.js b/src/components/Personalization/handlers/createProcessDomAction.js index dd825a16b..fe89e7888 100644 --- a/src/components/Personalization/handlers/createProcessDomAction.js +++ b/src/components/Personalization/handlers/createProcessDomAction.js @@ -22,7 +22,14 @@ export default ({ modules, logger, storeClickMetrics }) => item => { logger.warn("Invalid DOM action data: missing selector.", item.getData()); return {}; } - storeClickMetrics({ selector, meta: item.getMeta() }); + storeClickMetrics({ + selector, + meta: { + ...item.getProposition().getNotification(), + trackingLabel: item.getTrackingLabel(), + scopeType: item.getProposition().getScopeType() + } + }); return { setRenderAttempted: true, includeInNotification: false }; } diff --git a/src/components/Personalization/handlers/createProcessRedirect.js b/src/components/Personalization/handlers/createProcessRedirect.js index 4f03aa5ae..a3710958e 100644 --- a/src/components/Personalization/handlers/createProcessRedirect.js +++ b/src/components/Personalization/handlers/createProcessRedirect.js @@ -18,7 +18,9 @@ export default ({ logger, executeRedirect, collect }) => item => { } const render = () => { - return collect({ decisionsMeta: [item.getMeta()] }).then(() => { + return collect({ + decisionsMeta: [item.getProposition().getNotification()] + }).then(() => { executeRedirect(content); // We've already sent the display notification, so don't return anything }); diff --git a/src/components/Personalization/handlers/injectCreateProposition.js b/src/components/Personalization/handlers/injectCreateProposition.js index f94219d44..3c31fe4ad 100644 --- a/src/components/Personalization/handlers/injectCreateProposition.js +++ b/src/components/Personalization/handlers/injectCreateProposition.js @@ -13,15 +13,11 @@ governing permissions and limitations under the License. import PAGE_WIDE_SCOPE from "../../../constants/pageWideScope"; export default ({ preprocess, isPageWideSurface }) => { - const createItem = (item, meta) => { + const createItem = (item, proposition) => { const { schema, data, characteristics: { trackingLabel } = {} } = item; const processedData = preprocess(data); - if (trackingLabel) { - meta.trackingLabel = trackingLabel; - } - return { getSchema() { return schema; @@ -29,8 +25,11 @@ export default ({ preprocess, isPageWideSurface }) => { getData() { return processedData; }, - getMeta() { - return meta; + getProposition() { + return proposition; + }, + getTrackingLabel() { + return trackingLabel; }, getOriginalItem() { return item; @@ -65,7 +64,7 @@ export default ({ preprocess, isPageWideSurface }) => { return "proposition"; }, getItems() { - return items.map(item => createItem(item, { id, scope, scopeDetails })); + return items.map(item => createItem(item, this)); }, getNotification() { return { id, scope, scopeDetails }; diff --git a/test/functional/specs/Personalization/C9932846.js b/test/functional/specs/Personalization/C9932846.js index 6c0240598..7559198fd 100644 --- a/test/functional/specs/Personalization/C9932846.js +++ b/test/functional/specs/Personalization/C9932846.js @@ -134,4 +134,5 @@ test("Test C9932846: AJO click-tracking offers are delivered", async () => { await t .expect(interactEvent.xdm._experience.decisioning.propositions[0].id) .eql(personalizationPayload.id); + await t.expect(interactEvent.xdm.web.webPageDetails.viewName).notOk(); }); diff --git a/test/unit/specs/components/Personalization/createOnClickHandler.spec.js b/test/unit/specs/components/Personalization/createOnClickHandler.spec.js index abee75365..672221001 100644 --- a/test/unit/specs/components/Personalization/createOnClickHandler.spec.js +++ b/test/unit/specs/components/Personalization/createOnClickHandler.spec.js @@ -53,9 +53,6 @@ describe("Personalization::createOnClickHandler", () => { const expectedXdm = { eventType: "decisioning.propositionInteract", - web: { - webPageDetails: { viewName: "foo" } - }, _experience: { decisioning: { propositions: [ @@ -102,9 +99,6 @@ describe("Personalization::createOnClickHandler", () => { const expectedXdm = { eventType: "decisioning.propositionInteract", - web: { - webPageDetails: { viewName: "foo" } - }, _experience: { decisioning: { propositions: [ @@ -150,4 +144,55 @@ describe("Personalization::createOnClickHandler", () => { expect(event.mergeXdm).not.toHaveBeenCalled(); expect(collectClicks).not.toHaveBeenCalled(); }); + + it("adds a viewName to the response", () => { + const selectors = ["foo", "foo2"]; + collectClicks.and.returnValue({ + decisionsMeta, + viewName: "myview" + }); + getClickSelectors.and.returnValue(selectors); + const handleOnClick = createOnClickHandler({ + mergeDecisionsMeta, + collectClicks, + getClickSelectors, + getClickMetasBySelector + }); + const clickedElement = "foo"; + + handleOnClick({ event, clickedElement }); + + const expectedXdm = { + eventType: "decisioning.propositionInteract", + web: { + webPageDetails: { + viewName: "myview" + } + }, + _experience: { + decisioning: { + propositions: [ + { + id: 1, + scope: "foo" + } + ], + propositionEventType: { + interact: 1 + } + } + } + }; + + expect(event.mergeXdm).toHaveBeenCalledWith(expectedXdm); + expect(collectClicks).toHaveBeenCalledWith( + clickedElement, + selectors, + getClickMetasBySelector + ); + event.finalize(); + expect(event.toJSON()).toEqual({ + xdm: expectedXdm + }); + }); }); diff --git a/test/unit/specs/components/Personalization/handlers/createProcessDomAction.spec.js b/test/unit/specs/components/Personalization/handlers/createProcessDomAction.spec.js index ffaaa2170..528388432 100644 --- a/test/unit/specs/components/Personalization/handlers/createProcessDomAction.spec.js +++ b/test/unit/specs/components/Personalization/handlers/createProcessDomAction.spec.js @@ -3,19 +3,33 @@ import createProcessDomAction from "../../../../../../src/components/Personaliza describe("createProcessDomAction", () => { let item; let data; + let proposition; let meta; + let trackingLabel; + let scopeType; let modules; let logger; let storeClickMetrics; let processDomAction; beforeEach(() => { + proposition = { + getNotification() { + return meta; + }, + getScopeType() { + return scopeType; + } + }; item = { getData() { return data; }, - getMeta() { - return meta; + getProposition() { + return proposition; + }, + getTrackingLabel() { + return trackingLabel; } }; modules = { @@ -74,14 +88,21 @@ describe("createProcessDomAction", () => { it("handles a click type", () => { data = { type: "click", selector: ".selector" }; - meta = "mymetavalue"; + meta = { id: "myid", scope: "myscope" }; + trackingLabel = "mytrackinglabel"; + scopeType = "myscopetype"; expect(processDomAction(item)).toEqual({ setRenderAttempted: true, includeInNotification: false }); expect(storeClickMetrics).toHaveBeenCalledWith({ selector: ".selector", - meta: "mymetavalue" + meta: { + id: "myid", + scope: "myscope", + trackingLabel: "mytrackinglabel", + scopeType: "myscopetype" + } }); }); diff --git a/test/unit/specs/components/Personalization/handlers/createProcessPropositions.spec.js b/test/unit/specs/components/Personalization/handlers/createProcessPropositions.spec.js index 10c726577..0a8985397 100644 --- a/test/unit/specs/components/Personalization/handlers/createProcessPropositions.spec.js +++ b/test/unit/specs/components/Personalization/handlers/createProcessPropositions.spec.js @@ -43,7 +43,10 @@ describe("createProcessPropositions", () => { schemaProcessors, logger }); - createProposition = injectCreateProposition({ preprocess: data => data }); + createProposition = injectCreateProposition({ + preprocess: data => data, + isPageWideSurface: () => false + }); }); it("handles no propositions", async () => { diff --git a/test/unit/specs/components/Personalization/handlers/createProcessRedirect.spec.js b/test/unit/specs/components/Personalization/handlers/createProcessRedirect.spec.js index f69b91f7d..b7fe65ebe 100644 --- a/test/unit/specs/components/Personalization/handlers/createProcessRedirect.spec.js +++ b/test/unit/specs/components/Personalization/handlers/createProcessRedirect.spec.js @@ -9,6 +9,7 @@ describe("createProcessRedirect", () => { let collectDefer; let item; let data; + let proposition; let meta; let processRedirect; @@ -20,12 +21,17 @@ describe("createProcessRedirect", () => { collect = jasmine .createSpy("collect") .and.returnValue(collectDefer.promise); + proposition = { + getNotification() { + return meta; + } + }; item = { getData() { return data; }, - getMeta() { - return meta; + getProposition() { + return proposition; } }; diff --git a/test/unit/specs/components/Personalization/handlers/injectCreateProposition.spec.js b/test/unit/specs/components/Personalization/handlers/injectCreateProposition.spec.js index 6266137f0..682870cf9 100644 --- a/test/unit/specs/components/Personalization/handlers/injectCreateProposition.spec.js +++ b/test/unit/specs/components/Personalization/handlers/injectCreateProposition.spec.js @@ -41,12 +41,8 @@ describe("injectCreateProposition", () => { const item = proposition.getItems()[0]; expect(item.getSchema()).toEqual("schema"); expect(item.getData()).toEqual("preprocessed data"); - expect(item.getMeta()).toEqual({ - id: "id", - scope: "scope", - scopeDetails: { characteristics: { scopeType: "view" } }, - trackingLabel: "trackingLabel" - }); + expect(item.getProposition()).toEqual(proposition); + expect(item.getTrackingLabel()).toEqual("trackingLabel"); expect(item.getOriginalItem()).toEqual({ schema: "schema", data: "data",