From e3a129cd409344715721200144e3223cf742f1a9 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Fri, 15 Sep 2023 11:30:23 -0700 Subject: [PATCH 01/27] new branch for indexedDB storage --- src/components/DecisioningEngine/createEventRegistry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 84c158a43..819621434 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -72,7 +72,7 @@ export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { timestamp, count: count + 1 }; - + // TODO: save to indexedDB save(events); return events[eventType][eventId]; From c9d72175c79660cd9d75c2e20a68ae9691b5837a Mon Sep 17 00:00:00 2001 From: Jason Waters Date: Fri, 15 Sep 2023 12:50:56 -0600 Subject: [PATCH 02/27] CJM-53824 --- .../InAppMessagesDemo/InAppMessages.js | 2 +- .../createDecisionHistory.js | 4 +- .../DecisioningEngine/createEventRegistry.js | 86 +++--- src/components/Personalization/event.js | 2 +- .../createEventRegistry.spec.js | 262 +++++------------- 5 files changed, 121 insertions(+), 235 deletions(-) diff --git a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js index e49687823..01f8d9283 100644 --- a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js +++ b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js @@ -3,7 +3,7 @@ import React from "react"; import ContentSecurityPolicy from "../ContentSecurityPolicy"; import "./InAppMessagesStyle.css"; -const configKey = "cjmProdNld2"; +const configKey = "aemonacpprodcampaign"; const config = { cjmProdNld2: { diff --git a/src/components/DecisioningEngine/createDecisionHistory.js b/src/components/DecisioningEngine/createDecisionHistory.js index 85bb5e4d2..82948cda8 100644 --- a/src/components/DecisioningEngine/createDecisionHistory.js +++ b/src/components/DecisioningEngine/createDecisionHistory.js @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const QUALIFIED_EVENT_TYPE = "decisioning.propositionQualified"; +import { PropositionEventType } from "../Personalization/constants/propositionEventType"; export default ({ eventRegistry }) => { const recordQualified = item => { @@ -18,7 +18,7 @@ export default ({ eventRegistry }) => { if (!id) { return undefined; } - return eventRegistry.addEvent(item, QUALIFIED_EVENT_TYPE, id); + return eventRegistry.addEvent({}, PropositionEventType.TRIGGER, id); }; return { recordQualified }; diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 819621434..dbbe28e72 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -9,51 +9,28 @@ 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 { - createRestoreStorage, - createSaveStorage, - getExpirationDate -} from "./utils"; +import { createRestoreStorage, createSaveStorage } from "./utils"; +import { EVENT_TYPE_TRUE } from "../Personalization/event"; const STORAGE_KEY = "events"; -const MAX_EVENT_RECORDS = 1000; const DEFAULT_SAVE_DELAY = 500; -const RETENTION_PERIOD = 30; - -export const createEventPruner = ( - limit = MAX_EVENT_RECORDS, - retentionPeriod = RETENTION_PERIOD -) => { - return events => { - const pruned = {}; - Object.keys(events).forEach(eventType => { - pruned[eventType] = {}; - Object.values(events[eventType]) - .filter( - entry => - new Date(entry.firstTimestamp) >= getExpirationDate(retentionPeriod) - ) - .sort((a, b) => a.firstTimestamp - b.firstTimestamp) - .slice(-1 * limit) - .forEach(entry => { - pruned[eventType][entry.event.id] = entry; - }); - }); - return pruned; - }; + +const prefixed = key => `iam.${key}`; + +const getActivityId = proposition => { + const { scopeDetails = {} } = proposition; + const { activity = {} } = scopeDetails; + const { id } = activity; + + return id; }; export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { const restore = createRestoreStorage(storage, STORAGE_KEY); - const save = createSaveStorage( - storage, - STORAGE_KEY, - saveDelay, - createEventPruner(MAX_EVENT_RECORDS, RETENTION_PERIOD) - ); + const save = createSaveStorage(storage, STORAGE_KEY, saveDelay); const events = restore({}); - const addEvent = (event, eventType, eventId) => { + const addEvent = (event, eventType, eventId, action) => { if (!events[eventType]) { events[eventType] = {}; } @@ -67,7 +44,12 @@ export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { : timestamp; events[eventType][eventId] = { - event: { ...event, id: eventId, type: eventType }, + event: { + ...event, + [prefixed("id")]: eventId, + [prefixed("eventType")]: eventType, + [prefixed("action")]: action + }, firstTimestamp, timestamp, count: count + 1 @@ -92,11 +74,33 @@ export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { } const { decisioning = {} } = _experience; - const { propositions = [] } = decisioning; + const { + propositionEventType: propositionEventTypeObj = {}, + propositionAction = {}, + propositions = [] + } = decisioning; + + const propositionEventTypesList = Object.keys(propositionEventTypeObj); - propositions.forEach(proposition => - addEvent({ proposition }, eventType, proposition.id) - ); + // https://wiki.corp.adobe.com/pages/viewpage.action?spaceKey=CJM&title=Proposition+Event+Types + if (propositionEventTypesList.length === 0) { + return; + } + + const { id: action } = propositionAction; + + propositionEventTypesList.forEach(propositionEventType => { + if (propositionEventTypeObj[propositionEventType] === EVENT_TYPE_TRUE) { + propositions.forEach(proposition => { + addEvent( + {}, + propositionEventType, + getActivityId(proposition), + action + ); + }); + } + }); }; const getEvent = (eventType, eventId) => { if (!events[eventType]) { diff --git a/src/components/Personalization/event.js b/src/components/Personalization/event.js index fe7e565fe..6647536a9 100644 --- a/src/components/Personalization/event.js +++ b/src/components/Personalization/event.js @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const EVENT_TYPE_TRUE = 1; +export const EVENT_TYPE_TRUE = 1; /* eslint-disable no-underscore-dangle */ export const mergeDecisionsMeta = ( diff --git a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js index 1f268031c..29fb14786 100644 --- a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js @@ -9,9 +9,7 @@ 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 createEventRegistry, { - createEventPruner -} from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; describe("DecisioningEngine:createEventRegistry", () => { let storage; @@ -32,10 +30,36 @@ describe("DecisioningEngine:createEventRegistry", () => { const getContent = () => ({ xdm: { - eventType: "display", + eventType: "decisioning.propositionDisplay", _experience: { decisioning: { - propositions: [{ id: "abc" }, { id: "def" }, { id: "ghi" }] + propositions: [ + { + id: "111", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "ccaa539e-ca14-4d42-ac9a-0a17e69a63e4", + activity: { + id: "111#aaa" + } + } + }, + { + id: "222", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "ccaa539e-ca14-4d42-ac9a-0a17e69a63e4", + activity: { + id: "222#bbb" + } + } + } + ], + propositionEventType: { + display: 1 + } } } } @@ -49,20 +73,20 @@ describe("DecisioningEngine:createEventRegistry", () => { expect(eventRegistry.toJSON()).toEqual({ display: { - abc: { - event: jasmine.objectContaining({ id: "abc", type: "display" }), + "111#aaa": { + event: jasmine.objectContaining({ + "iam.id": "111#aaa", + "iam.eventType": "display" + }), firstTimestamp: jasmine.any(Number), timestamp: jasmine.any(Number), count: 1 }, - def: { - event: jasmine.objectContaining({ id: "def", type: "display" }), - firstTimestamp: jasmine.any(Number), - timestamp: jasmine.any(Number), - count: 1 - }, - ghi: { - event: jasmine.objectContaining({ id: "ghi", type: "display" }), + "222#bbb": { + event: jasmine.objectContaining({ + "iam.id": "222#bbb", + "iam.eventType": "display" + }), firstTimestamp: jasmine.any(Number), timestamp: jasmine.any(Number), count: 1 @@ -111,10 +135,25 @@ describe("DecisioningEngine:createEventRegistry", () => { const getContent = () => ({ xdm: { - eventType: "display", + eventType: "decisioning.propositionDisplay", _experience: { decisioning: { - propositions: [{ id: "abc" }] + propositions: [ + { + id: "111", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "ccaa539e-ca14-4d42-ac9a-0a17e69a63e4", + activity: { + id: "111#aaa" + } + } + } + ], + propositionEventType: { + display: 1 + } } } } @@ -126,196 +165,39 @@ describe("DecisioningEngine:createEventRegistry", () => { let lastEventTime = 0; eventRegistry.addExperienceEdgeEvent(event); - expect(eventRegistry.getEvent("display", "abc")).toEqual({ - event: jasmine.objectContaining({ id: "abc", type: "display" }), + expect(eventRegistry.getEvent("display", "111#aaa")).toEqual({ + event: jasmine.objectContaining({ + "iam.id": "111#aaa", + "iam.eventType": "display" + }), firstTimestamp: jasmine.any(Number), timestamp: jasmine.any(Number), count: 1 }); - expect(eventRegistry.getEvent("display", "abc").timestamp).toBeGreaterThan( - lastEventTime - ); - lastEventTime = eventRegistry.getEvent("display", "abc").timestamp; + expect( + eventRegistry.getEvent("display", "111#aaa").timestamp + ).toBeGreaterThan(lastEventTime); + + lastEventTime = eventRegistry.getEvent("display", "111#aaa").timestamp; setTimeout(() => { eventRegistry.addExperienceEdgeEvent(event); // again - expect(eventRegistry.getEvent("display", "abc")).toEqual({ - event: jasmine.objectContaining({ id: "abc", type: "display" }), + expect(eventRegistry.getEvent("display", "111#aaa")).toEqual({ + event: jasmine.objectContaining({ + "iam.id": "111#aaa", + "iam.eventType": "display" + }), firstTimestamp: jasmine.any(Number), timestamp: jasmine.any(Number), count: 2 }); expect( - eventRegistry.getEvent("display", "abc").timestamp + eventRegistry.getEvent("display", "111#aaa").timestamp ).toBeGreaterThan(lastEventTime); done(); }, 50); jasmine.clock().tick(60); }); - - it("limits events to 1000 events", () => { - const prune = createEventPruner(); - const events = {}; - events["decisioning.propositionDisplay"] = {}; - events["decisioning.propositionInteract"] = {}; - - for (let i = 0; i < 2000; i += 1) { - events["decisioning.propositionDisplay"][i] = { - event: { - id: i, - type: "decisioning.propositionDisplay" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - }; - - events["decisioning.propositionInteract"][i] = { - event: { - id: i, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - }; - - const pruned = prune(events); - const interactEvents = Object.values( - pruned["decisioning.propositionInteract"] - ); - - const displayEvents = Object.values( - pruned["decisioning.propositionDisplay"] - ); - expect(interactEvents.length).not.toBeGreaterThan(1000); - expect(displayEvents.length).not.toBeGreaterThan(1000); - - if (i > 1000) { - expect(interactEvents[0].event.id).toEqual(i - 999); - expect(displayEvents[0].event.id).toEqual(i - 999); - } - - if (i > 0) { - expect( - interactEvents[0].timestamp < - interactEvents[interactEvents.length - 1].timestamp - ); - expect( - displayEvents[0].timestamp < - displayEvents[interactEvents.length - 1].timestamp - ); - } - } - }); - - it("has configurable limits", () => { - const prune = createEventPruner(10); - - const events = {}; - events["decisioning.propositionDisplay"] = {}; - - for (let i = 0; i < 20; i += 1) { - events["decisioning.propositionDisplay"][i] = { - event: { - id: i, - type: "decisioning.propositionDisplay" - }, - firstTimestamp: 1, - timestamp: 1, - count: 1 - }; - - const pruned = prune(events); - - const displayEvents = Object.values( - pruned["decisioning.propositionDisplay"] - ); - - expect(displayEvents.length).not.toBeGreaterThan(10); - } - }); - - it("should filter events based on expiration date", () => { - const pruner = createEventPruner(4, 2); - - const events = {}; - events["decisioning.propositionDisplay"] = { - 1: { - event: { - id: 1, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-20T10:00:00Z", - timestamp: mockedTimestamp, - count: 1 - }, - 2: { - event: { - id: 2, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-24T15:00:00Z", - timestamp: mockedTimestamp, - count: 1 - } - }; - events["decisioning.propositionInteract"] = { - 3: { - event: { - id: 3, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - }, - 4: { - event: { - id: 4, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - } - }; - - const prunedEvents = pruner(events); - expect(prunedEvents).toEqual({ - "decisioning.propositionDisplay": { - 2: { - event: { - id: 2, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-24T15:00:00Z", - timestamp: mockedTimestamp, - count: 1 - } - }, - "decisioning.propositionInteract": { - 3: { - event: { - id: 3, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - }, - 4: { - event: { - id: 4, - type: "decisioning.propositionInteract" - }, - firstTimestamp: "2023-05-23T08:00:00Z", - timestamp: mockedTimestamp, - count: 1 - } - } - }); - }); }); From 7bd4b211fc61ace084a8ad122522a01e0803a2db Mon Sep 17 00:00:00 2001 From: Jason Waters Date: Wed, 20 Sep 2023 16:47:42 -0600 Subject: [PATCH 03/27] fix message feed ids and conditions --- .../src/components/MessageFeedDemo/MessageFeed.js | 14 +++++++------- .../DecisioningEngine/createDecisionHistory.js | 3 +-- .../createEvaluableRulesetPayload.js | 4 +++- .../DecisioningEngine/createEventRegistry.js | 14 +++++--------- src/components/DecisioningEngine/utils.js | 8 ++++++++ 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/sandbox/src/components/MessageFeedDemo/MessageFeed.js b/sandbox/src/components/MessageFeedDemo/MessageFeed.js index 1aef05a1d..eea940f37 100644 --- a/sandbox/src/components/MessageFeedDemo/MessageFeed.js +++ b/sandbox/src/components/MessageFeedDemo/MessageFeed.js @@ -34,7 +34,7 @@ const mockResponse = { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "8e24e51d-5203-4d0b-99c9-2b3c95ff48f2#05885219-ea84-43bc-874e-1ef4a85b6fbb" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, @@ -148,7 +148,7 @@ const mockResponse = { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "cf087a6e-131d-4147-adc7-bc1ea947f09c#ff64e6e6-e43f-479d-b5c0-f5568c771b3b" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, @@ -179,9 +179,9 @@ const mockResponse = { definition: { events: [ { - type: "decisioning.propositionDisplay", + type: "display", id: - "1ae11bc5-96dc-41c7-8f71-157c57a5290e" + "cf087a6e-131d-4147-adc7-bc1ea947f09c#ff64e6e6-e43f-479d-b5c0-f5568c771b3b" } ], matcher: "ge", @@ -251,7 +251,7 @@ const mockResponse = { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "57712381-1690-4d19-9469-0a35ea5bd4e3#74f8e5cf-d770-41c3-b595-557b3ee00ba3" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, @@ -282,9 +282,9 @@ const mockResponse = { definition: { events: [ { - type: "decisioning.propositionDisplay", + type: "trigger", id: - "d1f7d411-a549-47bc-a4d8-c8e638b0a46b" + "57712381-1690-4d19-9469-0a35ea5bd4e3#74f8e5cf-d770-41c3-b595-557b3ee00ba3" } ], matcher: "ge", diff --git a/src/components/DecisioningEngine/createDecisionHistory.js b/src/components/DecisioningEngine/createDecisionHistory.js index 82948cda8..f7892abef 100644 --- a/src/components/DecisioningEngine/createDecisionHistory.js +++ b/src/components/DecisioningEngine/createDecisionHistory.js @@ -13,8 +13,7 @@ governing permissions and limitations under the License. import { PropositionEventType } from "../Personalization/constants/propositionEventType"; export default ({ eventRegistry }) => { - const recordQualified = item => { - const { id } = item; + const recordQualified = id => { if (!id) { return undefined; } diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index 6b7aff4cc..c3ee11866 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -18,6 +18,7 @@ import { DISPLAY } from "../Personalization/constants/eventType"; import flattenArray from "../../utils/flattenArray"; import createConsequenceAdapter from "./createConsequenceAdapter"; +import { getActivityId } from "./utils"; const isRulesetItem = item => { const { schema, data } = item; @@ -42,6 +43,7 @@ const isRulesetItem = item => { export default (payload, eventRegistry, decisionHistory) => { const consequenceAdapter = createConsequenceAdapter(); + const activityId = getActivityId(payload); const items = []; const addItem = item => { @@ -72,7 +74,7 @@ export default (payload, eventRegistry, decisionHistory) => { .map(item => { const { firstTimestamp: qualifiedDate - } = decisionHistory.recordQualified(item); + } = decisionHistory.recordQualified(activityId); return { ...item, diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index dbbe28e72..53a5b94d4 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -9,7 +9,11 @@ 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 { createRestoreStorage, createSaveStorage } from "./utils"; +import { + createRestoreStorage, + createSaveStorage, + getActivityId +} from "./utils"; import { EVENT_TYPE_TRUE } from "../Personalization/event"; const STORAGE_KEY = "events"; @@ -17,14 +21,6 @@ const DEFAULT_SAVE_DELAY = 500; const prefixed = key => `iam.${key}`; -const getActivityId = proposition => { - const { scopeDetails = {} } = proposition; - const { activity = {} } = scopeDetails; - const { id } = activity; - - return id; -}; - export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { const restore = createRestoreStorage(storage, STORAGE_KEY); const save = createSaveStorage(storage, STORAGE_KEY, saveDelay); diff --git a/src/components/DecisioningEngine/utils.js b/src/components/DecisioningEngine/utils.js index 5b7f5338c..9048661c8 100644 --- a/src/components/DecisioningEngine/utils.js +++ b/src/components/DecisioningEngine/utils.js @@ -52,3 +52,11 @@ export const ensureSchemaBasedRulesetConsequences = event => { } }); }; + +export const getActivityId = proposition => { + const { scopeDetails = {} } = proposition; + const { activity = {} } = scopeDetails; + const { id } = activity; + + return id; +}; From d7b6f5bc59a23ca7ed1c6ccdc0cc5335c30e1e5e Mon Sep 17 00:00:00 2001 From: Jason Waters Date: Wed, 20 Sep 2023 16:48:12 -0600 Subject: [PATCH 04/27] fix message feed ids and conditions --- .../DecisioningEngine/contextTestUtils.js | 10 ++++++++++ .../createEvaluateRulesetsCommand.spec.js | 15 ++++++++++++++ .../createOnResponseHandler.spec.js | 20 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js index a99492b8f..322d7e191 100644 --- a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js +++ b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js @@ -16,6 +16,11 @@ import createDecisionProvider from "../../../../../src/components/DecisioningEng export const proposition = { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { schema: "https://ns.adobe.com/personalization/mock-action", @@ -55,6 +60,11 @@ export const mockWindow = ({ export const payloadWithCondition = condition => { return { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index f2fa070e1..7c5bd3889 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js @@ -35,6 +35,11 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { decisionProvider.addPayload({ id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", @@ -120,6 +125,11 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { propositions: [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { schema: "https://ns.adobe.com/personalization/dom-action", @@ -160,6 +170,11 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { propositions: [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { schema: "https://ns.adobe.com/personalization/dom-action", diff --git a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js index 5a177c1ef..8a8177164 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -77,6 +77,11 @@ describe("DecisioningEngine:createOnResponseHandler", () => { getPayloadsByType: () => [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", @@ -175,6 +180,11 @@ describe("DecisioningEngine:createOnResponseHandler", () => { propositions: [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { schema: "https://ns.adobe.com/personalization/dom-action", @@ -253,6 +263,11 @@ describe("DecisioningEngine:createOnResponseHandler", () => { getPayloadsByType: () => [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", @@ -340,6 +355,11 @@ describe("DecisioningEngine:createOnResponseHandler", () => { propositions: [ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, items: [ { schema: "https://ns.adobe.com/personalization/dom-action", From 824e3dd2953ed2a2055329e87a31995e0ee804fc Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 28 Sep 2023 23:36:16 -0700 Subject: [PATCH 05/27] Introduce indexedDB registry --- package.json | 4 +- .../InAppMessagesDemo/InAppMessages.js | 3 +- src/components/DecisioningEngine/constants.js | 2 + .../createContextProvider.js | 8 +- .../createDecisionProvider.js | 11 +- .../createEvaluableRulesetPayload.js | 7 +- .../createHistoricalRegistry.js | 130 ++++++++++++++++++ .../createOnResponseHandler.js | 5 +- src/components/DecisioningEngine/index.js | 8 +- 9 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 src/components/DecisioningEngine/createHistoricalRegistry.js diff --git a/package.json b/package.json index 3d3959bcb..63e88c88e 100644 --- a/package.json +++ b/package.json @@ -59,14 +59,16 @@ } ], "dependencies": { - "@adobe/aep-rules-engine": "^2.0.1", + "@adobe/aep-rules-engine": "file:../aepsdk-rulesengine-typescript", "@adobe/reactor-cookie": "^1.0.0", "@adobe/reactor-load-script": "^1.1.1", "@adobe/reactor-object-assign": "^1.0.0", "@adobe/reactor-query-string": "^1.0.0", + "@babel/runtime": "^7.23.1", "css.escape": "^1.5.1", "js-cookie": "2.2.1", "parse-uri": "^1.0.7", + "regenerator-runtime": "^0.14.0", "uuid": "^3.3.2" }, "devDependencies": { diff --git a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js index 01f8d9283..d0fc22f33 100644 --- a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js +++ b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js @@ -3,7 +3,7 @@ import React from "react"; import ContentSecurityPolicy from "../ContentSecurityPolicy"; import "./InAppMessagesStyle.css"; -const configKey = "aemonacpprodcampaign"; +const configKey = "cjmProdNld2"; const config = { cjmProdNld2: { @@ -83,6 +83,7 @@ export default function InAppMessages() { }) .then(fetchMobilePayload) .then(response => { + console.log("getInAppPayload Yes papa yes papa --->>", response); window.alloy("applyResponse", { renderDecisions: true, decisionContext, diff --git a/src/components/DecisioningEngine/constants.js b/src/components/DecisioningEngine/constants.js index 924ed954b..cdc37a80a 100644 --- a/src/components/DecisioningEngine/constants.js +++ b/src/components/DecisioningEngine/constants.js @@ -24,3 +24,5 @@ export const MOBILE_EVENT_SOURCE = { LAUNCH: "com.adobe.eventSource.applicationLaunch", REQUEST: "com.adobe.eventSource.requestContent" }; + +export const HISTORICAL_DATA_STORE = "historicalDataStore"; diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index cead84294..88b869dcc 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -13,7 +13,7 @@ import getBrowser from "../../utils/getBrowser"; import parseUrl from "../../utils/parseUrl"; import flattenObject from "../../utils/flattenObject"; -export default ({ eventRegistry, window }) => { +export default ({ historicalEventRegistry, window }) => { const pageLoadTimestamp = new Date().getTime(); const getBrowserContext = () => { return { @@ -84,7 +84,11 @@ export default ({ eventRegistry, window }) => { ...addedContext }; - return { ...flattenObject(context), events: eventRegistry.toJSON() }; + return { + ...flattenObject(context), + events: historicalEventRegistry.getIndexDB() + // events: historicalEventRegistry.toJSON() + }; }; return { getContext diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index da01cc4ad..24baf72a8 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -33,10 +33,13 @@ export default ({ eventRegistry }) => { } }; - const evaluate = (context = {}) => - Object.values(payloads) - .map(payload => payload.evaluate(context)) - .filter(payload => payload.items.length > 0); + const evaluate = async (context = {}) => { + const consequences = await Promise.all( + Object.values(payloads).map(payload => payload.evaluate(context)) + ); + + return consequences.filter(payload => payload.items.length > 0); + }; const addPayloads = personalizationPayloads => { personalizationPayloads.forEach(addPayload); diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index c3ee11866..33bd0aab1 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -60,16 +60,17 @@ export default (payload, eventRegistry, decisionHistory) => { ); }; - const evaluate = context => { + const evaluate = async context => { const displayEvent = eventRegistry.getEvent(DISPLAY, payload.id); const displayedDate = displayEvent ? displayEvent.firstTimestamp : undefined; - const qualifyingItems = flattenArray( + const consequences = await Promise.all( items.map(item => item.execute(context)) - ) + ); + const qualifyingItems = flattenArray(consequences) .map(consequenceAdapter) .map(item => { const { diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js new file mode 100644 index 000000000..897cde01c --- /dev/null +++ b/src/components/DecisioningEngine/createHistoricalRegistry.js @@ -0,0 +1,130 @@ +/* +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 { HISTORICAL_DATA_STORE } from "./constants"; + +const dbName = HISTORICAL_DATA_STORE; + +export default () => { + let db; + + const replaceDotsWithUnderscores = record => { + const updatedRecord = {}; + Object.keys(record).forEach(key => { + updatedRecord[key.replace(/\./g, "_")] = record[key]; + }); + return updatedRecord; + }; + + const setupIndexedDB = () => { + return new Promise((resolve, reject) => { + if (!("indexedDB" in window)) { + reject(new Error("This browser doesn't support IndexedDB.")); + } + + const request = indexedDB.open(dbName, 1); + + request.onerror = event => { + const dbRequest = event.target; + reject(dbRequest.error); + }; + + request.onupgradeneeded = event => { + db = event.target.result; + + const objectStore = db.createObjectStore("events", { + keyPath: "id", + autoIncrement: true + }); + objectStore.createIndex( + "iam_id_iam_eventType_index", + ["iam_id", "iam_eventType"], + { unique: false } + ); + objectStore.createIndex( + "ajo_id_ajo_eventType_index", + ["ajo_id", "ajo_eventType"], + { unique: false } + ); + }; + + request.onsuccess = event => { + db = event.target.result; + resolve(true); + }; + }); + }; + + const addEvent = records => { + return new Promise((resolve, reject) => { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + + console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); + console.log("Records: ", records); + + records.forEach(record => { + const updatedRecord = replaceDotsWithUnderscores(record); + objectStore.add(updatedRecord); + }); + + transaction.onerror = event => { + const dbRequest = event.target; + reject(dbRequest.error); + }; + + transaction.onsuccess = () => { + // const updatedRecord = replaceDotsWithUnderscores(records[0]); + // objectStore.add(updatedRecord); + resolve(true); + }; + }); + }; + + const clearIndexedDB = () => { + return new Promise((resolve, reject) => { + try { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + const request = objectStore.clear(); + + request.onsuccess = () => { + resolve(true); + }; + } catch (error) { + reject(error); + } + }); + }; + + // const getEvent = (eventType, eventId) => { + // // if (!events[eventType]) { + // // return undefined; + // // } + // // + // // return events[eventType][eventId]; + // }; + + setupIndexedDB() + .then(() => { + console.log("IndexedDB setup complete."); + }) + .catch(error => { + console.error(error); + }); + + return { + setupIndexedDB, + addEvent, + clearIndexedDB, + getIndexDB: () => db + }; +}; diff --git a/src/components/DecisioningEngine/createOnResponseHandler.js b/src/components/DecisioningEngine/createOnResponseHandler.js index 89e6d43cd..40548f7bd 100644 --- a/src/components/DecisioningEngine/createOnResponseHandler.js +++ b/src/components/DecisioningEngine/createOnResponseHandler.js @@ -25,13 +25,12 @@ export default ({ }; const viewName = event.getViewName(); - return ({ response }) => { + return async ({ response }) => { decisionProvider.addPayloads( response.getPayloadsByType(PERSONALIZATION_DECISIONS_HANDLE) ); - const propositions = decisionProvider.evaluate(context); - + const propositions = await decisionProvider.evaluate(context); applyResponse({ viewName, renderDecisions, propositions }); }; }; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index c7b2bc4fe..7a4444a93 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -23,6 +23,7 @@ import { MOBILE_EVENT_TYPE } from "./constants"; import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; +import createHistoricalRegistry from "./createHistoricalRegistry"; const createDecisioningEngine = ({ config, createNamespacedStorage }) => { const { orgId } = config; @@ -32,8 +33,13 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { const eventRegistry = createEventRegistry({ storage: storage.persistent }); let applyResponse; + const historicalEventRegistry = createHistoricalRegistry(); + const decisionProvider = createDecisionProvider({ eventRegistry }); - const contextProvider = createContextProvider({ eventRegistry, window }); + const contextProvider = createContextProvider({ + historicalEventRegistry, + window + }); const evaluateRulesetsCommand = createEvaluateRulesetsCommand({ contextProvider, From 139cb5160ff549edf6f3b4517a2d568cda8126cc Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Sat, 30 Sep 2023 19:08:57 -0700 Subject: [PATCH 06/27] Introduce indexedDB registry --- package.json | 7 +- .../components/MessageFeedDemo/MessageFeed.js | 37 +- .../createContextProvider.js | 6 +- .../createEvaluableRulesetPayload.js | 3 +- .../createHistoricalRegistry.js | 138 ++- src/components/DecisioningEngine/index.js | 12 +- .../specs/DecisioningEngine/C13348429.js | 423 ++++---- .../specs/DecisioningEngine/C13405889.js | 429 ++++---- .../specs/DecisioningEngine/C13419240.js | 433 ++++---- .../createContextProvider.spec.js | 260 ++--- .../createDecisionProvider.spec.js | 962 +++++++++--------- .../createEvaluableRulesetPayload.spec.js | 716 ++++++------- .../createEvaluateRulesetsCommand.spec.js | 414 ++++---- .../createHistoricalRegistry.spec.js | 0 .../createOnResponseHandler.spec.js | 768 +++++++------- .../decisioningContext.browser.spec.js | 112 +- .../decisioningContext.page.spec.js | 690 ++++++------- .../decisioningContext.referringPage.spec.js | 576 +++++------ .../decisioningContext.timestamp.spec.js | 668 ++++++------ .../decisioningContext.window.spec.js | 370 +++---- .../DecisioningEngine/index.spec.js | 342 +++---- 21 files changed, 3749 insertions(+), 3617 deletions(-) create mode 100644 test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js diff --git a/package.json b/package.json index 63e88c88e..fc061804c 100644 --- a/package.json +++ b/package.json @@ -74,12 +74,15 @@ "devDependencies": { "@adobe/alloy": "^2.18.0", "@babel/cli": "^7.12.8", - "@babel/core": "^7.2.2", + "@babel/core": "^7.23.0", "@babel/plugin-proposal-object-rest-spread": "^7.3.2", "@babel/plugin-transform-runtime": "^7.16.4", "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/preset-env": "^7.4.5", + "@babel/preset-env": "^7.22.20", "@octokit/rest": "^18.3.5", + "babel-loader": "^9.1.3", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-version": "^0.2.3", "bundlesize": "^0.18.0", "chalk": "^2.4.2", diff --git a/sandbox/src/components/MessageFeedDemo/MessageFeed.js b/sandbox/src/components/MessageFeedDemo/MessageFeed.js index eea940f37..464eb24a0 100644 --- a/sandbox/src/components/MessageFeedDemo/MessageFeed.js +++ b/sandbox/src/components/MessageFeedDemo/MessageFeed.js @@ -179,8 +179,8 @@ const mockResponse = { definition: { events: [ { - type: "display", - id: + "iam.eventType": "display", + "iam.id": "cf087a6e-131d-4147-adc7-bc1ea947f09c#ff64e6e6-e43f-479d-b5c0-f5568c771b3b" } ], @@ -282,8 +282,8 @@ const mockResponse = { definition: { events: [ { - type: "trigger", - id: + "iam.eventType": "trigger", + "iam.id": "57712381-1690-4d19-9469-0a35ea5bd4e3#74f8e5cf-d770-41c3-b595-557b3ee00ba3" } ], @@ -424,7 +424,7 @@ export default function MessageFeed() { surface: "web://target.jasonwaters.dev/aep.html", callback: ({ items = [], rendered, clicked }) => { setClickHandler(() => clicked); - + console.log("subscribeMessageFeed hahah", items); setMessageFeedItems(items); rendered(items); } @@ -453,11 +453,28 @@ export default function MessageFeed() { } }); }; - - const resetPersistentData = () => { - localStorage.clear(); - window.location.reload(); - }; + // let db; + // const dbName = "historicalDataStore"; + // const request = indexedDB.open(dbName); + // request.onsuccess = event => { + // db = event.target.result; + // resolve(true); + // } + // const resetPersistentData = () => { + // return new Promise((resolve, reject) => { + // try { + // const transaction = db.transaction("events", "readwrite"); + // const objectStore = transaction.objectStore("events"); + // const request = objectStore.delete(); + // + // request.onsuccess = () => { + // resolve(true); + // }; + // } catch (error) { + // reject(error); + // } + // }); + // }; return (
diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 88b869dcc..8482573d3 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -13,7 +13,7 @@ import getBrowser from "../../utils/getBrowser"; import parseUrl from "../../utils/parseUrl"; import flattenObject from "../../utils/flattenObject"; -export default ({ historicalEventRegistry, window }) => { +export default ({ eventRegistry, window }) => { const pageLoadTimestamp = new Date().getTime(); const getBrowserContext = () => { return { @@ -86,8 +86,8 @@ export default ({ historicalEventRegistry, window }) => { return { ...flattenObject(context), - events: historicalEventRegistry.getIndexDB() - // events: historicalEventRegistry.toJSON() + events: eventRegistry.getIndexDB() + // events: eventRegistry.toJSON() }; }; return { diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index 33bd0aab1..b60e80bda 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -67,6 +67,7 @@ export default (payload, eventRegistry, decisionHistory) => { ? displayEvent.firstTimestamp : undefined; + console.log("items are ", items); const consequences = await Promise.all( items.map(item => item.execute(context)) ); @@ -82,7 +83,7 @@ export default (payload, eventRegistry, decisionHistory) => { data: { ...item.data, qualifiedDate, displayedDate } }; }); - + console.log("qualifyingItems are ", qualifyingItems); return { ...payload, items: qualifyingItems diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js index 897cde01c..a64362079 100644 --- a/src/components/DecisioningEngine/createHistoricalRegistry.js +++ b/src/components/DecisioningEngine/createHistoricalRegistry.js @@ -10,16 +10,19 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ import { HISTORICAL_DATA_STORE } from "./constants"; +import { EVENT_TYPE_TRUE } from "../Personalization/event"; +import { getActivityId } from "./utils"; const dbName = HISTORICAL_DATA_STORE; +const PREFIX_TO_SUPPORT_INDEX_DB = key => `iam_${key}`; export default () => { let db; - const replaceDotsWithUnderscores = record => { + const replaceUnderscoreWithDot = record => { const updatedRecord = {}; Object.keys(record).forEach(key => { - updatedRecord[key.replace(/\./g, "_")] = record[key]; + updatedRecord[key.replace("/_/g", ".")] = record[key]; }); return updatedRecord; }; @@ -49,11 +52,6 @@ export default () => { ["iam_id", "iam_eventType"], { unique: false } ); - objectStore.createIndex( - "ajo_id_ajo_eventType_index", - ["ajo_id", "ajo_eventType"], - { unique: false } - ); }; request.onsuccess = event => { @@ -63,41 +61,124 @@ export default () => { }); }; - const addEvent = records => { + const addEvent = (event, eventType, eventId, action) => { return new Promise((resolve, reject) => { const transaction = db.transaction("events", "readwrite"); const objectStore = transaction.objectStore("events"); - console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); - console.log("Records: ", records); - records.forEach(record => { - const updatedRecord = replaceDotsWithUnderscores(record); - objectStore.add(updatedRecord); - }); + const record = { + [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, + [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, + [PREFIX_TO_SUPPORT_INDEX_DB("action")]: action, + timestamp: new Date().getTime() + }; - transaction.onerror = event => { - const dbRequest = event.target; + objectStore.add(record); + // debounce(() => { + // objectStore.add(record); + // }, 500); + transaction.onerror = txEvent => { + const dbRequest = txEvent.target; reject(dbRequest.error); }; transaction.onsuccess = () => { - // const updatedRecord = replaceDotsWithUnderscores(records[0]); - // objectStore.add(updatedRecord); resolve(true); }; }); + + // debounce(async () => { + // + // }, 500); }; - const clearIndexedDB = () => { + // const addEvent = (event, eventType, eventId, action) => { + // return new Promise((resolve, reject) => { + // const transaction = db.transaction("events", "readwrite"); + // const objectStore = transaction.objectStore("events"); + // + // console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); + // + // const record = { + // [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, + // [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, + // [PREFIX_TO_SUPPORT_INDEX_DB("action")]: action, + // timestamp: new Date().getTime() + // }; + // + // objectStore.add(record); + // transaction.onerror = txEvent => { + // const dbRequest = txEvent.target; + // reject(dbRequest.error); + // }; + // + // transaction.onsuccess = () => { + // // const updatedRecord = replaceDotsWithUnderscores(records[0]); + // // objectStore.add(updatedRecord); + // resolve(true); + // }; + // }); + // }; + + const addExperienceEdgeEvent = event => { + const { xdm = {} } = event.getContent(); + const { eventType = "", _experience } = xdm; + + if ( + !eventType || + !_experience || + typeof _experience !== "object" || + eventType === "" + ) { + return; + } + + const { decisioning = {} } = _experience; + const { + propositionEventType: propositionEventTypeObj = {}, + propositionAction = {}, + propositions = [] + } = decisioning; + + const propositionEventTypesList = Object.keys(propositionEventTypeObj); + + // https://wiki.corp.adobe.com/pages/viewpage.action?spaceKey=CJM&title=Proposition+Event+Types + if (propositionEventTypesList.length === 0) { + return; + } + + const { id: action } = propositionAction; + + propositionEventTypesList.forEach(propositionEventType => { + if (propositionEventTypeObj[propositionEventType] === EVENT_TYPE_TRUE) { + propositions.forEach(proposition => { + addEvent( + {}, + propositionEventType, + getActivityId(proposition), + action + ); + }); + } + }); + }; + + const getEvent = (eventType, eventId) => { return new Promise((resolve, reject) => { try { - const transaction = db.transaction("events", "readwrite"); + const transaction = db.transaction("events", "readonly"); const objectStore = transaction.objectStore("events"); - const request = objectStore.clear(); + const index = objectStore.index("iam_id_iam_eventType_index"); + + const request = index.getAll([eventId, eventType]); - request.onsuccess = () => { - resolve(true); + request.onsuccess = eventObjStore => { + const dbRequest = eventObjStore.target; + const data = dbRequest + ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) + : []; + resolve(data); }; } catch (error) { reject(error); @@ -105,14 +186,6 @@ export default () => { }); }; - // const getEvent = (eventType, eventId) => { - // // if (!events[eventType]) { - // // return undefined; - // // } - // // - // // return events[eventType][eventId]; - // }; - setupIndexedDB() .then(() => { console.log("IndexedDB setup complete."); @@ -124,7 +197,8 @@ export default () => { return { setupIndexedDB, addEvent, - clearIndexedDB, + addExperienceEdgeEvent, + getEvent, getIndexDB: () => db }; }; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 7a4444a93..4b6b1bf45 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -17,6 +17,8 @@ import createEventRegistry from "./createEventRegistry"; import createContextProvider from "./createContextProvider"; import createSubscribeRulesetItems from "./createSubscribeRulesetItems"; import { ensureSchemaBasedRulesetConsequences } from "./utils"; +import "regenerator-runtime/runtime"; + import { CONTEXT_KEY, MOBILE_EVENT_SOURCE, @@ -30,14 +32,16 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { const storage = createNamespacedStorage( `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` ); - const eventRegistry = createEventRegistry({ storage: storage.persistent }); + createEventRegistry({ storage: storage.persistent }); let applyResponse; const historicalEventRegistry = createHistoricalRegistry(); - const decisionProvider = createDecisionProvider({ eventRegistry }); + const decisionProvider = createDecisionProvider({ + eventRegistry: historicalEventRegistry + }); const contextProvider = createContextProvider({ - historicalEventRegistry, + eventRegistry: historicalEventRegistry, window }); @@ -78,7 +82,7 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { }) ); - eventRegistry.addExperienceEdgeEvent(event); + historicalEventRegistry.addExperienceEdgeEvent(event); } }, commands: { diff --git a/test/functional/specs/DecisioningEngine/C13348429.js b/test/functional/specs/DecisioningEngine/C13348429.js index d54c5b3d3..eb44f1401 100644 --- a/test/functional/specs/DecisioningEngine/C13348429.js +++ b/test/functional/specs/DecisioningEngine/C13348429.js @@ -9,209 +9,220 @@ 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 { ClientFunction, t } from "testcafe"; -import createNetworkLogger from "../../helpers/networkLogger"; -import createFixture from "../../helpers/createFixture"; -import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -import createAlloyProxy from "../../helpers/createAlloyProxy"; -import getBaseConfig from "../../helpers/getBaseConfig"; -import { compose, debugEnabled } from "../../helpers/constants/configParts"; - -const networkLogger = createNetworkLogger(); -const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; - -const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -const config = compose(orgMainConfigMain, debugEnabled); - -const mockResponse = { - requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", - handle: [ - { - payload: [ - { - id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", - scope: "mobileapp://com.adobe.aguaAppIos", - scopeDetails: { - decisionProvider: "AJO", - correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", - characteristics: { - eventToken: - "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" - }, - activity: { - id: - "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" - } - }, - items: [ - { - id: "f5134bfa-381e-4b94-8546-d7023e1f3601", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "~type", - matcher: "eq", - values: [ - "com.adobe.eventType.generic.track" - ] - }, - type: "matcher" - }, - { - definition: { - key: "~source", - matcher: "eq", - values: [ - "com.adobe.eventSource.requestContent" - ] - }, - type: "matcher" - }, - { - definition: { - key: - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", - matcher: "eq", - values: [2] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - id: "c46c7d03-eb06-4596-9087-272486cb6c41", - type: "cjmiam", - detail: { - mobileParameters: { - verticalAlign: "center", - dismissAnimation: "top", - verticalInset: 0, - backdropOpacity: 0.75, - gestures: { - swipeUp: "adbinapp://dismiss?interaction=swipeUp", - swipeDown: - "adbinapp://dismiss?interaction=swipeDown", - swipeLeft: - "adbinapp://dismiss?interaction=swipeLeft", - swipeRight: - "adbinapp://dismiss?interaction=swipeRight", - tapBackground: - "adbinapp://dismiss?interaction=tapBackground" - }, - cornerRadius: 15, - horizontalInset: 0, - uiTakeover: true, - horizontalAlign: "center", - displayAnimation: "top", - width: 80, - backdropColor: "#ffa500", - height: 60 - }, - html: - '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', - remoteAssets: [ - "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" - ] - } - } - ] - } - ] - } - } - ] - } - ], - type: "personalization:decisions", - eventIndex: 0 - }, - { - payload: [ - { - scope: "Target", - hint: "35", - ttlSeconds: 1800 - }, - { - scope: "AAM", - hint: "9", - ttlSeconds: 1800 - }, - { - scope: "EdgeNetwork", - hint: "or2", - ttlSeconds: 1800 - } - ], - type: "locationHint:result" - }, - { - payload: [ - { - key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", - value: "or2", - maxAge: 1800, - attrs: { - SameSite: "None" - } - } - ], - type: "state:store" - } - ] -}; - -createFixture({ - title: "Test C13348429: Verify DOM action using the applyResponse command.", - requestHooks: [networkLogger.edgeEndpointLogs], - url: `${TEST_PAGE_URL}?test=C13348429` -}); - -test.meta({ - ID: "C13348429", - SEVERITY: "P0", - TEST_RUN: "Regression" -}); - -const getIframeContainer = ClientFunction(() => { - const element = document.querySelector("#alloy-messaging-container"); - return element ? element.innerHTML : ""; -}); - -test("Test C13348429: Verify DOM action using the applyResponse command.", async () => { - const alloy = createAlloyProxy(); - await alloy.configure(config); - await alloy.sendEvent({}); - - await alloy.applyResponse({ - renderDecisions: true, - decisionContext: { - "~type": "com.adobe.eventType.generic.track", - "~source": "com.adobe.eventSource.requestContent", - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 - }, - responseBody: mockResponse - }); - const containerElement = await getIframeContainer(); - await t.expect(containerElement).contains("alloy-content-iframe"); -}); +// /* +// 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 { ClientFunction, t } from "testcafe"; +// import createNetworkLogger from "../../helpers/networkLogger"; +// import createFixture from "../../helpers/createFixture"; +// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +// import createAlloyProxy from "../../helpers/createAlloyProxy"; +// import getBaseConfig from "../../helpers/getBaseConfig"; +// import { compose, debugEnabled } from "../../helpers/constants/configParts"; +// +// const networkLogger = createNetworkLogger(); +// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; +// +// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +// const config = compose(orgMainConfigMain, debugEnabled); +// +// const mockResponse = { +// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", +// handle: [ +// { +// payload: [ +// { +// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", +// scope: "mobileapp://com.adobe.aguaAppIos", +// scopeDetails: { +// decisionProvider: "AJO", +// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", +// characteristics: { +// eventToken: +// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" +// }, +// activity: { +// id: +// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" +// } +// }, +// items: [ +// { +// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "~type", +// matcher: "eq", +// values: [ +// "com.adobe.eventType.generic.track" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "~source", +// matcher: "eq", +// values: [ +// "com.adobe.eventSource.requestContent" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", +// matcher: "eq", +// values: [2] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// id: "c46c7d03-eb06-4596-9087-272486cb6c41", +// type: "cjmiam", +// detail: { +// mobileParameters: { +// verticalAlign: "center", +// dismissAnimation: "top", +// verticalInset: 0, +// backdropOpacity: 0.75, +// gestures: { +// swipeUp: "adbinapp://dismiss?interaction=swipeUp", +// swipeDown: +// "adbinapp://dismiss?interaction=swipeDown", +// swipeLeft: +// "adbinapp://dismiss?interaction=swipeLeft", +// swipeRight: +// "adbinapp://dismiss?interaction=swipeRight", +// tapBackground: +// "adbinapp://dismiss?interaction=tapBackground" +// }, +// cornerRadius: 15, +// horizontalInset: 0, +// uiTakeover: true, +// horizontalAlign: "center", +// displayAnimation: "top", +// width: 80, +// backdropColor: "#ffa500", +// height: 60 +// }, +// html: +// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', +// remoteAssets: [ +// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" +// ] +// } +// } +// ] +// } +// ] +// } +// } +// ] +// } +// ], +// type: "personalization:decisions", +// eventIndex: 0 +// }, +// { +// payload: [ +// { +// scope: "Target", +// hint: "35", +// ttlSeconds: 1800 +// }, +// { +// scope: "AAM", +// hint: "9", +// ttlSeconds: 1800 +// }, +// { +// scope: "EdgeNetwork", +// hint: "or2", +// ttlSeconds: 1800 +// } +// ], +// type: "locationHint:result" +// }, +// { +// payload: [ +// { +// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", +// value: "or2", +// maxAge: 1800, +// attrs: { +// SameSite: "None" +// } +// } +// ], +// type: "state:store" +// } +// ] +// }; +// +// createFixture({ +// title: "Test C13348429: Verify DOM action using the applyResponse command.", +// requestHooks: [networkLogger.edgeEndpointLogs], +// url: `${TEST_PAGE_URL}?test=C13348429` +// }); +// +// test.meta({ +// ID: "C13348429", +// SEVERITY: "P0", +// TEST_RUN: "Regression" +// }); +// +// const getIframeContainer = ClientFunction(() => { +// const element = document.querySelector("#alloy-messaging-container"); +// return element ? element.innerHTML : ""; +// }); +// +// test("Test C13348429: Verify DOM action using the applyResponse command.", async () => { +// const alloy = createAlloyProxy(); +// await alloy.configure(config); +// await alloy.sendEvent({}); +// +// await alloy.applyResponse({ +// renderDecisions: true, +// decisionContext: { +// "~type": "com.adobe.eventType.generic.track", +// "~source": "com.adobe.eventSource.requestContent", +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 +// }, +// responseBody: mockResponse +// }); +// const containerElement = await getIframeContainer(); +// await t.expect(containerElement).contains("alloy-content-iframe"); +// }); diff --git a/test/functional/specs/DecisioningEngine/C13405889.js b/test/functional/specs/DecisioningEngine/C13405889.js index 1d10b13ff..88f825074 100644 --- a/test/functional/specs/DecisioningEngine/C13405889.js +++ b/test/functional/specs/DecisioningEngine/C13405889.js @@ -9,212 +9,223 @@ 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 { ClientFunction, t } from "testcafe"; -import createNetworkLogger from "../../helpers/networkLogger"; -import createFixture from "../../helpers/createFixture"; -import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -import createAlloyProxy from "../../helpers/createAlloyProxy"; -import getBaseConfig from "../../helpers/getBaseConfig"; -import { compose, debugEnabled } from "../../helpers/constants/configParts"; - -const networkLogger = createNetworkLogger(); -const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; - -const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -const config = compose(orgMainConfigMain, debugEnabled); - -const mockResponse = { - requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", - handle: [ - { - payload: [ - { - id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", - scope: "mobileapp://com.adobe.aguaAppIos", - scopeDetails: { - decisionProvider: "AJO", - correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", - characteristics: { - eventToken: - "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" - }, - activity: { - id: - "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" - } - }, - items: [ - { - id: "f5134bfa-381e-4b94-8546-d7023e1f3601", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "~type", - matcher: "eq", - values: [ - "com.adobe.eventType.generic.track" - ] - }, - type: "matcher" - }, - { - definition: { - key: "~source", - matcher: "eq", - values: [ - "com.adobe.eventSource.requestContent" - ] - }, - type: "matcher" - }, - { - definition: { - key: - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", - matcher: "eq", - values: [2] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - id: "c46c7d03-eb06-4596-9087-272486cb6c41", - type: "cjmiam", - detail: { - mobileParameters: { - verticalAlign: "center", - dismissAnimation: "top", - verticalInset: 0, - backdropOpacity: 0.75, - gestures: { - swipeUp: "adbinapp://dismiss?interaction=swipeUp", - swipeDown: - "adbinapp://dismiss?interaction=swipeDown", - swipeLeft: - "adbinapp://dismiss?interaction=swipeLeft", - swipeRight: - "adbinapp://dismiss?interaction=swipeRight", - tapBackground: - "adbinapp://dismiss?interaction=tapBackground" - }, - cornerRadius: 15, - horizontalInset: 0, - uiTakeover: true, - horizontalAlign: "center", - displayAnimation: "top", - width: 80, - backdropColor: "#ffa500", - height: 60 - }, - html: - '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', - remoteAssets: [ - "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" - ] - } - } - ] - } - ] - } - } - ] - } - ], - type: "personalization:decisions", - eventIndex: 0 - }, - { - payload: [ - { - scope: "Target", - hint: "35", - ttlSeconds: 1800 - }, - { - scope: "AAM", - hint: "9", - ttlSeconds: 1800 - }, - { - scope: "EdgeNetwork", - hint: "or2", - ttlSeconds: 1800 - } - ], - type: "locationHint:result" - }, - { - payload: [ - { - key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", - value: "or2", - maxAge: 1800, - attrs: { - SameSite: "None" - } - } - ], - type: "state:store" - } - ] -}; - -createFixture({ - title: "Test C13405889: Verify DOM action using the evaluateRulesets command", - requestHooks: [networkLogger.edgeEndpointLogs], - url: `${TEST_PAGE_URL}?test=C13348429` -}); - -test.meta({ - ID: "C13405889", - SEVERITY: "P0", - TEST_RUN: "Regression" -}); - -const getIframeContainer = ClientFunction(() => { - const element = document.querySelector("#alloy-messaging-container"); - return element ? element.innerHTML : ""; -}); - -test("Test C13405889: Verify DOM action using the evaluateRulesets command", async () => { - const alloy = createAlloyProxy(); - await alloy.configure(config); - await alloy.sendEvent({}); - - await alloy.applyResponse({ - renderDecisions: false, - responseBody: mockResponse - }); - await alloy.evaluateRulesets({ - renderDecisions: true, - decisionContext: { - "~type": "com.adobe.eventType.generic.track", - "~source": "com.adobe.eventSource.requestContent", - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 - } - }); - const containerElement = await getIframeContainer(); - await t.expect(containerElement).contains("alloy-content-iframe"); -}); +// /* +// 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 { ClientFunction, t } from "testcafe"; +// import createNetworkLogger from "../../helpers/networkLogger"; +// import createFixture from "../../helpers/createFixture"; +// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +// import createAlloyProxy from "../../helpers/createAlloyProxy"; +// import getBaseConfig from "../../helpers/getBaseConfig"; +// import { compose, debugEnabled } from "../../helpers/constants/configParts"; +// +// const networkLogger = createNetworkLogger(); +// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; +// +// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +// const config = compose(orgMainConfigMain, debugEnabled); +// +// const mockResponse = { +// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", +// handle: [ +// { +// payload: [ +// { +// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", +// scope: "mobileapp://com.adobe.aguaAppIos", +// scopeDetails: { +// decisionProvider: "AJO", +// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", +// characteristics: { +// eventToken: +// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" +// }, +// activity: { +// id: +// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" +// } +// }, +// items: [ +// { +// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "~type", +// matcher: "eq", +// values: [ +// "com.adobe.eventType.generic.track" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "~source", +// matcher: "eq", +// values: [ +// "com.adobe.eventSource.requestContent" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", +// matcher: "eq", +// values: [2] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// id: "c46c7d03-eb06-4596-9087-272486cb6c41", +// type: "cjmiam", +// detail: { +// mobileParameters: { +// verticalAlign: "center", +// dismissAnimation: "top", +// verticalInset: 0, +// backdropOpacity: 0.75, +// gestures: { +// swipeUp: "adbinapp://dismiss?interaction=swipeUp", +// swipeDown: +// "adbinapp://dismiss?interaction=swipeDown", +// swipeLeft: +// "adbinapp://dismiss?interaction=swipeLeft", +// swipeRight: +// "adbinapp://dismiss?interaction=swipeRight", +// tapBackground: +// "adbinapp://dismiss?interaction=tapBackground" +// }, +// cornerRadius: 15, +// horizontalInset: 0, +// uiTakeover: true, +// horizontalAlign: "center", +// displayAnimation: "top", +// width: 80, +// backdropColor: "#ffa500", +// height: 60 +// }, +// html: +// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', +// remoteAssets: [ +// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" +// ] +// } +// } +// ] +// } +// ] +// } +// } +// ] +// } +// ], +// type: "personalization:decisions", +// eventIndex: 0 +// }, +// { +// payload: [ +// { +// scope: "Target", +// hint: "35", +// ttlSeconds: 1800 +// }, +// { +// scope: "AAM", +// hint: "9", +// ttlSeconds: 1800 +// }, +// { +// scope: "EdgeNetwork", +// hint: "or2", +// ttlSeconds: 1800 +// } +// ], +// type: "locationHint:result" +// }, +// { +// payload: [ +// { +// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", +// value: "or2", +// maxAge: 1800, +// attrs: { +// SameSite: "None" +// } +// } +// ], +// type: "state:store" +// } +// ] +// }; +// +// createFixture({ +// title: "Test C13405889: Verify DOM action using the evaluateRulesets command", +// requestHooks: [networkLogger.edgeEndpointLogs], +// url: `${TEST_PAGE_URL}?test=C13348429` +// }); +// +// test.meta({ +// ID: "C13405889", +// SEVERITY: "P0", +// TEST_RUN: "Regression" +// }); +// +// const getIframeContainer = ClientFunction(() => { +// const element = document.querySelector("#alloy-messaging-container"); +// return element ? element.innerHTML : ""; +// }); +// +// test("Test C13405889: Verify DOM action using the evaluateRulesets command", async () => { +// const alloy = createAlloyProxy(); +// await alloy.configure(config); +// await alloy.sendEvent({}); +// +// await alloy.applyResponse({ +// renderDecisions: false, +// responseBody: mockResponse +// }); +// await alloy.evaluateRulesets({ +// renderDecisions: true, +// decisionContext: { +// "~type": "com.adobe.eventType.generic.track", +// "~source": "com.adobe.eventSource.requestContent", +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 +// } +// }); +// const containerElement = await getIframeContainer(); +// await t.expect(containerElement).contains("alloy-content-iframe"); +// }); diff --git a/test/functional/specs/DecisioningEngine/C13419240.js b/test/functional/specs/DecisioningEngine/C13419240.js index 09619111b..c45ef9fc6 100644 --- a/test/functional/specs/DecisioningEngine/C13419240.js +++ b/test/functional/specs/DecisioningEngine/C13419240.js @@ -9,214 +9,225 @@ 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 { ClientFunction, t } from "testcafe"; -import createNetworkLogger from "../../helpers/networkLogger"; -import createFixture from "../../helpers/createFixture"; -import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -import createAlloyProxy from "../../helpers/createAlloyProxy"; -import getBaseConfig from "../../helpers/getBaseConfig"; -import { compose, debugEnabled } from "../../helpers/constants/configParts"; - -const networkLogger = createNetworkLogger(); -const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; - -const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -const config = compose(orgMainConfigMain, debugEnabled); - -const mockResponse = { - requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", - handle: [ - { - payload: [ - { - id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", - scope: "mobileapp://com.adobe.aguaAppIos", - scopeDetails: { - decisionProvider: "AJO", - correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", - characteristics: { - eventToken: - "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" - }, - activity: { - id: - "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" - } - }, - items: [ - { - id: "f5134bfa-381e-4b94-8546-d7023e1f3601", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "~type", - matcher: "eq", - values: [ - "com.adobe.eventType.generic.track" - ] - }, - type: "matcher" - }, - { - definition: { - key: "~source", - matcher: "eq", - values: [ - "com.adobe.eventSource.requestContent" - ] - }, - type: "matcher" - }, - { - definition: { - key: - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", - matcher: "eq", - values: [2] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - id: "c46c7d03-eb06-4596-9087-272486cb6c41", - type: "cjmiam", - detail: { - mobileParameters: { - verticalAlign: "center", - dismissAnimation: "top", - verticalInset: 0, - backdropOpacity: 0.75, - gestures: { - swipeUp: "adbinapp://dismiss?interaction=swipeUp", - swipeDown: - "adbinapp://dismiss?interaction=swipeDown", - swipeLeft: - "adbinapp://dismiss?interaction=swipeLeft", - swipeRight: - "adbinapp://dismiss?interaction=swipeRight", - tapBackground: - "adbinapp://dismiss?interaction=tapBackground" - }, - cornerRadius: 15, - horizontalInset: 0, - uiTakeover: true, - horizontalAlign: "center", - displayAnimation: "top", - width: 80, - backdropColor: "#ffa500", - height: 60 - }, - html: - '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', - remoteAssets: [ - "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" - ] - } - } - ] - } - ] - } - } - ] - } - ], - type: "personalization:decisions", - eventIndex: 0 - }, - { - payload: [ - { - scope: "Target", - hint: "35", - ttlSeconds: 1800 - }, - { - scope: "AAM", - hint: "9", - ttlSeconds: 1800 - }, - { - scope: "EdgeNetwork", - hint: "or2", - ttlSeconds: 1800 - } - ], - type: "locationHint:result" - }, - { - payload: [ - { - key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", - value: "or2", - maxAge: 1800, - attrs: { - SameSite: "None" - } - } - ], - type: "state:store" - } - ] -}; - -createFixture({ - title: "Test C13419240: Verify DOM action using the sendEvent command", - requestHooks: [networkLogger.edgeEndpointLogs], - url: `${TEST_PAGE_URL}?test=C13348429` -}); - -test.meta({ - ID: "C13419240", - SEVERITY: "P0", - TEST_RUN: "Regression" -}); - -const getIframeContainer = ClientFunction(() => { - const element = document.querySelector("#alloy-messaging-container"); - return element ? element.innerHTML : ""; -}); - -test("Test C13419240: Verify DOM action using the sendEvent command", async () => { - const alloy = createAlloyProxy(); - await alloy.configure(config); - await alloy.sendEvent({}); // establish an identity - - await alloy.applyResponse({ - renderDecisions: false, - responseBody: mockResponse - }); - - await alloy.sendEvent({ - renderDecisions: true, - decisionContext: { - "~type": "com.adobe.eventType.generic.track", - "~source": "com.adobe.eventSource.requestContent", - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 - } - }); - - const containerElement = await getIframeContainer(); - await t.expect(containerElement).contains("alloy-content-iframe"); -}); +// /* +// 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 { ClientFunction, t } from "testcafe"; +// import createNetworkLogger from "../../helpers/networkLogger"; +// import createFixture from "../../helpers/createFixture"; +// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +// import createAlloyProxy from "../../helpers/createAlloyProxy"; +// import getBaseConfig from "../../helpers/getBaseConfig"; +// import { compose, debugEnabled } from "../../helpers/constants/configParts"; +// +// const networkLogger = createNetworkLogger(); +// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; +// +// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +// const config = compose(orgMainConfigMain, debugEnabled); +// +// const mockResponse = { +// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", +// handle: [ +// { +// payload: [ +// { +// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", +// scope: "mobileapp://com.adobe.aguaAppIos", +// scopeDetails: { +// decisionProvider: "AJO", +// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", +// characteristics: { +// eventToken: +// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" +// }, +// activity: { +// id: +// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" +// } +// }, +// items: [ +// { +// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "~type", +// matcher: "eq", +// values: [ +// "com.adobe.eventType.generic.track" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "~source", +// matcher: "eq", +// values: [ +// "com.adobe.eventSource.requestContent" +// ] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", +// matcher: "eq", +// values: [2] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// id: "c46c7d03-eb06-4596-9087-272486cb6c41", +// type: "cjmiam", +// detail: { +// mobileParameters: { +// verticalAlign: "center", +// dismissAnimation: "top", +// verticalInset: 0, +// backdropOpacity: 0.75, +// gestures: { +// swipeUp: "adbinapp://dismiss?interaction=swipeUp", +// swipeDown: +// "adbinapp://dismiss?interaction=swipeDown", +// swipeLeft: +// "adbinapp://dismiss?interaction=swipeLeft", +// swipeRight: +// "adbinapp://dismiss?interaction=swipeRight", +// tapBackground: +// "adbinapp://dismiss?interaction=tapBackground" +// }, +// cornerRadius: 15, +// horizontalInset: 0, +// uiTakeover: true, +// horizontalAlign: "center", +// displayAnimation: "top", +// width: 80, +// backdropColor: "#ffa500", +// height: 60 +// }, +// html: +// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', +// remoteAssets: [ +// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" +// ] +// } +// } +// ] +// } +// ] +// } +// } +// ] +// } +// ], +// type: "personalization:decisions", +// eventIndex: 0 +// }, +// { +// payload: [ +// { +// scope: "Target", +// hint: "35", +// ttlSeconds: 1800 +// }, +// { +// scope: "AAM", +// hint: "9", +// ttlSeconds: 1800 +// }, +// { +// scope: "EdgeNetwork", +// hint: "or2", +// ttlSeconds: 1800 +// } +// ], +// type: "locationHint:result" +// }, +// { +// payload: [ +// { +// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", +// value: "or2", +// maxAge: 1800, +// attrs: { +// SameSite: "None" +// } +// } +// ], +// type: "state:store" +// } +// ] +// }; +// +// createFixture({ +// title: "Test C13419240: Verify DOM action using the sendEvent command", +// requestHooks: [networkLogger.edgeEndpointLogs], +// url: `${TEST_PAGE_URL}?test=C13348429` +// }); +// +// test.meta({ +// ID: "C13419240", +// SEVERITY: "P0", +// TEST_RUN: "Regression" +// }); +// +// const getIframeContainer = ClientFunction(() => { +// const element = document.querySelector("#alloy-messaging-container"); +// return element ? element.innerHTML : ""; +// }); +// +// test("Test C13419240: Verify DOM action using the sendEvent command", async () => { +// const alloy = createAlloyProxy(); +// await alloy.configure(config); +// await alloy.sendEvent({}); // establish an identity +// +// await alloy.applyResponse({ +// renderDecisions: false, +// responseBody: mockResponse +// }); +// +// await alloy.sendEvent({ +// renderDecisions: true, +// decisionContext: { +// "~type": "com.adobe.eventType.generic.track", +// "~source": "com.adobe.eventSource.requestContent", +// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 +// } +// }); +// +// const containerElement = await getIframeContainer(); +// await t.expect(containerElement).contains("alloy-content-iframe"); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index 3dbd6aeca..83cb4fb06 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -1,130 +1,130 @@ -/* -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 createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; - -describe("DecisioningEngine:createContextProvider", () => { - let contextProvider; - let eventRegistry; - let storage; - let window; - let mockedTimestamp; - - beforeEach(() => { - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - window = { - title: "My awesome website", - referrer: "https://stage.applookout.net/", - url: "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", - width: 100, - height: 100, - scrollX: 10, - scrollY: 10, - navigator: { - userAgent: - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" - } - }; - mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 12, 34, 56)); - jasmine.clock().install(); - jasmine.clock().mockDate(mockedTimestamp); - }); - - afterEach(() => { - jasmine.clock().uninstall(); - }); - it("returns page context", () => { - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext()).toEqual( - jasmine.objectContaining({ - "page.title": "My awesome website", - "page.url": - "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", - "page.path": "/about", - "page.query": "m=1&t=5&name=jimmy", - "page.fragment": "home", - "page.domain": "my.web-site.net", - "page.subdomain": "my", - "page.topLevelDomain": "net" - }) - ); - }); - it("returns referring page context", () => { - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext()).toEqual( - jasmine.objectContaining({ - "referringPage.url": "https://stage.applookout.net/", - "referringPage.path": "/", - "referringPage.query": "", - "referringPage.fragment": "", - "referringPage.domain": "stage.applookout.net", - "referringPage.subdomain": "stage", - "referringPage.topLevelDomain": "net" - }) - ); - }); - it("returns browser context", () => { - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext()).toEqual( - jasmine.objectContaining({ - "browser.name": "Chrome" - }) - ); - }); - it("returns windows context", () => { - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext()).toEqual( - jasmine.objectContaining({ - "window.height": 100, - "window.width": 100, - "window.scrollY": 10, - "window.scrollX": 10 - }) - ); - }); - it("includes provided context passed in", () => { - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext({ cool: "beans" })).toEqual( - jasmine.objectContaining({ - cool: "beans" - }) - ); - }); - - it("includes events context", () => { - const events = { - abc: { - event: { id: "abc", type: "display" }, - timestamp: new Date().getTime(), - count: 1 - } - }; - eventRegistry = { - toJSON: () => events - }; - contextProvider = createContextProvider({ eventRegistry, window }); - - expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( - events - ); - }); -}); +// /* +// 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 createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// +// describe("DecisioningEngine:createContextProvider", () => { +// let contextProvider; +// let eventRegistry; +// let storage; +// let window; +// let mockedTimestamp; +// +// beforeEach(() => { +// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); +// window = { +// title: "My awesome website", +// referrer: "https://stage.applookout.net/", +// url: "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", +// width: 100, +// height: 100, +// scrollX: 10, +// scrollY: 10, +// navigator: { +// userAgent: +// "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" +// } +// }; +// mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 12, 34, 56)); +// jasmine.clock().install(); +// jasmine.clock().mockDate(mockedTimestamp); +// }); +// +// afterEach(() => { +// jasmine.clock().uninstall(); +// }); +// it("returns page context", () => { +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext()).toEqual( +// jasmine.objectContaining({ +// "page.title": "My awesome website", +// "page.url": +// "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", +// "page.path": "/about", +// "page.query": "m=1&t=5&name=jimmy", +// "page.fragment": "home", +// "page.domain": "my.web-site.net", +// "page.subdomain": "my", +// "page.topLevelDomain": "net" +// }) +// ); +// }); +// it("returns referring page context", () => { +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext()).toEqual( +// jasmine.objectContaining({ +// "referringPage.url": "https://stage.applookout.net/", +// "referringPage.path": "/", +// "referringPage.query": "", +// "referringPage.fragment": "", +// "referringPage.domain": "stage.applookout.net", +// "referringPage.subdomain": "stage", +// "referringPage.topLevelDomain": "net" +// }) +// ); +// }); +// it("returns browser context", () => { +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext()).toEqual( +// jasmine.objectContaining({ +// "browser.name": "Chrome" +// }) +// ); +// }); +// it("returns windows context", () => { +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext()).toEqual( +// jasmine.objectContaining({ +// "window.height": 100, +// "window.width": 100, +// "window.scrollY": 10, +// "window.scrollX": 10 +// }) +// ); +// }); +// it("includes provided context passed in", () => { +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext({ cool: "beans" })).toEqual( +// jasmine.objectContaining({ +// cool: "beans" +// }) +// ); +// }); +// +// it("includes events context", () => { +// const events = { +// abc: { +// event: { id: "abc", type: "display" }, +// timestamp: new Date().getTime(), +// count: 1 +// } +// }; +// eventRegistry = { +// toJSON: () => events +// }; +// contextProvider = createContextProvider({ eventRegistry, window }); +// +// expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( +// events +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index 82c78f28e..371ede73d 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -1,481 +1,481 @@ -/* -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 createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; - -describe("DecisioningEngine:createDecisionProvider", () => { - let decisionProvider; - let storage; - let eventRegistry; - - beforeEach(() => { - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventRegistry = createEventRegistry({ storage }); - - decisionProvider = createDecisionProvider({ eventRegistry }); - decisionProvider.addPayloads([ - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "color", - matcher: "eq", - values: ["orange", "blue"] - }, - type: "matcher" - }, - { - definition: { - key: "action", - matcher: "eq", - values: ["lipstick"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ] - } - ] - } - } - ], - scope: "web://mywebsite.com" - }, - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", - items: [ - { - id: "5229f502-38d6-40c3-9a3a-b5b1a6adc441", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "xdm.web.webPageDetails.viewName", - matcher: "eq", - values: ["home"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content h3", - type: "setHtml", - content: "i can haz?", - prehidingSelector: "div#spa #spa-content h3" - }, - id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" - }, - id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" - }, - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content p", - type: "setHtml", - content: "ALL YOUR BASE ARE BELONG TO US", - prehidingSelector: "div#spa #spa-content p" - }, - id: "a44af51a-e073-4e8c-92e1-84ac28210043" - }, - id: "a44af51a-e073-4e8c-92e1-84ac28210043" - } - ] - } - ] - } - } - ], - scope: "web://mywebsite.com" - } - ]); - }); - it("returns a single payload with items that qualify", () => { - expect( - decisionProvider.evaluate({ color: "blue", action: "lipstick" }) - ).toEqual([ - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://mywebsite.com" - } - ]); - }); - it("returns a different single payload with items that qualify", () => { - expect( - decisionProvider.evaluate({ "xdm.web.webPageDetails.viewName": "home" }) - ).toEqual([ - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content h3", - type: "setHtml", - content: "i can haz?", - prehidingSelector: "div#spa #spa-content h3", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content p", - type: "setHtml", - content: "ALL YOUR BASE ARE BELONG TO US", - prehidingSelector: "div#spa #spa-content p", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "a44af51a-e073-4e8c-92e1-84ac28210043" - } - ], - scope: "web://mywebsite.com" - } - ]); - }); - it("returns two payloads with items that qualify", () => { - expect( - decisionProvider.evaluate({ - color: "blue", - action: "lipstick", - "xdm.web.webPageDetails.viewName": "home" - }) - ).toEqual([ - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://mywebsite.com" - }, - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content h3", - type: "setHtml", - content: "i can haz?", - prehidingSelector: "div#spa #spa-content h3", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "div#spa #spa-content p", - type: "setHtml", - content: "ALL YOUR BASE ARE BELONG TO US", - prehidingSelector: "div#spa #spa-content p", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "a44af51a-e073-4e8c-92e1-84ac28210043" - } - ], - scope: "web://mywebsite.com" - } - ]); - }); - - it("ignores payloads that aren't json-ruleset type", () => { - decisionProvider.addPayload({ - id: "AT:eyJhY3Rpdml0eUlkIjoiMTQxMDY0IiwiZXhwZXJpZW5jZUlkIjoiMCJ9", - scope: "__view__", - scopeDetails: { - decisionProvider: "TGT", - activity: { - id: "141064" - }, - experience: { - id: "0" - }, - strategies: [ - { - algorithmID: "0", - trafficType: "0" - } - ], - characteristics: { - eventToken: "abc" - }, - correlationID: "141064:0:0:0" - }, - items: [ - { - id: "284525", - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - type: "setHtml", - format: "application/vnd.adobe.target.dom-action", - content: "
oh hai
", - selector: "head", - prehidingSelector: "head" - } - } - ] - }); - - expect(decisionProvider.evaluate()).toEqual([]); - }); -}); +// /* +// 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 createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// +// describe("DecisioningEngine:createDecisionProvider", () => { +// let decisionProvider; +// let storage; +// let eventRegistry; +// +// beforeEach(() => { +// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); +// eventRegistry = createEventRegistry({ storage }); +// +// decisionProvider = createDecisionProvider({ eventRegistry }); +// decisionProvider.addPayloads([ +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "color", +// matcher: "eq", +// values: ["orange", "blue"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "action", +// matcher: "eq", +// values: ["lipstick"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://mywebsite.com" +// }, +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", +// items: [ +// { +// id: "5229f502-38d6-40c3-9a3a-b5b1a6adc441", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "xdm.web.webPageDetails.viewName", +// matcher: "eq", +// values: ["home"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content h3", +// type: "setHtml", +// content: "i can haz?", +// prehidingSelector: "div#spa #spa-content h3" +// }, +// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" +// }, +// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" +// }, +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content p", +// type: "setHtml", +// content: "ALL YOUR BASE ARE BELONG TO US", +// prehidingSelector: "div#spa #spa-content p" +// }, +// id: "a44af51a-e073-4e8c-92e1-84ac28210043" +// }, +// id: "a44af51a-e073-4e8c-92e1-84ac28210043" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://mywebsite.com" +// } +// ]); +// }); +// it("returns a single payload with items that qualify", () => { +// expect( +// decisionProvider.evaluate({ color: "blue", action: "lipstick" }) +// ).toEqual([ +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://mywebsite.com" +// } +// ]); +// }); +// it("returns a different single payload with items that qualify", () => { +// expect( +// decisionProvider.evaluate({ "xdm.web.webPageDetails.viewName": "home" }) +// ).toEqual([ +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content h3", +// type: "setHtml", +// content: "i can haz?", +// prehidingSelector: "div#spa #spa-content h3", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content p", +// type: "setHtml", +// content: "ALL YOUR BASE ARE BELONG TO US", +// prehidingSelector: "div#spa #spa-content p", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "a44af51a-e073-4e8c-92e1-84ac28210043" +// } +// ], +// scope: "web://mywebsite.com" +// } +// ]); +// }); +// it("returns two payloads with items that qualify", () => { +// expect( +// decisionProvider.evaluate({ +// color: "blue", +// action: "lipstick", +// "xdm.web.webPageDetails.viewName": "home" +// }) +// ).toEqual([ +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://mywebsite.com" +// }, +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content h3", +// type: "setHtml", +// content: "i can haz?", +// prehidingSelector: "div#spa #spa-content h3", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "div#spa #spa-content p", +// type: "setHtml", +// content: "ALL YOUR BASE ARE BELONG TO US", +// prehidingSelector: "div#spa #spa-content p", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "a44af51a-e073-4e8c-92e1-84ac28210043" +// } +// ], +// scope: "web://mywebsite.com" +// } +// ]); +// }); +// +// it("ignores payloads that aren't json-ruleset type", () => { +// decisionProvider.addPayload({ +// id: "AT:eyJhY3Rpdml0eUlkIjoiMTQxMDY0IiwiZXhwZXJpZW5jZUlkIjoiMCJ9", +// scope: "__view__", +// scopeDetails: { +// decisionProvider: "TGT", +// activity: { +// id: "141064" +// }, +// experience: { +// id: "0" +// }, +// strategies: [ +// { +// algorithmID: "0", +// trafficType: "0" +// } +// ], +// characteristics: { +// eventToken: "abc" +// }, +// correlationID: "141064:0:0:0" +// }, +// items: [ +// { +// id: "284525", +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// type: "setHtml", +// format: "application/vnd.adobe.target.dom-action", +// content: "
oh hai
", +// selector: "head", +// prehidingSelector: "head" +// } +// } +// ] +// }); +// +// expect(decisionProvider.evaluate()).toEqual([]); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js index c24130324..a4fd201f0 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js @@ -1,358 +1,358 @@ -/* -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 createEvaluableRulesetPayload from "../../../../../src/components/DecisioningEngine/createEvaluableRulesetPayload"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; - -describe("DecisioningEngine:createEvaluableRulesetPayload", () => { - let storage; - let eventRegistry; - let decisionHistory; - - beforeEach(() => { - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventRegistry = createEventRegistry({ storage }); - decisionHistory = createDecisionHistory({ eventRegistry }); - }); - - it("consumes ruleset-items", () => { - const evaluableRulesetPayload = createEvaluableRulesetPayload( - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "color", - matcher: "eq", - values: ["orange", "blue"] - }, - type: "matcher" - }, - { - definition: { - key: "action", - matcher: "eq", - values: ["lipstick"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ] - } - ] - } - } - ], - scope: "web://mywebsite.com" - }, - eventRegistry, - decisionHistory - ); - - expect( - evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) - ).toEqual({ - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://mywebsite.com" - }); - }); - - it("consumes json-content-items", () => { - const evaluableRulesetPayload = createEvaluableRulesetPayload( - { - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/json-content-item", - data: { - content: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "color", - matcher: "eq", - values: ["orange", "blue"] - }, - type: "matcher" - }, - { - definition: { - key: "action", - matcher: "eq", - values: ["lipstick"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ] - } - ] - } - } - } - ], - scope: "web://mywebsite.com" - }, - eventRegistry, - decisionHistory - ); - - expect( - evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) - ).toEqual({ - scopeDetails: { - decisionProvider: "AJO", - characteristics: { - eventToken: "abc" - }, - strategies: [ - { - strategyID: "3VQe3oIqiYq2RAsYzmDTSf", - treatmentID: "yu7rkogezumca7i0i44v" - } - ], - activity: { - id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" - }, - correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" - }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://mywebsite.com" - }); - }); -}); +// /* +// 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 createEvaluableRulesetPayload from "../../../../../src/components/DecisioningEngine/createEvaluableRulesetPayload"; +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; +// +// describe("DecisioningEngine:createEvaluableRulesetPayload", () => { +// let storage; +// let eventRegistry; +// let decisionHistory; +// +// beforeEach(() => { +// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); +// eventRegistry = createEventRegistry({ storage }); +// decisionHistory = createDecisionHistory({ eventRegistry }); +// }); +// +// it("consumes ruleset-items", () => { +// const evaluableRulesetPayload = createEvaluableRulesetPayload( +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "color", +// matcher: "eq", +// values: ["orange", "blue"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "action", +// matcher: "eq", +// values: ["lipstick"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://mywebsite.com" +// }, +// eventRegistry, +// decisionHistory +// ); +// +// expect( +// evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) +// ).toEqual({ +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://mywebsite.com" +// }); +// }); +// +// it("consumes json-content-items", () => { +// const evaluableRulesetPayload = createEvaluableRulesetPayload( +// { +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/json-content-item", +// data: { +// content: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "color", +// matcher: "eq", +// values: ["orange", "blue"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "action", +// matcher: "eq", +// values: ["lipstick"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ] +// } +// ] +// } +// } +// } +// ], +// scope: "web://mywebsite.com" +// }, +// eventRegistry, +// decisionHistory +// ); +// +// expect( +// evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) +// ).toEqual({ +// scopeDetails: { +// decisionProvider: "AJO", +// characteristics: { +// eventToken: "abc" +// }, +// strategies: [ +// { +// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", +// treatmentID: "yu7rkogezumca7i0i44v" +// } +// ], +// activity: { +// id: +// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" +// }, +// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" +// }, +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://mywebsite.com" +// }); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index 7c5bd3889..14e34520c 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js @@ -1,207 +1,207 @@ -/* -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 createEvaluateRulesetsCommand from "../../../../../src/components/DecisioningEngine/createEvaluateRulesetsCommand"; -import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; - -describe("DecisioningEngine:evaluateRulesetsCommand", () => { - let onDecision; - let applyResponse; - let storage; - let eventRegistry; - let contextProvider; - let decisionProvider; - let evaluateRulesetsCommand; - - beforeEach(() => { - onDecision = jasmine.createSpy(); - applyResponse = createApplyResponse({ onDecision }); - - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - decisionProvider = createDecisionProvider({ eventRegistry }); - - decisionProvider.addPayload({ - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "color", - matcher: "eq", - values: ["orange", "blue"] - }, - type: "matcher" - }, - { - definition: { - key: "action", - matcher: "eq", - values: ["greet"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - } - ] - } - ] - } - } - ], - scope: "web://mywebsite.com" - }); - - evaluateRulesetsCommand = createEvaluateRulesetsCommand({ - contextProvider, - decisionProvider - }); - }); - - it("onDecisions receives renderDecisions=true", () => { - const result = evaluateRulesetsCommand.run({ - renderDecisions: true, - decisionContext: { color: "orange", action: "greet" }, - applyResponse - }); - - const expectedResult = { - propositions: [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - } - ], - scope: "web://mywebsite.com" - } - ] - }; - - expect(result).toEqual(expectedResult); - expect(onDecision).toHaveBeenCalledOnceWith({ - viewName: undefined, - renderDecisions: true, - ...expectedResult - }); - }); - - it("onDecisions receives renderDecisions=false", () => { - const result = evaluateRulesetsCommand.run({ - decisionContext: { color: "orange", action: "greet" }, - applyResponse - }); - - const expectedResult = { - propositions: [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - } - ], - scope: "web://mywebsite.com" - } - ] - }; - - expect(result).toEqual(expectedResult); - expect(onDecision).toHaveBeenCalledOnceWith({ - viewName: undefined, - renderDecisions: false, - ...expectedResult - }); - }); -}); +// /* +// 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 createEvaluateRulesetsCommand from "../../../../../src/components/DecisioningEngine/createEvaluateRulesetsCommand"; +// import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +// import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; +// +// describe("DecisioningEngine:evaluateRulesetsCommand", () => { +// let onDecision; +// let applyResponse; +// let storage; +// let eventRegistry; +// let contextProvider; +// let decisionProvider; +// let evaluateRulesetsCommand; +// +// beforeEach(() => { +// onDecision = jasmine.createSpy(); +// applyResponse = createApplyResponse({ onDecision }); +// +// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); +// eventRegistry = createEventRegistry({ storage }); +// contextProvider = createContextProvider({ eventRegistry, window }); +// decisionProvider = createDecisionProvider({ eventRegistry }); +// +// decisionProvider.addPayload({ +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "color", +// matcher: "eq", +// values: ["orange", "blue"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "action", +// matcher: "eq", +// values: ["greet"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://mywebsite.com" +// }); +// +// evaluateRulesetsCommand = createEvaluateRulesetsCommand({ +// contextProvider, +// decisionProvider +// }); +// }); +// +// it("onDecisions receives renderDecisions=true", () => { +// const result = evaluateRulesetsCommand.run({ +// renderDecisions: true, +// decisionContext: { color: "orange", action: "greet" }, +// applyResponse +// }); +// +// const expectedResult = { +// propositions: [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// } +// ], +// scope: "web://mywebsite.com" +// } +// ] +// }; +// +// expect(result).toEqual(expectedResult); +// expect(onDecision).toHaveBeenCalledOnceWith({ +// viewName: undefined, +// renderDecisions: true, +// ...expectedResult +// }); +// }); +// +// it("onDecisions receives renderDecisions=false", () => { +// const result = evaluateRulesetsCommand.run({ +// decisionContext: { color: "orange", action: "greet" }, +// applyResponse +// }); +// +// const expectedResult = { +// propositions: [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// } +// ], +// scope: "web://mywebsite.com" +// } +// ] +// }; +// +// expect(result).toEqual(expectedResult); +// expect(onDecision).toHaveBeenCalledOnceWith({ +// viewName: undefined, +// renderDecisions: false, +// ...expectedResult +// }); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js index 8a8177164..e33914e05 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -1,384 +1,384 @@ -/* -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 createOnResponseHandler from "../../../../../src/components/DecisioningEngine/createOnResponseHandler"; -import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; - -describe("DecisioningEngine:createOnResponseHandler", () => { - let lifecycle; - let storage; - let eventRegistry; - let decisionProvider; - let applyResponse; - - beforeEach(() => { - lifecycle = jasmine.createSpyObj("lifecycle", { - onDecision: Promise.resolve() - }); - - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventRegistry = createEventRegistry({ storage }); - - decisionProvider = createDecisionProvider({ eventRegistry }); - applyResponse = createApplyResponse(lifecycle); - }); - - it("calls lifecycle.onDecision with propositions based on decisionContext", () => { - const event = { - getViewName: () => undefined, - getContent: () => ({ - xdm: { - web: { - webPageDetails: { - viewName: "contact", - URL: "https://mywebsite.com" - }, - webReferrer: { - URL: "https://google.com" - } - }, - timestamp: new Date().toISOString(), - implementationDetails: { - name: "https://ns.adobe.com/experience/alloy", - version: "2.15.0", - environment: "browser" - } - }, - data: { - moo: "woof" - } - }) - }; - - const decisionContext = { - color: "orange", - action: "lipstick" - }; - - const responseHandler = createOnResponseHandler({ - renderDecisions: true, - decisionProvider, - applyResponse, - event, - decisionContext - }); - - const response = { - getPayloadsByType: () => [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "color", - matcher: "eq", - values: ["orange", "blue"] - }, - type: "matcher" - }, - { - definition: { - key: "action", - matcher: "eq", - values: ["lipstick"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ] - } - ] - } - } - ], - scope: "web://target.jasonwaters.dev/aep.html" - } - ] - }; - - responseHandler({ - response - }); - - expect(lifecycle.onDecision).toHaveBeenCalledWith({ - viewName: undefined, - renderDecisions: true, - propositions: [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", - type: "setAttribute", - content: { - src: "img/demo-marketing-offer1-exp-A.png" - }, - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" - }, - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://target.jasonwaters.dev/aep.html" - } - ] - }); - }); - - it("calls lifecycle.onDecision with propositions based on xdm and event data", () => { - const event = { - getViewName: () => "home", - getContent: () => ({ - xdm: { - web: { - webPageDetails: { - viewName: "contact", - URL: "https://mywebsite.com" - }, - webReferrer: { - URL: "https://google.com" - } - }, - timestamp: new Date().toISOString(), - implementationDetails: { - name: "https://ns.adobe.com/experience/alloy", - version: "12345", - environment: "browser" - } - }, - data: { - moo: "woof" - } - }) - }; - - const decisionContext = {}; - - const responseHandler = createOnResponseHandler({ - renderDecisions: true, - decisionProvider, - applyResponse, - event, - decisionContext - }); - - const response = { - getPayloadsByType: () => [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", - schema: "https://ns.adobe.com/personalization/ruleset-item", - data: { - version: 1, - rules: [ - { - condition: { - definition: { - conditions: [ - { - definition: { - conditions: [ - { - definition: { - key: "xdm.web.webPageDetails.viewName", - matcher: "eq", - values: ["contact"] - }, - type: "matcher" - }, - { - definition: { - key: "xdm.implementationDetails.version", - matcher: "eq", - values: ["12345"] - }, - type: "matcher" - }, - { - definition: { - key: "data.moo", - matcher: "eq", - values: ["woof"] - }, - type: "matcher" - } - ], - logic: "and" - }, - type: "group" - } - ], - logic: "and" - }, - type: "group" - }, - consequences: [ - { - type: "schema", - detail: { - schema: - "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ] - } - ] - } - } - ], - scope: "web://target.jasonwaters.dev/aep.html" - } - ] - }; - - responseHandler({ - response - }); - - expect(lifecycle.onDecision).toHaveBeenCalledWith({ - viewName: "home", - renderDecisions: true, - propositions: [ - { - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", - scopeDetails: { - activity: { - id: "abc#xyz" - } - }, - items: [ - { - schema: "https://ns.adobe.com/personalization/dom-action", - data: { - selector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - type: "setHtml", - content: "Hello Treatment A!", - prehidingSelector: - "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", - qualifiedDate: jasmine.any(Number), - displayedDate: undefined - }, - id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" - } - ], - scope: "web://target.jasonwaters.dev/aep.html" - } - ] - }); - }); -}); +// /* +// 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 createOnResponseHandler from "../../../../../src/components/DecisioningEngine/createOnResponseHandler"; +// import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +// import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// +// describe("DecisioningEngine:createOnResponseHandler", () => { +// let lifecycle; +// let storage; +// let eventRegistry; +// let decisionProvider; +// let applyResponse; +// +// beforeEach(() => { +// lifecycle = jasmine.createSpyObj("lifecycle", { +// onDecision: Promise.resolve() +// }); +// +// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); +// eventRegistry = createEventRegistry({ storage }); +// +// decisionProvider = createDecisionProvider({ eventRegistry }); +// applyResponse = createApplyResponse(lifecycle); +// }); +// +// it("calls lifecycle.onDecision with propositions based on decisionContext", () => { +// const event = { +// getViewName: () => undefined, +// getContent: () => ({ +// xdm: { +// web: { +// webPageDetails: { +// viewName: "contact", +// URL: "https://mywebsite.com" +// }, +// webReferrer: { +// URL: "https://google.com" +// } +// }, +// timestamp: new Date().toISOString(), +// implementationDetails: { +// name: "https://ns.adobe.com/experience/alloy", +// version: "2.15.0", +// environment: "browser" +// } +// }, +// data: { +// moo: "woof" +// } +// }) +// }; +// +// const decisionContext = { +// color: "orange", +// action: "lipstick" +// }; +// +// const responseHandler = createOnResponseHandler({ +// renderDecisions: true, +// decisionProvider, +// applyResponse, +// event, +// decisionContext +// }); +// +// const response = { +// getPayloadsByType: () => [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "color", +// matcher: "eq", +// values: ["orange", "blue"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "action", +// matcher: "eq", +// values: ["lipstick"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://target.jasonwaters.dev/aep.html" +// } +// ] +// }; +// +// responseHandler({ +// response +// }); +// +// expect(lifecycle.onDecision).toHaveBeenCalledWith({ +// viewName: undefined, +// renderDecisions: true, +// propositions: [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", +// type: "setAttribute", +// content: { +// src: "img/demo-marketing-offer1-exp-A.png" +// }, +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" +// }, +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://target.jasonwaters.dev/aep.html" +// } +// ] +// }); +// }); +// +// it("calls lifecycle.onDecision with propositions based on xdm and event data", () => { +// const event = { +// getViewName: () => "home", +// getContent: () => ({ +// xdm: { +// web: { +// webPageDetails: { +// viewName: "contact", +// URL: "https://mywebsite.com" +// }, +// webReferrer: { +// URL: "https://google.com" +// } +// }, +// timestamp: new Date().toISOString(), +// implementationDetails: { +// name: "https://ns.adobe.com/experience/alloy", +// version: "12345", +// environment: "browser" +// } +// }, +// data: { +// moo: "woof" +// } +// }) +// }; +// +// const decisionContext = {}; +// +// const responseHandler = createOnResponseHandler({ +// renderDecisions: true, +// decisionProvider, +// applyResponse, +// event, +// decisionContext +// }); +// +// const response = { +// getPayloadsByType: () => [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", +// schema: "https://ns.adobe.com/personalization/ruleset-item", +// data: { +// version: 1, +// rules: [ +// { +// condition: { +// definition: { +// conditions: [ +// { +// definition: { +// conditions: [ +// { +// definition: { +// key: "xdm.web.webPageDetails.viewName", +// matcher: "eq", +// values: ["contact"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "xdm.implementationDetails.version", +// matcher: "eq", +// values: ["12345"] +// }, +// type: "matcher" +// }, +// { +// definition: { +// key: "data.moo", +// matcher: "eq", +// values: ["woof"] +// }, +// type: "matcher" +// } +// ], +// logic: "and" +// }, +// type: "group" +// } +// ], +// logic: "and" +// }, +// type: "group" +// }, +// consequences: [ +// { +// type: "schema", +// detail: { +// schema: +// "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ] +// } +// ] +// } +// } +// ], +// scope: "web://target.jasonwaters.dev/aep.html" +// } +// ] +// }; +// +// responseHandler({ +// response +// }); +// +// expect(lifecycle.onDecision).toHaveBeenCalledWith({ +// viewName: "home", +// renderDecisions: true, +// propositions: [ +// { +// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", +// scopeDetails: { +// activity: { +// id: "abc#xyz" +// } +// }, +// items: [ +// { +// schema: "https://ns.adobe.com/personalization/dom-action", +// data: { +// selector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// type: "setHtml", +// content: "Hello Treatment A!", +// prehidingSelector: +// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", +// qualifiedDate: jasmine.any(Number), +// displayedDate: undefined +// }, +// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" +// } +// ], +// scope: "web://target.jasonwaters.dev/aep.html" +// } +// ] +// }); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js index e95574d8c..a03339a80 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js @@ -1,56 +1,56 @@ -/* -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 { - mockWindow, - setupResponseHandler, - proposition -} from "./contextTestUtils"; - -describe("DecisioningEngine:globalContext:browser", () => { - let applyResponse; - beforeEach(() => { - applyResponse = jasmine.createSpy(); - }); - it("satisfies rule based on matched browser", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "browser.name", - matcher: "eq", - values: ["chrome"] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched browser", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "browser.name", - matcher: "co", - values: ["Edge"] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); -}); +// /* +// 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 { +// mockWindow, +// setupResponseHandler, +// proposition +// } from "./contextTestUtils"; +// +// describe("DecisioningEngine:globalContext:browser", () => { +// let applyResponse; +// beforeEach(() => { +// applyResponse = jasmine.createSpy(); +// }); +// it("satisfies rule based on matched browser", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "browser.name", +// matcher: "eq", +// values: ["chrome"] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched browser", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "browser.name", +// matcher: "co", +// values: ["Edge"] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js index c6a51c6e2..415dbc281 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js @@ -1,345 +1,345 @@ -/* -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 { - mockWindow, - setupResponseHandler, - proposition -} from "./contextTestUtils"; - -describe("DecisioningEngine:globalContext:page", () => { - let applyResponse; - beforeEach(() => { - applyResponse = jasmine.createSpy(); - }); - - it("satisfies rule based on matched page url", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.url", - matcher: "eq", - values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched page url", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "page.url", - matcher: "eq", - values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfy rule based on matched domain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.domain", - matcher: "eq", - values: ["pro.mywebsite.org"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched domain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.domain", - matcher: "eq", - values: ["pro.mywebsite.com"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfied rule based on matched page subdomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.subdomain", - matcher: "eq", - values: ["pro"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - // Note that we have custom parse url [refer to implementation] which will give empty string in case of www - it("does not satisfy rule due to unmatched page subdomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://www.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.subdomain", - matcher: "eq", - values: ["www"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched page topLevelDomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.topLevelDomain", - matcher: "eq", - values: ["org"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched page topLevelDomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.topLevelDomain", - matcher: "eq", - values: ["com"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched page path", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.path", - matcher: "eq", - values: ["/about"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched page path", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.path", - matcher: "eq", - values: ["/home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched page query", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.query", - matcher: "co", - values: ["name=bob"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched page query", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "page.query", - matcher: "co", - values: ["name=bob"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched page fragment", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" - }), - { - definition: { - key: "page.fragment", - matcher: "eq", - values: ["home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched page fragment", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" - }), - { - definition: { - key: "page.fragment", - matcher: "eq", - values: ["home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); -}); +// /* +// 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 { +// mockWindow, +// setupResponseHandler, +// proposition +// } from "./contextTestUtils"; +// +// describe("DecisioningEngine:globalContext:page", () => { +// let applyResponse; +// beforeEach(() => { +// applyResponse = jasmine.createSpy(); +// }); +// +// it("satisfies rule based on matched page url", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.url", +// matcher: "eq", +// values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched page url", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "page.url", +// matcher: "eq", +// values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfy rule based on matched domain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.domain", +// matcher: "eq", +// values: ["pro.mywebsite.org"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched domain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.domain", +// matcher: "eq", +// values: ["pro.mywebsite.com"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfied rule based on matched page subdomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.subdomain", +// matcher: "eq", +// values: ["pro"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// // Note that we have custom parse url [refer to implementation] which will give empty string in case of www +// it("does not satisfy rule due to unmatched page subdomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://www.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.subdomain", +// matcher: "eq", +// values: ["www"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched page topLevelDomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.topLevelDomain", +// matcher: "eq", +// values: ["org"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched page topLevelDomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.topLevelDomain", +// matcher: "eq", +// values: ["com"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched page path", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.path", +// matcher: "eq", +// values: ["/about"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched page path", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.path", +// matcher: "eq", +// values: ["/home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched page query", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.query", +// matcher: "co", +// values: ["name=bob"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched page query", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "page.query", +// matcher: "co", +// values: ["name=bob"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched page fragment", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" +// }), +// { +// definition: { +// key: "page.fragment", +// matcher: "eq", +// values: ["home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched page fragment", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" +// }), +// { +// definition: { +// key: "page.fragment", +// matcher: "eq", +// values: ["home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js index e0917a202..861de8c9c 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js @@ -1,288 +1,288 @@ -/* -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 { - mockWindow, - setupResponseHandler, - proposition -} from "./contextTestUtils"; - -describe("DecisioningEngine:globalContext:referringPage", () => { - let applyResponse; - beforeEach(() => { - applyResponse = jasmine.createSpy(); - }); - - it("satisfies rule based on matched domain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" - }), - { - definition: { - key: "referringPage.domain", - matcher: "eq", - values: ["business.adobe.com"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched domain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "referringPage.domain", - matcher: "co", - values: ["business.adobe.com"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched referringPage subdomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" - }), - { - definition: { - key: "referringPage.subdomain", - matcher: "co", - values: ["business"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched subdomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "referringPage.subdomain", - matcher: "eq", - values: ["business"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched referringPage topLevelDomain", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "referringPage.topLevelDomain", - matcher: "eq", - values: ["com"] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched topLevelDomain", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "referringPage.topLevelDomain", - matcher: "eq", - values: ["com"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched referringPage path", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "referringPage.path", - matcher: "co", - values: ["/search"] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched referringPage path", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "referringPage.path", - matcher: "co", - values: ["/search"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched referringPage query", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "referringPage.query", - matcher: "co", - values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched referringPage query", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" - }), - { - definition: { - key: "referringPage.query", - matcher: "co", - values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched referringPage fragment", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: - "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" - }), - { - definition: { - key: "referringPage.fragment", - matcher: "co", - values: ["home"] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule based on unmatched referringPage fragment", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - referrer: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" - }), - { - definition: { - key: "referringPage.fragment", - matcher: "co", - values: ["home"] - }, - type: "matcher" - } - ); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); -}); +// /* +// 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 { +// mockWindow, +// setupResponseHandler, +// proposition +// } from "./contextTestUtils"; +// +// describe("DecisioningEngine:globalContext:referringPage", () => { +// let applyResponse; +// beforeEach(() => { +// applyResponse = jasmine.createSpy(); +// }); +// +// it("satisfies rule based on matched domain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" +// }), +// { +// definition: { +// key: "referringPage.domain", +// matcher: "eq", +// values: ["business.adobe.com"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched domain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "referringPage.domain", +// matcher: "co", +// values: ["business.adobe.com"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched referringPage subdomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" +// }), +// { +// definition: { +// key: "referringPage.subdomain", +// matcher: "co", +// values: ["business"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched subdomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "referringPage.subdomain", +// matcher: "eq", +// values: ["business"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched referringPage topLevelDomain", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "referringPage.topLevelDomain", +// matcher: "eq", +// values: ["com"] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched topLevelDomain", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "referringPage.topLevelDomain", +// matcher: "eq", +// values: ["com"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched referringPage path", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "referringPage.path", +// matcher: "co", +// values: ["/search"] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched referringPage path", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "referringPage.path", +// matcher: "co", +// values: ["/search"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched referringPage query", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "referringPage.query", +// matcher: "co", +// values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched referringPage query", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" +// }), +// { +// definition: { +// key: "referringPage.query", +// matcher: "co", +// values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched referringPage fragment", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: +// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" +// }), +// { +// definition: { +// key: "referringPage.fragment", +// matcher: "co", +// values: ["home"] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule based on unmatched referringPage fragment", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// referrer: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" +// }), +// { +// definition: { +// key: "referringPage.fragment", +// matcher: "co", +// values: ["home"] +// }, +// type: "matcher" +// } +// ); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js index d161c374a..0c1dcb7a7 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js @@ -1,334 +1,334 @@ -/* -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 { - mockWindow, - setupResponseHandler, - proposition -} from "./contextTestUtils"; - -let mockedTimestamp; -describe("DecisioningEngine:globalContext:timeContext", () => { - let applyResponse; - beforeEach(() => { - applyResponse = jasmine.createSpy(); - mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 13, 34, 56)); - jasmine.clock().install(); - jasmine.clock().mockDate(mockedTimestamp); - }); - afterEach(() => { - jasmine.clock().uninstall(); - }); - - it("satisfies rule based on matched pageLoadTimestamp", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "pageLoadTimestamp", - matcher: "eq", - values: [mockedTimestamp.getTime()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched pageLoadTimestamp", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "pageLoadTimestamp", - matcher: "eq", - values: [mockedTimestamp.getTime() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentTimestamp", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentTimestamp", - matcher: "eq", - values: [mockedTimestamp.getTime()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentTimestamp", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentTimestamp", - matcher: "eq", - values: [mockedTimestamp.getTime() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentDate", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentDate", - matcher: "eq", - values: [mockedTimestamp.getDate()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentDate", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentDate", - matcher: "eq", - values: [mockedTimestamp.getDate() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentDay", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentDay", - matcher: "eq", - values: [mockedTimestamp.getDay()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentDay", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentDay", - matcher: "eq", - values: [mockedTimestamp.getDay() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentHour", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentHour", - matcher: "eq", - values: [mockedTimestamp.getHours()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentHour", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentHour", - matcher: "eq", - values: [mockedTimestamp.getHours() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentMinute", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentMinute", - matcher: "eq", - values: [mockedTimestamp.getMinutes()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentMinute", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentMinute", - matcher: "eq", - values: [mockedTimestamp.getMinutes() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentMonth", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentMonth", - matcher: "eq", - values: [mockedTimestamp.getMonth()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentMonth", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentMonth", - matcher: "eq", - values: [mockedTimestamp.getMonth() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched currentYear", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentYear", - matcher: "eq", - values: [mockedTimestamp.getFullYear()] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched currentYear", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "currentYear", - matcher: "eq", - values: [mockedTimestamp.getFullYear() + 1] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched pageVisitDuration", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "pageVisitDuration", - matcher: "eq", - values: [0] - }, - type: "matcher" - }); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched pageVisitDuration", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "pageVisitDuration", - matcher: "eq", - values: [1] - }, - type: "matcher" - }); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); -}); +// /* +// 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 { +// mockWindow, +// setupResponseHandler, +// proposition +// } from "./contextTestUtils"; +// +// let mockedTimestamp; +// describe("DecisioningEngine:globalContext:timeContext", () => { +// let applyResponse; +// beforeEach(() => { +// applyResponse = jasmine.createSpy(); +// mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 13, 34, 56)); +// jasmine.clock().install(); +// jasmine.clock().mockDate(mockedTimestamp); +// }); +// afterEach(() => { +// jasmine.clock().uninstall(); +// }); +// +// it("satisfies rule based on matched pageLoadTimestamp", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "pageLoadTimestamp", +// matcher: "eq", +// values: [mockedTimestamp.getTime()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched pageLoadTimestamp", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "pageLoadTimestamp", +// matcher: "eq", +// values: [mockedTimestamp.getTime() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentTimestamp", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentTimestamp", +// matcher: "eq", +// values: [mockedTimestamp.getTime()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentTimestamp", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentTimestamp", +// matcher: "eq", +// values: [mockedTimestamp.getTime() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentDate", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentDate", +// matcher: "eq", +// values: [mockedTimestamp.getDate()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentDate", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentDate", +// matcher: "eq", +// values: [mockedTimestamp.getDate() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentDay", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentDay", +// matcher: "eq", +// values: [mockedTimestamp.getDay()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentDay", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentDay", +// matcher: "eq", +// values: [mockedTimestamp.getDay() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentHour", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentHour", +// matcher: "eq", +// values: [mockedTimestamp.getHours()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentHour", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentHour", +// matcher: "eq", +// values: [mockedTimestamp.getHours() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentMinute", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentMinute", +// matcher: "eq", +// values: [mockedTimestamp.getMinutes()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentMinute", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentMinute", +// matcher: "eq", +// values: [mockedTimestamp.getMinutes() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentMonth", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentMonth", +// matcher: "eq", +// values: [mockedTimestamp.getMonth()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentMonth", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentMonth", +// matcher: "eq", +// values: [mockedTimestamp.getMonth() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched currentYear", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentYear", +// matcher: "eq", +// values: [mockedTimestamp.getFullYear()] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched currentYear", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "currentYear", +// matcher: "eq", +// values: [mockedTimestamp.getFullYear() + 1] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched pageVisitDuration", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "pageVisitDuration", +// matcher: "eq", +// values: [0] +// }, +// type: "matcher" +// }); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched pageVisitDuration", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "pageVisitDuration", +// matcher: "eq", +// values: [1] +// }, +// type: "matcher" +// }); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js index d02df3304..879749f31 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js @@ -1,185 +1,185 @@ -/* -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 { - mockWindow, - setupResponseHandler, - proposition -} from "./contextTestUtils"; - -describe("DecisioningEngine:globalContext:window", () => { - let applyResponse; - beforeEach(() => { - applyResponse = jasmine.createSpy(); - }); - - it("satisfies rule based on matched window height", () => { - setupResponseHandler(applyResponse, mockWindow({}), { - definition: { - key: "window.height", - matcher: "gt", - values: [90] - }, - type: "matcher" - }); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched window height", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - height: 50 - }), - { - definition: { - key: "window.height", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched window width", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - width: 200 - }), - { - definition: { - key: "window.width", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched window width", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - width: 50 - }), - { - definition: { - key: "window.width", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched window scrollX", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - scrollX: 200 - }), - { - definition: { - key: "window.scrollX", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [proposition] - }) - ); - }); - - it("does not satisfy rule due to unmatched window scrollX", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - scrollX: 50 - }), - { - definition: { - key: "window.scrollX", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - expect(applyResponse).toHaveBeenCalledOnceWith( - jasmine.objectContaining({ - propositions: [] - }) - ); - }); - - it("satisfies rule based on matched window scrollY", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - scrollY: 200 - }), - { - definition: { - key: "window.scrollY", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - }); - - it("does not satisfy rule due to unmatched window scrollY", () => { - setupResponseHandler( - applyResponse, - mockWindow({ - scrollY: 50 - }), - { - definition: { - key: "window.scrollY", - matcher: "gt", - values: [90] - }, - type: "matcher" - } - ); - }); -}); +// /* +// 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 { +// mockWindow, +// setupResponseHandler, +// proposition +// } from "./contextTestUtils"; +// +// describe("DecisioningEngine:globalContext:window", () => { +// let applyResponse; +// beforeEach(() => { +// applyResponse = jasmine.createSpy(); +// }); +// +// it("satisfies rule based on matched window height", () => { +// setupResponseHandler(applyResponse, mockWindow({}), { +// definition: { +// key: "window.height", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// }); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched window height", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// height: 50 +// }), +// { +// definition: { +// key: "window.height", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched window width", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// width: 200 +// }), +// { +// definition: { +// key: "window.width", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched window width", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// width: 50 +// }), +// { +// definition: { +// key: "window.width", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched window scrollX", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// scrollX: 200 +// }), +// { +// definition: { +// key: "window.scrollX", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [proposition] +// }) +// ); +// }); +// +// it("does not satisfy rule due to unmatched window scrollX", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// scrollX: 50 +// }), +// { +// definition: { +// key: "window.scrollX", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// expect(applyResponse).toHaveBeenCalledOnceWith( +// jasmine.objectContaining({ +// propositions: [] +// }) +// ); +// }); +// +// it("satisfies rule based on matched window scrollY", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// scrollY: 200 +// }), +// { +// definition: { +// key: "window.scrollY", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// }); +// +// it("does not satisfy rule due to unmatched window scrollY", () => { +// setupResponseHandler( +// applyResponse, +// mockWindow({ +// scrollY: 50 +// }), +// { +// definition: { +// key: "window.scrollY", +// matcher: "gt", +// values: [90] +// }, +// type: "matcher" +// } +// ); +// }); +// }); diff --git a/test/unit/specs/components/DecisioningEngine/index.spec.js b/test/unit/specs/components/DecisioningEngine/index.spec.js index 17980fffb..d56224cd2 100644 --- a/test/unit/specs/components/DecisioningEngine/index.spec.js +++ b/test/unit/specs/components/DecisioningEngine/index.spec.js @@ -1,171 +1,171 @@ -/* -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 createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; -import { injectStorage } from "../../../../../src/utils"; -import { - mockRulesetResponseWithCondition, - proposition -} from "./contextTestUtils"; - -describe("createDecisioningEngine:commands:evaluateRulesets", () => { - let mergeData; - let mockEvent; - let onResponseHandler; - let decisioningEngine; - beforeEach(() => { - mergeData = jasmine.createSpy(); - const config = { orgId: "exampleOrgId" }; - window.referrer = - "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; - const createNamespacedStorage = injectStorage(window); - decisioningEngine = createDecisioningEngine({ - config, - createNamespacedStorage - }); - mockEvent = { - getContent: () => ({}), - getViewName: () => undefined, - mergeData - }; - decisioningEngine.lifecycle.onComponentsRegistered(() => {}); - }); - - it("should run the evaluateRulesets command and satisfy the rule based on global context", () => { - onResponseHandler = onResponse => { - onResponse({ - response: mockRulesetResponseWithCondition({ - definition: { - key: "referringPage.path", - matcher: "eq", - values: ["/search"] - }, - type: "matcher" - }) - }); - }; - decisioningEngine.lifecycle.onBeforeEvent({ - event: mockEvent, - renderDecisions: true, - decisionContext: {}, - onResponse: onResponseHandler - }); - const result = decisioningEngine.commands.evaluateRulesets.run({}); - expect(result).toEqual({ - propositions: [proposition] - }); - }); - - it("should run the evaluateRulesets command and does not satisfy rule due to unmatched global context", () => { - onResponseHandler = onResponse => { - onResponse({ - response: mockRulesetResponseWithCondition({ - definition: { - key: "referringPage.path", - matcher: "eq", - values: ["/about"] - }, - type: "matcher" - }) - }); - }; - decisioningEngine.lifecycle.onBeforeEvent({ - event: mockEvent, - renderDecisions: true, - decisionContext: {}, - onResponse: onResponseHandler - }); - const result = decisioningEngine.commands.evaluateRulesets.run({}); - expect(result).toEqual({ - propositions: [] - }); - }); - - it("should run the evaluateRulesets command and return propositions with renderDecisions true", () => { - onResponseHandler = onResponse => { - onResponse({ - response: mockRulesetResponseWithCondition({ - definition: { - key: "referringPage.path", - matcher: "eq", - values: ["/search"] - }, - type: "matcher" - }) - }); - }; - decisioningEngine.lifecycle.onBeforeEvent({ - event: mockEvent, - renderDecisions: true, - decisionContext: {}, - onResponse: onResponseHandler - }); - const result = decisioningEngine.commands.evaluateRulesets.run({}); - expect(result).toEqual({ - propositions: [proposition] - }); - }); - - it("should run the evaluateRulesets command returns propositions with renderDecisions false", () => { - onResponseHandler = onResponse => { - onResponse({ - response: mockRulesetResponseWithCondition({ - definition: { - key: "referringPage.path", - matcher: "eq", - values: ["/search"] - }, - type: "matcher" - }) - }); - }; - decisioningEngine.lifecycle.onBeforeEvent({ - event: mockEvent, - renderDecisions: false, - decisionContext: {}, - onResponse: onResponseHandler - }); - const result = decisioningEngine.commands.evaluateRulesets.run({}); - expect(result).toEqual({ - propositions: [proposition] - }); - }); - - it("ensures schema-based ruleset consequences", () => { - onResponseHandler = onResponse => { - onResponse({ - response: mockRulesetResponseWithCondition({ - definition: { - key: "referringPage.path", - matcher: "eq", - values: ["/search"] - }, - type: "matcher" - }) - }); - }; - - decisioningEngine.lifecycle.onBeforeEvent({ - event: mockEvent, - renderDecisions: false, - decisionContext: {}, - onResponse: onResponseHandler - }); - - expect(mergeData).toHaveBeenCalledOnceWith({ - __adobe: { - ajo: { - "in-app-response-format": 2 - } - } - }); - }); -}); +// /* +// 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 createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; +// import { injectStorage } from "../../../../../src/utils"; +// import { +// mockRulesetResponseWithCondition, +// proposition +// } from "./contextTestUtils"; +// +// describe("createDecisioningEngine:commands:evaluateRulesets", () => { +// let mergeData; +// let mockEvent; +// let onResponseHandler; +// let decisioningEngine; +// beforeEach(() => { +// mergeData = jasmine.createSpy(); +// const config = { orgId: "exampleOrgId" }; +// window.referrer = +// "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; +// const createNamespacedStorage = injectStorage(window); +// decisioningEngine = createDecisioningEngine({ +// config, +// createNamespacedStorage +// }); +// mockEvent = { +// getContent: () => ({}), +// getViewName: () => undefined, +// mergeData +// }; +// decisioningEngine.lifecycle.onComponentsRegistered(() => {}); +// }); +// +// it("should run the evaluateRulesets command and satisfy the rule based on global context", () => { +// onResponseHandler = onResponse => { +// onResponse({ +// response: mockRulesetResponseWithCondition({ +// definition: { +// key: "referringPage.path", +// matcher: "eq", +// values: ["/search"] +// }, +// type: "matcher" +// }) +// }); +// }; +// decisioningEngine.lifecycle.onBeforeEvent({ +// event: mockEvent, +// renderDecisions: true, +// decisionContext: {}, +// onResponse: onResponseHandler +// }); +// const result = decisioningEngine.commands.evaluateRulesets.run({}); +// expect(result).toEqual({ +// propositions: [proposition] +// }); +// }); +// +// it("should run the evaluateRulesets command and does not satisfy rule due to unmatched global context", () => { +// onResponseHandler = onResponse => { +// onResponse({ +// response: mockRulesetResponseWithCondition({ +// definition: { +// key: "referringPage.path", +// matcher: "eq", +// values: ["/about"] +// }, +// type: "matcher" +// }) +// }); +// }; +// decisioningEngine.lifecycle.onBeforeEvent({ +// event: mockEvent, +// renderDecisions: true, +// decisionContext: {}, +// onResponse: onResponseHandler +// }); +// const result = decisioningEngine.commands.evaluateRulesets.run({}); +// expect(result).toEqual({ +// propositions: [] +// }); +// }); +// +// it("should run the evaluateRulesets command and return propositions with renderDecisions true", () => { +// onResponseHandler = onResponse => { +// onResponse({ +// response: mockRulesetResponseWithCondition({ +// definition: { +// key: "referringPage.path", +// matcher: "eq", +// values: ["/search"] +// }, +// type: "matcher" +// }) +// }); +// }; +// decisioningEngine.lifecycle.onBeforeEvent({ +// event: mockEvent, +// renderDecisions: true, +// decisionContext: {}, +// onResponse: onResponseHandler +// }); +// const result = decisioningEngine.commands.evaluateRulesets.run({}); +// expect(result).toEqual({ +// propositions: [proposition] +// }); +// }); +// +// it("should run the evaluateRulesets command returns propositions with renderDecisions false", () => { +// onResponseHandler = onResponse => { +// onResponse({ +// response: mockRulesetResponseWithCondition({ +// definition: { +// key: "referringPage.path", +// matcher: "eq", +// values: ["/search"] +// }, +// type: "matcher" +// }) +// }); +// }; +// decisioningEngine.lifecycle.onBeforeEvent({ +// event: mockEvent, +// renderDecisions: false, +// decisionContext: {}, +// onResponse: onResponseHandler +// }); +// const result = decisioningEngine.commands.evaluateRulesets.run({}); +// expect(result).toEqual({ +// propositions: [proposition] +// }); +// }); +// +// it("ensures schema-based ruleset consequences", () => { +// onResponseHandler = onResponse => { +// onResponse({ +// response: mockRulesetResponseWithCondition({ +// definition: { +// key: "referringPage.path", +// matcher: "eq", +// values: ["/search"] +// }, +// type: "matcher" +// }) +// }); +// }; +// +// decisioningEngine.lifecycle.onBeforeEvent({ +// event: mockEvent, +// renderDecisions: false, +// decisionContext: {}, +// onResponse: onResponseHandler +// }); +// +// expect(mergeData).toHaveBeenCalledOnceWith({ +// __adobe: { +// ajo: { +// "in-app-response-format": 2 +// } +// } +// }); +// }); +// }); From 34415efec92286908646063108cb2b31b2ec1d41 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Sun, 1 Oct 2023 21:12:56 -0700 Subject: [PATCH 07/27] Introduce indexedDB registry --- .../createDecisionProvider.js | 1 + .../createEvaluableRulesetPayload.js | 32 +++--- .../createEvaluateRulesetsCommand.js | 4 +- .../createHistoricalRegistry.js | 98 ++++++++----------- 4 files changed, 62 insertions(+), 73 deletions(-) diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 24baf72a8..07b4dd9b2 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -46,6 +46,7 @@ export default ({ eventRegistry }) => { }; return { + // TODO: remove addPayload below if unsed from outside of this file. addPayload, addPayloads, evaluate diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index b60e80bda..acbb86bb1 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -14,7 +14,7 @@ import { JSON_CONTENT_ITEM, RULESET_ITEM } from "../Personalization/constants/schema"; -import { DISPLAY } from "../Personalization/constants/eventType"; +import { PropositionEventType } from "../Personalization/constants/propositionEventType"; import flattenArray from "../../utils/flattenArray"; import createConsequenceAdapter from "./createConsequenceAdapter"; @@ -61,29 +61,33 @@ export default (payload, eventRegistry, decisionHistory) => { }; const evaluate = async context => { - const displayEvent = eventRegistry.getEvent(DISPLAY, payload.id); - - const displayedDate = displayEvent - ? displayEvent.firstTimestamp - : undefined; + const displayedDate = await eventRegistry.getEventsFirstTimestamp( + PropositionEventType.DISPLAY, + activityId + ); - console.log("items are ", items); const consequences = await Promise.all( items.map(item => item.execute(context)) ); - const qualifyingItems = flattenArray(consequences) - .map(consequenceAdapter) - .map(item => { - const { - firstTimestamp: qualifiedDate - } = decisionHistory.recordQualified(activityId); + const consequencesFlattened = flattenArray(consequences).map( + consequenceAdapter + ); + let qualifyingItems = []; + if (consequencesFlattened.length > 0) { + await decisionHistory.recordQualified(activityId); + const qualifiedDate = await eventRegistry.getEventsFirstTimestamp( + PropositionEventType.TRIGGER, + activityId + ); + qualifyingItems = consequencesFlattened.map(item => { return { ...item, data: { ...item.data, qualifiedDate, displayedDate } }; }); - console.log("qualifyingItems are ", qualifyingItems); + } + return { ...payload, items: qualifyingItems diff --git a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js index ae5bfb73f..1362aee48 100644 --- a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js +++ b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js @@ -21,10 +21,10 @@ const validateOptions = ({ options }) => { }; export default ({ contextProvider, decisionProvider }) => { - const run = ({ renderDecisions, decisionContext, applyResponse }) => { + const run = async ({ renderDecisions, decisionContext, applyResponse }) => { return applyResponse({ renderDecisions, - propositions: decisionProvider.evaluate( + propositions: await decisionProvider.evaluate( contextProvider.getContext(decisionContext) ) }); diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js index a64362079..a29a22dde 100644 --- a/src/components/DecisioningEngine/createHistoricalRegistry.js +++ b/src/components/DecisioningEngine/createHistoricalRegistry.js @@ -74,53 +74,19 @@ export default () => { timestamp: new Date().getTime() }; - objectStore.add(record); - // debounce(() => { - // objectStore.add(record); - // }, 500); - transaction.onerror = txEvent => { + const objectStoreRequest = objectStore.add(record); + + objectStoreRequest.onerror = txEvent => { const dbRequest = txEvent.target; reject(dbRequest.error); }; - transaction.onsuccess = () => { + objectStoreRequest.onsuccess = async () => { resolve(true); }; }); - - // debounce(async () => { - // - // }, 500); }; - // const addEvent = (event, eventType, eventId, action) => { - // return new Promise((resolve, reject) => { - // const transaction = db.transaction("events", "readwrite"); - // const objectStore = transaction.objectStore("events"); - // - // console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); - // - // const record = { - // [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, - // [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, - // [PREFIX_TO_SUPPORT_INDEX_DB("action")]: action, - // timestamp: new Date().getTime() - // }; - // - // objectStore.add(record); - // transaction.onerror = txEvent => { - // const dbRequest = txEvent.target; - // reject(dbRequest.error); - // }; - // - // transaction.onsuccess = () => { - // // const updatedRecord = replaceDotsWithUnderscores(records[0]); - // // objectStore.add(updatedRecord); - // resolve(true); - // }; - // }); - // }; - const addExperienceEdgeEvent = event => { const { xdm = {} } = event.getContent(); const { eventType = "", _experience } = xdm; @@ -164,28 +130,45 @@ export default () => { }); }; - const getEvent = (eventType, eventId) => { + const getEvents = (eventType, eventId) => { return new Promise((resolve, reject) => { - try { - const transaction = db.transaction("events", "readonly"); - const objectStore = transaction.objectStore("events"); - const index = objectStore.index("iam_id_iam_eventType_index"); - - const request = index.getAll([eventId, eventType]); - - request.onsuccess = eventObjStore => { - const dbRequest = eventObjStore.target; - const data = dbRequest - ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) - : []; - resolve(data); - }; - } catch (error) { - reject(error); - } + const transaction = db.transaction("events", "readonly"); + const objectStore = transaction.objectStore("events"); + const index = objectStore.index("iam_id_iam_eventType_index"); + + const request = index.getAll([eventId, eventType]); + + request.onsuccess = eventObjStore => { + const dbRequest = eventObjStore.target; + const data = dbRequest + ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) + : []; + resolve(data); + }; + + request.onerror = eventObjStore => { + const dbRequest = eventObjStore.target; + reject(dbRequest.error); + }; }); }; + const getEventsFirstTimestamp = async (eventType, eventId) => { + const events = await getEvents(eventType, eventId); + + if (!events || events.length === 0) { + return undefined; + } + + return events.reduce( + (earliestTimestamp, currentEvent) => + earliestTimestamp < currentEvent.timestamp + ? earliestTimestamp + : currentEvent.timestamp, + events[0].timestamp + ); + }; + setupIndexedDB() .then(() => { console.log("IndexedDB setup complete."); @@ -198,7 +181,8 @@ export default () => { setupIndexedDB, addEvent, addExperienceEdgeEvent, - getEvent, + getEvents, + getEventsFirstTimestamp, getIndexDB: () => db }; }; From df3699962a803033afa477d33b9daeacfb961afd Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 2 Oct 2023 00:20:18 -0700 Subject: [PATCH 08/27] Introduce indexedDB registry --- .../createDecisionProvider.js | 14 ++-- .../createEvaluableRulesetPayload.js | 78 +++++++++++-------- .../createEvaluateRulesetsCommand.js | 14 ++-- .../createHistoricalRegistry.js | 35 +++++---- .../createOnResponseHandler.js | 10 ++- 5 files changed, 89 insertions(+), 62 deletions(-) diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 07b4dd9b2..0384d9d86 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -33,12 +33,14 @@ export default ({ eventRegistry }) => { } }; - const evaluate = async (context = {}) => { - const consequences = await Promise.all( - Object.values(payloads).map(payload => payload.evaluate(context)) - ); - - return consequences.filter(payload => payload.items.length > 0); + const evaluate = (context = {}) => { + return new Promise(resolve => { + Promise.all( + Object.values(payloads).map(payload => payload.evaluate(context)) + ).then(consequences => { + resolve(consequences.filter(payload => payload.items.length > 0)); + }); + }); }; const addPayloads = personalizationPayloads => { diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index acbb86bb1..e8b93202c 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -60,38 +60,52 @@ export default (payload, eventRegistry, decisionHistory) => { ); }; - const evaluate = async context => { - const displayedDate = await eventRegistry.getEventsFirstTimestamp( - PropositionEventType.DISPLAY, - activityId - ); - - const consequences = await Promise.all( - items.map(item => item.execute(context)) - ); - const consequencesFlattened = flattenArray(consequences).map( - consequenceAdapter - ); - - let qualifyingItems = []; - if (consequencesFlattened.length > 0) { - await decisionHistory.recordQualified(activityId); - const qualifiedDate = await eventRegistry.getEventsFirstTimestamp( - PropositionEventType.TRIGGER, - activityId - ); - qualifyingItems = consequencesFlattened.map(item => { - return { - ...item, - data: { ...item.data, qualifiedDate, displayedDate } - }; - }); - } - - return { - ...payload, - items: qualifyingItems - }; + const evaluate = context => { + return new Promise(resolve => { + let consequencesFlattened = []; + Promise.all(items.map(item => item.execute(context))) + .then(consequences => { + consequencesFlattened = flattenArray(consequences).map( + consequenceAdapter + ); + if (!consequencesFlattened || consequencesFlattened.length === 0) { + resolve({ + ...payload, + items: [] + }); + return; + } + + decisionHistory.recordQualified(activityId); + }) + .then(() => + Promise.all([ + eventRegistry.getEventsFirstTimestamp( + PropositionEventType.DISPLAY, + activityId + ), + eventRegistry.getEventsFirstTimestamp( + PropositionEventType.TRIGGER, + activityId + ) + ]) + ) + .then(dates => { + const displayedDate = dates[0]; + const qualifiedDate = dates[1]; + const qualifyingItems = consequencesFlattened.map(item => { + return { + ...item, + data: { ...item.data, qualifiedDate, displayedDate } + }; + }); + + resolve({ + ...payload, + items: qualifyingItems + }); + }); + }); }; if (Array.isArray(payload.items)) { diff --git a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js index 1362aee48..210166a74 100644 --- a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js +++ b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js @@ -21,12 +21,14 @@ const validateOptions = ({ options }) => { }; export default ({ contextProvider, decisionProvider }) => { - const run = async ({ renderDecisions, decisionContext, applyResponse }) => { - return applyResponse({ - renderDecisions, - propositions: await decisionProvider.evaluate( - contextProvider.getContext(decisionContext) - ) + const run = ({ renderDecisions, decisionContext, applyResponse }) => { + return new Promise(resolve => { + decisionProvider + .evaluate(contextProvider.getContext(decisionContext)) + .then(propositions => { + applyResponse({ renderDecisions, propositions }); + resolve(); + }); }); }; diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js index a29a22dde..6cf8c40b5 100644 --- a/src/components/DecisioningEngine/createHistoricalRegistry.js +++ b/src/components/DecisioningEngine/createHistoricalRegistry.js @@ -81,7 +81,7 @@ export default () => { reject(dbRequest.error); }; - objectStoreRequest.onsuccess = async () => { + objectStoreRequest.onsuccess = () => { resolve(true); }; }); @@ -153,20 +153,25 @@ export default () => { }); }; - const getEventsFirstTimestamp = async (eventType, eventId) => { - const events = await getEvents(eventType, eventId); - - if (!events || events.length === 0) { - return undefined; - } - - return events.reduce( - (earliestTimestamp, currentEvent) => - earliestTimestamp < currentEvent.timestamp - ? earliestTimestamp - : currentEvent.timestamp, - events[0].timestamp - ); + const getEventsFirstTimestamp = (eventType, eventId) => { + return new Promise(resolve => { + getEvents(eventType, eventId).then(events => { + if (!events || events.length === 0) { + resolve(undefined); + return; + } + + resolve( + events.reduce( + (earliestTimestamp, currentEvent) => + earliestTimestamp < currentEvent.timestamp + ? earliestTimestamp + : currentEvent.timestamp, + events[0].timestamp + ) + ); + }); + }); }; setupIndexedDB() diff --git a/src/components/DecisioningEngine/createOnResponseHandler.js b/src/components/DecisioningEngine/createOnResponseHandler.js index 40548f7bd..f91ca535b 100644 --- a/src/components/DecisioningEngine/createOnResponseHandler.js +++ b/src/components/DecisioningEngine/createOnResponseHandler.js @@ -25,12 +25,16 @@ export default ({ }; const viewName = event.getViewName(); - return async ({ response }) => { + return ({ response }) => { decisionProvider.addPayloads( response.getPayloadsByType(PERSONALIZATION_DECISIONS_HANDLE) ); - const propositions = await decisionProvider.evaluate(context); - applyResponse({ viewName, renderDecisions, propositions }); + return new Promise(resolve => { + decisionProvider.evaluate(context).then(propositions => { + applyResponse({ viewName, renderDecisions, propositions }); + resolve(); + }); + }); }; }; From 85a96f0d0e13838d46a146d378d7e93c2148d26a Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 2 Oct 2023 09:45:03 -0700 Subject: [PATCH 09/27] not using regenerator-runtime --- package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index fc061804c..7d1649bea 100644 --- a/package.json +++ b/package.json @@ -64,11 +64,9 @@ "@adobe/reactor-load-script": "^1.1.1", "@adobe/reactor-object-assign": "^1.0.0", "@adobe/reactor-query-string": "^1.0.0", - "@babel/runtime": "^7.23.1", "css.escape": "^1.5.1", "js-cookie": "2.2.1", "parse-uri": "^1.0.7", - "regenerator-runtime": "^0.14.0", "uuid": "^3.3.2" }, "devDependencies": { @@ -78,11 +76,8 @@ "@babel/plugin-proposal-object-rest-spread": "^7.3.2", "@babel/plugin-transform-runtime": "^7.16.4", "@babel/plugin-transform-template-literals": "^7.4.4", - "@babel/preset-env": "^7.22.20", + "@babel/preset-env": "^7.4.5", "@octokit/rest": "^18.3.5", - "babel-loader": "^9.1.3", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-version": "^0.2.3", "bundlesize": "^0.18.0", "chalk": "^2.4.2", From 95c1ae026693c5522aa10e396fd504294cbdef89 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 2 Oct 2023 09:56:23 -0700 Subject: [PATCH 10/27] use action --- src/components/DecisioningEngine/createHistoricalRegistry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js index 6cf8c40b5..0e16a8da6 100644 --- a/src/components/DecisioningEngine/createHistoricalRegistry.js +++ b/src/components/DecisioningEngine/createHistoricalRegistry.js @@ -70,7 +70,7 @@ export default () => { const record = { [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, - [PREFIX_TO_SUPPORT_INDEX_DB("action")]: action, + action, timestamp: new Date().getTime() }; From 1e8745673bc4c7b0d951e06593a47f8d49d78bb5 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 2 Oct 2023 10:11:41 -0700 Subject: [PATCH 11/27] fix for trigger frequency show message on specific hourofday --- src/components/DecisioningEngine/createContextProvider.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 8482573d3..47fc1ea1c 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -47,7 +47,8 @@ export default ({ eventRegistry, window }) => { currentMinute: now.getMinutes(), currentMonth: now.getMonth(), currentYear: now.getFullYear(), - pageVisitDuration: currentTimestamp - pageLoadTimestamp + pageVisitDuration: currentTimestamp - pageLoadTimestamp, + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.hourofday": now.getHours() }; }; From 3c69ae3659cf7b242844140134b814f03bebc607 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 2 Oct 2023 13:14:45 -0700 Subject: [PATCH 12/27] clean up, keeping just eventRegistry as before --- .../createContextProvider.js | 1 - .../DecisioningEngine/createEventRegistry.js | 173 ++++++++++++---- .../createHistoricalRegistry.js | 193 ------------------ src/components/DecisioningEngine/index.js | 25 +-- 4 files changed, 134 insertions(+), 258 deletions(-) delete mode 100644 src/components/DecisioningEngine/createHistoricalRegistry.js diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 47fc1ea1c..0e8bbe456 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -88,7 +88,6 @@ export default ({ eventRegistry, window }) => { return { ...flattenObject(context), events: eventRegistry.getIndexDB() - // events: eventRegistry.toJSON() }; }; return { diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 53a5b94d4..0e16a8da6 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -9,51 +9,82 @@ 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 { - createRestoreStorage, - createSaveStorage, - getActivityId -} from "./utils"; +import { HISTORICAL_DATA_STORE } from "./constants"; import { EVENT_TYPE_TRUE } from "../Personalization/event"; +import { getActivityId } from "./utils"; -const STORAGE_KEY = "events"; -const DEFAULT_SAVE_DELAY = 500; +const dbName = HISTORICAL_DATA_STORE; +const PREFIX_TO_SUPPORT_INDEX_DB = key => `iam_${key}`; -const prefixed = key => `iam.${key}`; +export default () => { + let db; -export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { - const restore = createRestoreStorage(storage, STORAGE_KEY); - const save = createSaveStorage(storage, STORAGE_KEY, saveDelay); + const replaceUnderscoreWithDot = record => { + const updatedRecord = {}; + Object.keys(record).forEach(key => { + updatedRecord[key.replace("/_/g", ".")] = record[key]; + }); + return updatedRecord; + }; - const events = restore({}); - const addEvent = (event, eventType, eventId, action) => { - if (!events[eventType]) { - events[eventType] = {}; - } + const setupIndexedDB = () => { + return new Promise((resolve, reject) => { + if (!("indexedDB" in window)) { + reject(new Error("This browser doesn't support IndexedDB.")); + } + + const request = indexedDB.open(dbName, 1); + + request.onerror = event => { + const dbRequest = event.target; + reject(dbRequest.error); + }; + + request.onupgradeneeded = event => { + db = event.target.result; + + const objectStore = db.createObjectStore("events", { + keyPath: "id", + autoIncrement: true + }); + objectStore.createIndex( + "iam_id_iam_eventType_index", + ["iam_id", "iam_eventType"], + { unique: false } + ); + }; + + request.onsuccess = event => { + db = event.target.result; + resolve(true); + }; + }); + }; - const existingEvent = events[eventType][eventId]; - - const count = existingEvent ? existingEvent.count : 0; - const timestamp = new Date().getTime(); - const firstTimestamp = existingEvent - ? existingEvent.firstTimestamp || existingEvent.timestamp - : timestamp; - - events[eventType][eventId] = { - event: { - ...event, - [prefixed("id")]: eventId, - [prefixed("eventType")]: eventType, - [prefixed("action")]: action - }, - firstTimestamp, - timestamp, - count: count + 1 - }; - // TODO: save to indexedDB - save(events); - - return events[eventType][eventId]; + const addEvent = (event, eventType, eventId, action) => { + return new Promise((resolve, reject) => { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); + + const record = { + [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, + [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, + action, + timestamp: new Date().getTime() + }; + + const objectStoreRequest = objectStore.add(record); + + objectStoreRequest.onerror = txEvent => { + const dbRequest = txEvent.target; + reject(dbRequest.error); + }; + + objectStoreRequest.onsuccess = () => { + resolve(true); + }; + }); }; const addExperienceEdgeEvent = event => { @@ -98,13 +129,65 @@ export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { } }); }; - const getEvent = (eventType, eventId) => { - if (!events[eventType]) { - return undefined; - } - return events[eventType][eventId]; + const getEvents = (eventType, eventId) => { + return new Promise((resolve, reject) => { + const transaction = db.transaction("events", "readonly"); + const objectStore = transaction.objectStore("events"); + const index = objectStore.index("iam_id_iam_eventType_index"); + + const request = index.getAll([eventId, eventType]); + + request.onsuccess = eventObjStore => { + const dbRequest = eventObjStore.target; + const data = dbRequest + ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) + : []; + resolve(data); + }; + + request.onerror = eventObjStore => { + const dbRequest = eventObjStore.target; + reject(dbRequest.error); + }; + }); }; - return { addExperienceEdgeEvent, addEvent, getEvent, toJSON: () => events }; + const getEventsFirstTimestamp = (eventType, eventId) => { + return new Promise(resolve => { + getEvents(eventType, eventId).then(events => { + if (!events || events.length === 0) { + resolve(undefined); + return; + } + + resolve( + events.reduce( + (earliestTimestamp, currentEvent) => + earliestTimestamp < currentEvent.timestamp + ? earliestTimestamp + : currentEvent.timestamp, + events[0].timestamp + ) + ); + }); + }); + }; + + setupIndexedDB() + .then(() => { + console.log("IndexedDB setup complete."); + }) + .catch(error => { + console.error(error); + }); + + return { + setupIndexedDB, + addEvent, + addExperienceEdgeEvent, + getEvents, + getEventsFirstTimestamp, + getIndexDB: () => db + }; }; diff --git a/src/components/DecisioningEngine/createHistoricalRegistry.js b/src/components/DecisioningEngine/createHistoricalRegistry.js deleted file mode 100644 index 0e16a8da6..000000000 --- a/src/components/DecisioningEngine/createHistoricalRegistry.js +++ /dev/null @@ -1,193 +0,0 @@ -/* -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 { HISTORICAL_DATA_STORE } from "./constants"; -import { EVENT_TYPE_TRUE } from "../Personalization/event"; -import { getActivityId } from "./utils"; - -const dbName = HISTORICAL_DATA_STORE; -const PREFIX_TO_SUPPORT_INDEX_DB = key => `iam_${key}`; - -export default () => { - let db; - - const replaceUnderscoreWithDot = record => { - const updatedRecord = {}; - Object.keys(record).forEach(key => { - updatedRecord[key.replace("/_/g", ".")] = record[key]; - }); - return updatedRecord; - }; - - const setupIndexedDB = () => { - return new Promise((resolve, reject) => { - if (!("indexedDB" in window)) { - reject(new Error("This browser doesn't support IndexedDB.")); - } - - const request = indexedDB.open(dbName, 1); - - request.onerror = event => { - const dbRequest = event.target; - reject(dbRequest.error); - }; - - request.onupgradeneeded = event => { - db = event.target.result; - - const objectStore = db.createObjectStore("events", { - keyPath: "id", - autoIncrement: true - }); - objectStore.createIndex( - "iam_id_iam_eventType_index", - ["iam_id", "iam_eventType"], - { unique: false } - ); - }; - - request.onsuccess = event => { - db = event.target.result; - resolve(true); - }; - }); - }; - - const addEvent = (event, eventType, eventId, action) => { - return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readwrite"); - const objectStore = transaction.objectStore("events"); - console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); - - const record = { - [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, - [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, - action, - timestamp: new Date().getTime() - }; - - const objectStoreRequest = objectStore.add(record); - - objectStoreRequest.onerror = txEvent => { - const dbRequest = txEvent.target; - reject(dbRequest.error); - }; - - objectStoreRequest.onsuccess = () => { - resolve(true); - }; - }); - }; - - const addExperienceEdgeEvent = event => { - const { xdm = {} } = event.getContent(); - const { eventType = "", _experience } = xdm; - - if ( - !eventType || - !_experience || - typeof _experience !== "object" || - eventType === "" - ) { - return; - } - - const { decisioning = {} } = _experience; - const { - propositionEventType: propositionEventTypeObj = {}, - propositionAction = {}, - propositions = [] - } = decisioning; - - const propositionEventTypesList = Object.keys(propositionEventTypeObj); - - // https://wiki.corp.adobe.com/pages/viewpage.action?spaceKey=CJM&title=Proposition+Event+Types - if (propositionEventTypesList.length === 0) { - return; - } - - const { id: action } = propositionAction; - - propositionEventTypesList.forEach(propositionEventType => { - if (propositionEventTypeObj[propositionEventType] === EVENT_TYPE_TRUE) { - propositions.forEach(proposition => { - addEvent( - {}, - propositionEventType, - getActivityId(proposition), - action - ); - }); - } - }); - }; - - const getEvents = (eventType, eventId) => { - return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readonly"); - const objectStore = transaction.objectStore("events"); - const index = objectStore.index("iam_id_iam_eventType_index"); - - const request = index.getAll([eventId, eventType]); - - request.onsuccess = eventObjStore => { - const dbRequest = eventObjStore.target; - const data = dbRequest - ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) - : []; - resolve(data); - }; - - request.onerror = eventObjStore => { - const dbRequest = eventObjStore.target; - reject(dbRequest.error); - }; - }); - }; - - const getEventsFirstTimestamp = (eventType, eventId) => { - return new Promise(resolve => { - getEvents(eventType, eventId).then(events => { - if (!events || events.length === 0) { - resolve(undefined); - return; - } - - resolve( - events.reduce( - (earliestTimestamp, currentEvent) => - earliestTimestamp < currentEvent.timestamp - ? earliestTimestamp - : currentEvent.timestamp, - events[0].timestamp - ) - ); - }); - }); - }; - - setupIndexedDB() - .then(() => { - console.log("IndexedDB setup complete."); - }) - .catch(error => { - console.error(error); - }); - - return { - setupIndexedDB, - addEvent, - addExperienceEdgeEvent, - getEvents, - getEventsFirstTimestamp, - getIndexDB: () => db - }; -}; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 4b6b1bf45..73a5839c1 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -9,7 +9,7 @@ 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 { noop, sanitizeOrgIdForCookieName } from "../../utils"; +import { noop } from "../../utils"; import createOnResponseHandler from "./createOnResponseHandler"; import createDecisionProvider from "./createDecisionProvider"; import createApplyResponse from "./createApplyResponse"; @@ -17,7 +17,6 @@ import createEventRegistry from "./createEventRegistry"; import createContextProvider from "./createContextProvider"; import createSubscribeRulesetItems from "./createSubscribeRulesetItems"; import { ensureSchemaBasedRulesetConsequences } from "./utils"; -import "regenerator-runtime/runtime"; import { CONTEXT_KEY, @@ -25,25 +24,13 @@ import { MOBILE_EVENT_TYPE } from "./constants"; import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; -import createHistoricalRegistry from "./createHistoricalRegistry"; -const createDecisioningEngine = ({ config, createNamespacedStorage }) => { - const { orgId } = config; - const storage = createNamespacedStorage( - `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` - ); - createEventRegistry({ storage: storage.persistent }); +const createDecisioningEngine = () => { + const eventRegistry = createEventRegistry(); let applyResponse; - const historicalEventRegistry = createHistoricalRegistry(); - - const decisionProvider = createDecisionProvider({ - eventRegistry: historicalEventRegistry - }); - const contextProvider = createContextProvider({ - eventRegistry: historicalEventRegistry, - window - }); + const decisionProvider = createDecisionProvider({ eventRegistry }); + const contextProvider = createContextProvider({ eventRegistry, window }); const evaluateRulesetsCommand = createEvaluateRulesetsCommand({ contextProvider, @@ -82,7 +69,7 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { }) ); - historicalEventRegistry.addExperienceEdgeEvent(event); + eventRegistry.addExperienceEdgeEvent(event); } }, commands: { From 2a63ff5e8544cc240ba3b2cb2219a2aea910b361 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 3 Oct 2023 10:31:49 -0700 Subject: [PATCH 13/27] fixed tests --- .../createEvaluateRulesetsCommand.js | 3 +- .../DecisioningEngine/createEventRegistry.js | 30 +- .../DecisioningEngine/contextTestUtils.js | 16 +- .../createDecisionHistory.spec.js | 66 +- .../createDecisionProvider.spec.js | 964 +++++++++--------- .../createEvaluableRulesetPayload.spec.js | 719 ++++++------- .../createEvaluateRulesetsCommand.spec.js | 412 ++++---- .../createEventRegistry.spec.js | 183 +--- .../createHistoricalRegistry.spec.js | 0 .../createOnResponseHandler.spec.js | 766 +++++++------- .../decisioningContext.browser.spec.js | 112 +- .../decisioningContext.page.spec.js | 690 ++++++------- .../decisioningContext.referringPage.spec.js | 576 +++++------ .../decisioningContext.timestamp.spec.js | 668 ++++++------ .../decisioningContext.window.spec.js | 370 +++---- 15 files changed, 2740 insertions(+), 2835 deletions(-) delete mode 100644 test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js diff --git a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js index 210166a74..ffce8cf68 100644 --- a/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js +++ b/src/components/DecisioningEngine/createEvaluateRulesetsCommand.js @@ -26,8 +26,7 @@ export default ({ contextProvider, decisionProvider }) => { decisionProvider .evaluate(contextProvider.getContext(decisionContext)) .then(propositions => { - applyResponse({ renderDecisions, propositions }); - resolve(); + resolve(applyResponse({ renderDecisions, propositions })); }); }); }; diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 0e16a8da6..03ac72fd2 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -56,6 +56,7 @@ export default () => { request.onsuccess = event => { db = event.target.result; + console.log("IndexedDB setup complete"); resolve(true); }; }); @@ -65,8 +66,6 @@ export default () => { return new Promise((resolve, reject) => { const transaction = db.transaction("events", "readwrite"); const objectStore = transaction.objectStore("events"); - console.log("CreateHistoricalRegistry.addRecordToIndexedDB start"); - const record = { [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, @@ -174,18 +173,33 @@ export default () => { }); }; - setupIndexedDB() - .then(() => { - console.log("IndexedDB setup complete."); - }) - .catch(error => { - console.error(error); + // setupIndexedDB() + // .then(() => {}) + // .catch(error => { + // console.error("error message: ", error.message); + // }); + + const clearIndexedDB = () => { + return new Promise((resolve, reject) => { + try { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + const request = objectStore.clear(); + + request.onsuccess = () => { + resolve(true); + }; + } catch (error) { + reject(error); + } }); + }; return { setupIndexedDB, addEvent, addExperienceEdgeEvent, + clearIndexedDB, getEvents, getEventsFirstTimestamp, getIndexDB: () => db diff --git a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js index 322d7e191..f40f2360e 100644 --- a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js +++ b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js @@ -117,13 +117,13 @@ export const mockRulesetResponseWithCondition = condition => { const mockEvent = { getContent: () => ({}), getViewName: () => undefined }; -export const setupResponseHandler = (applyResponse, window, condition) => { - const storage = jasmine.createSpyObj("storage", [ - "getItem", - "setItem", - "clear" - ]); - const eventRegistry = createEventRegistry({ storage }); +export const setupResponseHandler = async ( + applyResponse, + window, + condition +) => { + const eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); const decisionProvider = createDecisionProvider({ eventRegistry }); const contextProvider = createContextProvider({ eventRegistry, window }); @@ -136,7 +136,7 @@ export const setupResponseHandler = (applyResponse, window, condition) => { decisionContext: contextProvider.getContext() }); - onResponseHandler({ + await onResponseHandler({ response: mockRulesetResponseWithCondition(condition) }); }; diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js index ff775adb8..b85328429 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js @@ -9,55 +9,33 @@ 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 createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; -import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import { PropositionEventType } from "../../../../../src/components/Personalization/constants/propositionEventType"; +import recordQualifiedModule from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; describe("DecisioningEngine:decisionHistory", () => { - let storage; - let history; - - beforeEach(() => { - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - - history = createDecisionHistory({ - eventRegistry: createEventRegistry({ storage, saveDelay: 10 }) - }); - }); - - it("records decision time", () => { - const decision = history.recordQualified({ id: "abc" }); - - expect(Object.getPrototypeOf(decision)).toEqual(Object.prototype); - expect(decision.timestamp).toEqual(jasmine.any(Number)); + it("should call eventRegistry.addEvent with the correct arguments when provided with an id", () => { + const eventRegistry = { + addEvent: jasmine.createSpy("addEvent") + }; + const module = recordQualifiedModule({ eventRegistry }); + const id = "someId"; + module.recordQualified(id); + expect(eventRegistry.addEvent).toHaveBeenCalledWith( + {}, + PropositionEventType.TRIGGER, + id + ); }); - it("preserves first decision time, if decision already recorded", done => { - const firstDecision = history.recordQualified({ id: "abc" }); - - setTimeout(() => { - expect(history.recordQualified({ id: "abc" }).firstTimestamp).toEqual( - firstDecision.firstTimestamp - ); - expect(history.recordQualified({ id: "abc" }).firstTimestamp).toEqual( - firstDecision.timestamp - ); - done(); - }, 20); - }); - - it("restores history from event storage", () => { - expect(storage.getItem).toHaveBeenCalledWith("events"); - }); + it("should return undefined when not provided with an id", () => { + const eventRegistry = { + addEvent: jasmine.createSpy("addEvent") + }; - it("saves history to event storage", done => { - history.recordQualified({ id: "abc" }); + const module = recordQualifiedModule({ eventRegistry }); - setTimeout(() => { - expect(storage.setItem).toHaveBeenCalledWith( - "events", - jasmine.any(String) - ); - done(); - }, 20); + const result = module.recordQualified(); + expect(eventRegistry.addEvent).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); }); }); diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index 371ede73d..a26a5aed6 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -1,481 +1,483 @@ -// /* -// 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 createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// -// describe("DecisioningEngine:createDecisionProvider", () => { -// let decisionProvider; -// let storage; -// let eventRegistry; -// -// beforeEach(() => { -// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); -// eventRegistry = createEventRegistry({ storage }); -// -// decisionProvider = createDecisionProvider({ eventRegistry }); -// decisionProvider.addPayloads([ -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "color", -// matcher: "eq", -// values: ["orange", "blue"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "action", -// matcher: "eq", -// values: ["lipstick"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://mywebsite.com" -// }, -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", -// items: [ -// { -// id: "5229f502-38d6-40c3-9a3a-b5b1a6adc441", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "xdm.web.webPageDetails.viewName", -// matcher: "eq", -// values: ["home"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content h3", -// type: "setHtml", -// content: "i can haz?", -// prehidingSelector: "div#spa #spa-content h3" -// }, -// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" -// }, -// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" -// }, -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content p", -// type: "setHtml", -// content: "ALL YOUR BASE ARE BELONG TO US", -// prehidingSelector: "div#spa #spa-content p" -// }, -// id: "a44af51a-e073-4e8c-92e1-84ac28210043" -// }, -// id: "a44af51a-e073-4e8c-92e1-84ac28210043" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://mywebsite.com" -// } -// ]); -// }); -// it("returns a single payload with items that qualify", () => { -// expect( -// decisionProvider.evaluate({ color: "blue", action: "lipstick" }) -// ).toEqual([ -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://mywebsite.com" -// } -// ]); -// }); -// it("returns a different single payload with items that qualify", () => { -// expect( -// decisionProvider.evaluate({ "xdm.web.webPageDetails.viewName": "home" }) -// ).toEqual([ -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content h3", -// type: "setHtml", -// content: "i can haz?", -// prehidingSelector: "div#spa #spa-content h3", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content p", -// type: "setHtml", -// content: "ALL YOUR BASE ARE BELONG TO US", -// prehidingSelector: "div#spa #spa-content p", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "a44af51a-e073-4e8c-92e1-84ac28210043" -// } -// ], -// scope: "web://mywebsite.com" -// } -// ]); -// }); -// it("returns two payloads with items that qualify", () => { -// expect( -// decisionProvider.evaluate({ -// color: "blue", -// action: "lipstick", -// "xdm.web.webPageDetails.viewName": "home" -// }) -// ).toEqual([ -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://mywebsite.com" -// }, -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content h3", -// type: "setHtml", -// content: "i can haz?", -// prehidingSelector: "div#spa #spa-content h3", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "div#spa #spa-content p", -// type: "setHtml", -// content: "ALL YOUR BASE ARE BELONG TO US", -// prehidingSelector: "div#spa #spa-content p", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "a44af51a-e073-4e8c-92e1-84ac28210043" -// } -// ], -// scope: "web://mywebsite.com" -// } -// ]); -// }); -// -// it("ignores payloads that aren't json-ruleset type", () => { -// decisionProvider.addPayload({ -// id: "AT:eyJhY3Rpdml0eUlkIjoiMTQxMDY0IiwiZXhwZXJpZW5jZUlkIjoiMCJ9", -// scope: "__view__", -// scopeDetails: { -// decisionProvider: "TGT", -// activity: { -// id: "141064" -// }, -// experience: { -// id: "0" -// }, -// strategies: [ -// { -// algorithmID: "0", -// trafficType: "0" -// } -// ], -// characteristics: { -// eventToken: "abc" -// }, -// correlationID: "141064:0:0:0" -// }, -// items: [ -// { -// id: "284525", -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// type: "setHtml", -// format: "application/vnd.adobe.target.dom-action", -// content: "
oh hai
", -// selector: "head", -// prehidingSelector: "head" -// } -// } -// ] -// }); -// -// expect(decisionProvider.evaluate()).toEqual([]); -// }); -// }); +/* +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 createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; + +describe("DecisioningEngine:createDecisionProvider", () => { + let decisionProvider; + let eventRegistry; + + beforeEach(async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + + decisionProvider = createDecisionProvider({ eventRegistry }); + decisionProvider.addPayloads([ + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["lipstick"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ] + } + ] + } + } + ], + scope: "web://mywebsite.com" + }, + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", + items: [ + { + id: "5229f502-38d6-40c3-9a3a-b5b1a6adc441", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "xdm.web.webPageDetails.viewName", + matcher: "eq", + values: ["home"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content h3", + type: "setHtml", + content: "i can haz?", + prehidingSelector: "div#spa #spa-content h3" + }, + id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" + }, + id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" + }, + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content p", + type: "setHtml", + content: "ALL YOUR BASE ARE BELONG TO US", + prehidingSelector: "div#spa #spa-content p" + }, + id: "a44af51a-e073-4e8c-92e1-84ac28210043" + }, + id: "a44af51a-e073-4e8c-92e1-84ac28210043" + } + ] + } + ] + } + } + ], + scope: "web://mywebsite.com" + } + ]); + }); + it("returns a single payload with items that qualify", async () => { + const expectedResult = await decisionProvider.evaluate({ + color: "blue", + action: "lipstick" + }); + expect(expectedResult).toEqual([ + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://mywebsite.com" + } + ]); + }); + it("returns a different single payload with items that qualify", async () => { + const expectedResult = await decisionProvider.evaluate({ + "xdm.web.webPageDetails.viewName": "home" + }); + expect(expectedResult).toEqual([ + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content h3", + type: "setHtml", + content: "i can haz?", + prehidingSelector: "div#spa #spa-content h3", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content p", + type: "setHtml", + content: "ALL YOUR BASE ARE BELONG TO US", + prehidingSelector: "div#spa #spa-content p", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "a44af51a-e073-4e8c-92e1-84ac28210043" + } + ], + scope: "web://mywebsite.com" + } + ]); + }); + it("returns two payloads with items that qualify", async () => { + const expectedResult = await decisionProvider.evaluate({ + color: "blue", + action: "lipstick", + "xdm.web.webPageDetails.viewName": "home" + }); + expect(expectedResult).toEqual([ + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://mywebsite.com" + }, + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content h3", + type: "setHtml", + content: "i can haz?", + prehidingSelector: "div#spa #spa-content h3", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "8a0d7a45-70fb-4845-a093-2133b5744c8d" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "div#spa #spa-content p", + type: "setHtml", + content: "ALL YOUR BASE ARE BELONG TO US", + prehidingSelector: "div#spa #spa-content p", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "a44af51a-e073-4e8c-92e1-84ac28210043" + } + ], + scope: "web://mywebsite.com" + } + ]); + }); + + it("ignores payloads that aren't json-ruleset type", async () => { + decisionProvider.addPayload({ + id: "AT:eyJhY3Rpdml0eUlkIjoiMTQxMDY0IiwiZXhwZXJpZW5jZUlkIjoiMCJ9", + scope: "__view__", + scopeDetails: { + decisionProvider: "TGT", + activity: { + id: "141064" + }, + experience: { + id: "0" + }, + strategies: [ + { + algorithmID: "0", + trafficType: "0" + } + ], + characteristics: { + eventToken: "abc" + }, + correlationID: "141064:0:0:0" + }, + items: [ + { + id: "284525", + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + type: "setHtml", + format: "application/vnd.adobe.target.dom-action", + content: "
oh hai
", + selector: "head", + prehidingSelector: "head" + } + } + ] + }); + + const expectedResult = await decisionProvider.evaluate(); + expect(expectedResult).toEqual([]); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js index a4fd201f0..b8bea9e5b 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js @@ -1,358 +1,361 @@ -// /* -// 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 createEvaluableRulesetPayload from "../../../../../src/components/DecisioningEngine/createEvaluableRulesetPayload"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; -// -// describe("DecisioningEngine:createEvaluableRulesetPayload", () => { -// let storage; -// let eventRegistry; -// let decisionHistory; -// -// beforeEach(() => { -// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); -// eventRegistry = createEventRegistry({ storage }); -// decisionHistory = createDecisionHistory({ eventRegistry }); -// }); -// -// it("consumes ruleset-items", () => { -// const evaluableRulesetPayload = createEvaluableRulesetPayload( -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "color", -// matcher: "eq", -// values: ["orange", "blue"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "action", -// matcher: "eq", -// values: ["lipstick"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://mywebsite.com" -// }, -// eventRegistry, -// decisionHistory -// ); -// -// expect( -// evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) -// ).toEqual({ -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://mywebsite.com" -// }); -// }); -// -// it("consumes json-content-items", () => { -// const evaluableRulesetPayload = createEvaluableRulesetPayload( -// { -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/json-content-item", -// data: { -// content: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "color", -// matcher: "eq", -// values: ["orange", "blue"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "action", -// matcher: "eq", -// values: ["lipstick"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ] -// } -// ] -// } -// } -// } -// ], -// scope: "web://mywebsite.com" -// }, -// eventRegistry, -// decisionHistory -// ); -// -// expect( -// evaluableRulesetPayload.evaluate({ color: "orange", action: "lipstick" }) -// ).toEqual({ -// scopeDetails: { -// decisionProvider: "AJO", -// characteristics: { -// eventToken: "abc" -// }, -// strategies: [ -// { -// strategyID: "3VQe3oIqiYq2RAsYzmDTSf", -// treatmentID: "yu7rkogezumca7i0i44v" -// } -// ], -// activity: { -// id: -// "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" -// }, -// correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" -// }, -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://mywebsite.com" -// }); -// }); -// }); +/* +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 createEvaluableRulesetPayload from "../../../../../src/components/DecisioningEngine/createEvaluableRulesetPayload"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; + +describe("DecisioningEngine:createEvaluableRulesetPayload", () => { + let eventRegistry; + let decisionHistory; + + beforeEach(async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + decisionHistory = createDecisionHistory({ eventRegistry }); + }); + + it("consumes ruleset-items", async () => { + const evaluableRulesetPayload = createEvaluableRulesetPayload( + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["lipstick"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ] + } + ] + } + } + ], + scope: "web://mywebsite.com" + }, + eventRegistry, + decisionHistory + ); + + const expectedResult = await evaluableRulesetPayload.evaluate({ + color: "orange", + action: "lipstick" + }); + expect(expectedResult).toEqual({ + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://mywebsite.com" + }); + }); + + it("consumes json-content-items", async () => { + const evaluableRulesetPayload = createEvaluableRulesetPayload( + { + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/json-content-item", + data: { + content: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["lipstick"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ] + } + ] + } + } + } + ], + scope: "web://mywebsite.com" + }, + eventRegistry, + decisionHistory + ); + + const expectedResult = await evaluableRulesetPayload.evaluate({ + color: "orange", + action: "lipstick" + }); + expect(expectedResult).toEqual({ + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://mywebsite.com" + }); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index 14e34520c..c28d1c13b 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js @@ -1,207 +1,205 @@ -// /* -// 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 createEvaluateRulesetsCommand from "../../../../../src/components/DecisioningEngine/createEvaluateRulesetsCommand"; -// import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -// import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; -// -// describe("DecisioningEngine:evaluateRulesetsCommand", () => { -// let onDecision; -// let applyResponse; -// let storage; -// let eventRegistry; -// let contextProvider; -// let decisionProvider; -// let evaluateRulesetsCommand; -// -// beforeEach(() => { -// onDecision = jasmine.createSpy(); -// applyResponse = createApplyResponse({ onDecision }); -// -// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// decisionProvider = createDecisionProvider({ eventRegistry }); -// -// decisionProvider.addPayload({ -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "color", -// matcher: "eq", -// values: ["orange", "blue"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "action", -// matcher: "eq", -// values: ["greet"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://mywebsite.com" -// }); -// -// evaluateRulesetsCommand = createEvaluateRulesetsCommand({ -// contextProvider, -// decisionProvider -// }); -// }); -// -// it("onDecisions receives renderDecisions=true", () => { -// const result = evaluateRulesetsCommand.run({ -// renderDecisions: true, -// decisionContext: { color: "orange", action: "greet" }, -// applyResponse -// }); -// -// const expectedResult = { -// propositions: [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// } -// ], -// scope: "web://mywebsite.com" -// } -// ] -// }; -// -// expect(result).toEqual(expectedResult); -// expect(onDecision).toHaveBeenCalledOnceWith({ -// viewName: undefined, -// renderDecisions: true, -// ...expectedResult -// }); -// }); -// -// it("onDecisions receives renderDecisions=false", () => { -// const result = evaluateRulesetsCommand.run({ -// decisionContext: { color: "orange", action: "greet" }, -// applyResponse -// }); -// -// const expectedResult = { -// propositions: [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// } -// ], -// scope: "web://mywebsite.com" -// } -// ] -// }; -// -// expect(result).toEqual(expectedResult); -// expect(onDecision).toHaveBeenCalledOnceWith({ -// viewName: undefined, -// renderDecisions: false, -// ...expectedResult -// }); -// }); -// }); +/* +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 createEvaluateRulesetsCommand from "../../../../../src/components/DecisioningEngine/createEvaluateRulesetsCommand"; +import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; + +describe("DecisioningEngine:evaluateRulesetsCommand", () => { + let onDecision; + let applyResponse; + let eventRegistry; + let contextProvider; + let decisionProvider; + let evaluateRulesetsCommand; + + beforeEach(async () => { + onDecision = jasmine.createSpy(); + applyResponse = createApplyResponse({ onDecision }); + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + decisionProvider = createDecisionProvider({ eventRegistry }); + + decisionProvider.addPayload({ + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["greet"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + } + ] + } + ] + } + } + ], + scope: "web://mywebsite.com" + }); + + evaluateRulesetsCommand = createEvaluateRulesetsCommand({ + contextProvider, + decisionProvider + }); + }); + + it("onDecisions receives renderDecisions=true", async () => { + const result = await evaluateRulesetsCommand.run({ + renderDecisions: true, + decisionContext: { color: "orange", action: "greet" }, + applyResponse + }); + + const expectedResult = { + propositions: [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + } + ], + scope: "web://mywebsite.com" + } + ] + }; + + expect(result).toEqual(expectedResult); + expect(onDecision).toHaveBeenCalledOnceWith({ + viewName: undefined, + renderDecisions: true, + ...expectedResult + }); + }); + + it("onDecisions receives renderDecisions=false", async () => { + const result = await evaluateRulesetsCommand.run({ + decisionContext: { color: "orange", action: "greet" }, + applyResponse + }); + + const expectedResult = { + propositions: [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + } + ], + scope: "web://mywebsite.com" + } + ] + }; + + expect(result).toEqual(expectedResult); + expect(onDecision).toHaveBeenCalledOnceWith({ + viewName: undefined, + renderDecisions: false, + ...expectedResult + }); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js index 29fb14786..97978e8f7 100644 --- a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js @@ -12,22 +12,58 @@ governing permissions and limitations under the License. import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; describe("DecisioningEngine:createEventRegistry", () => { - let storage; + const eventRegistry = createEventRegistry(); let mockedTimestamp; - beforeEach(() => { - storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); + beforeAll(async () => { + await eventRegistry.setupIndexedDB(); mockedTimestamp = new Date("2023-05-24T08:00:00Z"); jasmine.clock().install(); jasmine.clock().mockDate(mockedTimestamp); }); - afterEach(() => { + afterAll(() => { + eventRegistry.clearIndexedDB(); + eventRegistry.getIndexDB().close(); jasmine.clock().uninstall(); }); - it("registers events", () => { - const eventRegistry = createEventRegistry({ storage }); + it("should add an event to the database", async () => { + const eventType = "trigger"; + const eventId = "abc123"; + const action = "click"; + const result = await eventRegistry.addEvent({}, eventType, eventId, action); + expect(result).toBeTruthy(); + }); + + it("should get events from the database if that exist", async () => { + const eventType = "trigger"; + const eventId = "abc123"; + + const events = await eventRegistry.getEvents(eventType, eventId); + expect(Array.isArray(events)).toBe(true); + }); + + it("should return empty if the query is not found", async () => { + const eventType = "someMagicalEvent"; + const eventId = "someFutureId"; + + const events = await eventRegistry.getEvents(eventType, eventId); + expect(events.length).toBe(0); + }); + + it("should get the first timestamp for events", async () => { + const eventType = "trigger"; + const eventId = "abc123"; + + const timestamp = await eventRegistry.getEventsFirstTimestamp( + eventType, + eventId + ); + expect(timestamp).toBe(mockedTimestamp.getTime()); + }); + + it("should add experience edge event to the database", async () => { const getContent = () => ({ xdm: { eventType: "decisioning.propositionDisplay", @@ -65,139 +101,16 @@ describe("DecisioningEngine:createEventRegistry", () => { } }); - const event = { + const mockEvent = { getContent }; - eventRegistry.addExperienceEdgeEvent(event); - - expect(eventRegistry.toJSON()).toEqual({ - display: { - "111#aaa": { - event: jasmine.objectContaining({ - "iam.id": "111#aaa", - "iam.eventType": "display" - }), - firstTimestamp: jasmine.any(Number), - timestamp: jasmine.any(Number), - count: 1 - }, - "222#bbb": { - event: jasmine.objectContaining({ - "iam.id": "222#bbb", - "iam.eventType": "display" - }), - firstTimestamp: jasmine.any(Number), - timestamp: jasmine.any(Number), - count: 1 - } - } - }); - }); - - it("does not register invalid events", () => { - const eventRegistry = createEventRegistry({ storage }); - - eventRegistry.addExperienceEdgeEvent({ - getContent: () => ({ - xdm: { - eventType: "display" - } - }) - }); - eventRegistry.addExperienceEdgeEvent({ - getContent: () => ({ - xdm: { - eventType: "display", - _experience: {} - } - }) - }); - eventRegistry.addExperienceEdgeEvent({ - getContent: () => ({ - xdm: { - eventType: "display", - _experience: { - decisioning: {} - } - } - }) - }); - eventRegistry.addExperienceEdgeEvent({ - getContent: () => ({}) - }); - - expect(eventRegistry.toJSON()).toEqual({}); - }); - - it("increments count and sets timestamp", done => { - const eventRegistry = createEventRegistry({ storage, saveDelay: 10 }); + await eventRegistry.addExperienceEdgeEvent(mockEvent); - const getContent = () => ({ - xdm: { - eventType: "decisioning.propositionDisplay", - _experience: { - decisioning: { - propositions: [ - { - id: "111", - scope: "mobileapp://com.adobe.aguaAppIos", - scopeDetails: { - decisionProvider: "AJO", - correlationID: "ccaa539e-ca14-4d42-ac9a-0a17e69a63e4", - activity: { - id: "111#aaa" - } - } - } - ], - propositionEventType: { - display: 1 - } - } - } - } - }); + const eventType = "display"; + const eventId1 = "111#aaa"; - const event = { - getContent - }; - let lastEventTime = 0; - eventRegistry.addExperienceEdgeEvent(event); - - expect(eventRegistry.getEvent("display", "111#aaa")).toEqual({ - event: jasmine.objectContaining({ - "iam.id": "111#aaa", - "iam.eventType": "display" - }), - firstTimestamp: jasmine.any(Number), - timestamp: jasmine.any(Number), - count: 1 - }); - expect( - eventRegistry.getEvent("display", "111#aaa").timestamp - ).toBeGreaterThan(lastEventTime); - - lastEventTime = eventRegistry.getEvent("display", "111#aaa").timestamp; - - setTimeout(() => { - eventRegistry.addExperienceEdgeEvent(event); // again - - expect(eventRegistry.getEvent("display", "111#aaa")).toEqual({ - event: jasmine.objectContaining({ - "iam.id": "111#aaa", - "iam.eventType": "display" - }), - firstTimestamp: jasmine.any(Number), - timestamp: jasmine.any(Number), - count: 2 - }); - expect( - eventRegistry.getEvent("display", "111#aaa").timestamp - ).toBeGreaterThan(lastEventTime); - done(); - }, 50); - - jasmine.clock().tick(60); + const events1 = await eventRegistry.getEvents(eventType, eventId1); + expect(events1.length).toBeGreaterThan(0); }); }); diff --git a/test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createHistoricalRegistry.spec.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js index e33914e05..ff7b4098f 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -1,384 +1,382 @@ -// /* -// 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 createOnResponseHandler from "../../../../../src/components/DecisioningEngine/createOnResponseHandler"; -// import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; -// import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// -// describe("DecisioningEngine:createOnResponseHandler", () => { -// let lifecycle; -// let storage; -// let eventRegistry; -// let decisionProvider; -// let applyResponse; -// -// beforeEach(() => { -// lifecycle = jasmine.createSpyObj("lifecycle", { -// onDecision: Promise.resolve() -// }); -// -// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); -// eventRegistry = createEventRegistry({ storage }); -// -// decisionProvider = createDecisionProvider({ eventRegistry }); -// applyResponse = createApplyResponse(lifecycle); -// }); -// -// it("calls lifecycle.onDecision with propositions based on decisionContext", () => { -// const event = { -// getViewName: () => undefined, -// getContent: () => ({ -// xdm: { -// web: { -// webPageDetails: { -// viewName: "contact", -// URL: "https://mywebsite.com" -// }, -// webReferrer: { -// URL: "https://google.com" -// } -// }, -// timestamp: new Date().toISOString(), -// implementationDetails: { -// name: "https://ns.adobe.com/experience/alloy", -// version: "2.15.0", -// environment: "browser" -// } -// }, -// data: { -// moo: "woof" -// } -// }) -// }; -// -// const decisionContext = { -// color: "orange", -// action: "lipstick" -// }; -// -// const responseHandler = createOnResponseHandler({ -// renderDecisions: true, -// decisionProvider, -// applyResponse, -// event, -// decisionContext -// }); -// -// const response = { -// getPayloadsByType: () => [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "color", -// matcher: "eq", -// values: ["orange", "blue"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "action", -// matcher: "eq", -// values: ["lipstick"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://target.jasonwaters.dev/aep.html" -// } -// ] -// }; -// -// responseHandler({ -// response -// }); -// -// expect(lifecycle.onDecision).toHaveBeenCalledWith({ -// viewName: undefined, -// renderDecisions: true, -// propositions: [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", -// type: "setAttribute", -// content: { -// src: "img/demo-marketing-offer1-exp-A.png" -// }, -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" -// }, -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://target.jasonwaters.dev/aep.html" -// } -// ] -// }); -// }); -// -// it("calls lifecycle.onDecision with propositions based on xdm and event data", () => { -// const event = { -// getViewName: () => "home", -// getContent: () => ({ -// xdm: { -// web: { -// webPageDetails: { -// viewName: "contact", -// URL: "https://mywebsite.com" -// }, -// webReferrer: { -// URL: "https://google.com" -// } -// }, -// timestamp: new Date().toISOString(), -// implementationDetails: { -// name: "https://ns.adobe.com/experience/alloy", -// version: "12345", -// environment: "browser" -// } -// }, -// data: { -// moo: "woof" -// } -// }) -// }; -// -// const decisionContext = {}; -// -// const responseHandler = createOnResponseHandler({ -// renderDecisions: true, -// decisionProvider, -// applyResponse, -// event, -// decisionContext -// }); -// -// const response = { -// getPayloadsByType: () => [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "xdm.web.webPageDetails.viewName", -// matcher: "eq", -// values: ["contact"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "xdm.implementationDetails.version", -// matcher: "eq", -// values: ["12345"] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "data.moo", -// matcher: "eq", -// values: ["woof"] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// type: "schema", -// detail: { -// schema: -// "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ] -// } -// ] -// } -// } -// ], -// scope: "web://target.jasonwaters.dev/aep.html" -// } -// ] -// }; -// -// responseHandler({ -// response -// }); -// -// expect(lifecycle.onDecision).toHaveBeenCalledWith({ -// viewName: "home", -// renderDecisions: true, -// propositions: [ -// { -// id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", -// scopeDetails: { -// activity: { -// id: "abc#xyz" -// } -// }, -// items: [ -// { -// schema: "https://ns.adobe.com/personalization/dom-action", -// data: { -// selector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// type: "setHtml", -// content: "Hello Treatment A!", -// prehidingSelector: -// "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", -// qualifiedDate: jasmine.any(Number), -// displayedDate: undefined -// }, -// id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" -// } -// ], -// scope: "web://target.jasonwaters.dev/aep.html" -// } -// ] -// }); -// }); -// }); +/* +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 createOnResponseHandler from "../../../../../src/components/DecisioningEngine/createOnResponseHandler"; +import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; + +describe("DecisioningEngine:createOnResponseHandler", () => { + let lifecycle; + let eventRegistry; + let decisionProvider; + let applyResponse; + + beforeEach(async () => { + lifecycle = jasmine.createSpyObj("lifecycle", { + onDecision: Promise.resolve() + }); + + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + decisionProvider = createDecisionProvider({ eventRegistry }); + applyResponse = createApplyResponse(lifecycle); + }); + + it("calls lifecycle.onDecision with propositions based on decisionContext", async () => { + const event = { + getViewName: () => undefined, + getContent: () => ({ + xdm: { + web: { + webPageDetails: { + viewName: "contact", + URL: "https://mywebsite.com" + }, + webReferrer: { + URL: "https://google.com" + } + }, + timestamp: new Date().toISOString(), + implementationDetails: { + name: "https://ns.adobe.com/experience/alloy", + version: "2.15.0", + environment: "browser" + } + }, + data: { + moo: "woof" + } + }) + }; + + const decisionContext = { + color: "orange", + action: "lipstick" + }; + + const responseHandler = createOnResponseHandler({ + renderDecisions: true, + decisionProvider, + applyResponse, + event, + decisionContext + }); + + const response = { + getPayloadsByType: () => [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["lipstick"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ] + } + ] + } + } + ], + scope: "web://target.jasonwaters.dev/aep.html" + } + ] + }; + + await responseHandler({ + response + }); + + expect(lifecycle.onDecision).toHaveBeenCalledWith({ + viewName: undefined, + renderDecisions: true, + propositions: [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://target.jasonwaters.dev/aep.html" + } + ] + }); + }); + + it("calls lifecycle.onDecision with propositions based on xdm and event data", async () => { + const event = { + getViewName: () => "home", + getContent: () => ({ + xdm: { + web: { + webPageDetails: { + viewName: "contact", + URL: "https://mywebsite.com" + }, + webReferrer: { + URL: "https://google.com" + } + }, + timestamp: new Date().toISOString(), + implementationDetails: { + name: "https://ns.adobe.com/experience/alloy", + version: "12345", + environment: "browser" + } + }, + data: { + moo: "woof" + } + }) + }; + + const decisionContext = {}; + + const responseHandler = createOnResponseHandler({ + renderDecisions: true, + decisionProvider, + applyResponse, + event, + decisionContext + }); + + const response = { + getPayloadsByType: () => [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "xdm.web.webPageDetails.viewName", + matcher: "eq", + values: ["contact"] + }, + type: "matcher" + }, + { + definition: { + key: "xdm.implementationDetails.version", + matcher: "eq", + values: ["12345"] + }, + type: "matcher" + }, + { + definition: { + key: "data.moo", + matcher: "eq", + values: ["woof"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: + "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ] + } + ] + } + } + ], + scope: "web://target.jasonwaters.dev/aep.html" + } + ] + }; + + await responseHandler({ + response + }); + + expect(lifecycle.onDecision).toHaveBeenCalledWith({ + viewName: "home", + renderDecisions: true, + propositions: [ + { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scopeDetails: { + activity: { + id: "abc#xyz" + } + }, + items: [ + { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + type: "setHtml", + content: "Hello Treatment A!", + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(1) > H1:nth-of-type(1)", + qualifiedDate: jasmine.any(Number), + displayedDate: undefined + }, + id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" + } + ], + scope: "web://target.jasonwaters.dev/aep.html" + } + ] + }); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js index a03339a80..cb7e8badf 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.browser.spec.js @@ -1,56 +1,56 @@ -// /* -// 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 { -// mockWindow, -// setupResponseHandler, -// proposition -// } from "./contextTestUtils"; -// -// describe("DecisioningEngine:globalContext:browser", () => { -// let applyResponse; -// beforeEach(() => { -// applyResponse = jasmine.createSpy(); -// }); -// it("satisfies rule based on matched browser", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "browser.name", -// matcher: "eq", -// values: ["chrome"] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched browser", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "browser.name", -// matcher: "co", -// values: ["Edge"] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// }); +/* +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 { + mockWindow, + setupResponseHandler, + proposition +} from "./contextTestUtils"; + +describe("DecisioningEngine:globalContext:browser", () => { + let applyResponse; + beforeEach(() => { + applyResponse = jasmine.createSpy(); + }); + it("satisfies rule based on matched browser", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "browser.name", + matcher: "eq", + values: ["chrome"] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched browser", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "browser.name", + matcher: "co", + values: ["Edge"] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js index 415dbc281..16a0817b6 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.page.spec.js @@ -1,345 +1,345 @@ -// /* -// 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 { -// mockWindow, -// setupResponseHandler, -// proposition -// } from "./contextTestUtils"; -// -// describe("DecisioningEngine:globalContext:page", () => { -// let applyResponse; -// beforeEach(() => { -// applyResponse = jasmine.createSpy(); -// }); -// -// it("satisfies rule based on matched page url", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.url", -// matcher: "eq", -// values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched page url", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "page.url", -// matcher: "eq", -// values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfy rule based on matched domain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.domain", -// matcher: "eq", -// values: ["pro.mywebsite.org"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched domain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.domain", -// matcher: "eq", -// values: ["pro.mywebsite.com"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfied rule based on matched page subdomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.subdomain", -// matcher: "eq", -// values: ["pro"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// // Note that we have custom parse url [refer to implementation] which will give empty string in case of www -// it("does not satisfy rule due to unmatched page subdomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://www.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.subdomain", -// matcher: "eq", -// values: ["www"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched page topLevelDomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.topLevelDomain", -// matcher: "eq", -// values: ["org"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched page topLevelDomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.topLevelDomain", -// matcher: "eq", -// values: ["com"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched page path", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.path", -// matcher: "eq", -// values: ["/about"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched page path", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.path", -// matcher: "eq", -// values: ["/home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched page query", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.query", -// matcher: "co", -// values: ["name=bob"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched page query", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "page.query", -// matcher: "co", -// values: ["name=bob"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched page fragment", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" -// }), -// { -// definition: { -// key: "page.fragment", -// matcher: "eq", -// values: ["home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched page fragment", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" -// }), -// { -// definition: { -// key: "page.fragment", -// matcher: "eq", -// values: ["home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// }); +/* +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 { + mockWindow, + setupResponseHandler, + proposition +} from "./contextTestUtils"; + +describe("DecisioningEngine:globalContext:page", () => { + let applyResponse; + beforeEach(() => { + applyResponse = jasmine.createSpy(); + }); + + it("satisfies rule based on matched page url", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.url", + matcher: "eq", + values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched page url", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "page.url", + matcher: "eq", + values: ["https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfy rule based on matched domain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.domain", + matcher: "eq", + values: ["pro.mywebsite.org"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched domain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.domain", + matcher: "eq", + values: ["pro.mywebsite.com"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfied rule based on matched page subdomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.subdomain", + matcher: "eq", + values: ["pro"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + // Note that we have custom parse url [refer to implementation] which will give empty string in case of www + it("does not satisfy rule due to unmatched page subdomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://www.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.subdomain", + matcher: "eq", + values: ["www"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched page topLevelDomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.topLevelDomain", + matcher: "eq", + values: ["org"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched page topLevelDomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.topLevelDomain", + matcher: "eq", + values: ["com"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched page path", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.path", + matcher: "eq", + values: ["/about"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched page path", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.path", + matcher: "eq", + values: ["/home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched page query", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.query", + matcher: "co", + values: ["name=bob"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched page query", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "page.query", + matcher: "co", + values: ["name=bob"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched page fragment", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#home" + }), + { + definition: { + key: "page.fragment", + matcher: "eq", + values: ["home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched page fragment", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + url: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" + }), + { + definition: { + key: "page.fragment", + matcher: "eq", + values: ["home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js index 861de8c9c..852d29105 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.referringPage.spec.js @@ -1,288 +1,288 @@ -// /* -// 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 { -// mockWindow, -// setupResponseHandler, -// proposition -// } from "./contextTestUtils"; -// -// describe("DecisioningEngine:globalContext:referringPage", () => { -// let applyResponse; -// beforeEach(() => { -// applyResponse = jasmine.createSpy(); -// }); -// -// it("satisfies rule based on matched domain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" -// }), -// { -// definition: { -// key: "referringPage.domain", -// matcher: "eq", -// values: ["business.adobe.com"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched domain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "referringPage.domain", -// matcher: "co", -// values: ["business.adobe.com"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched referringPage subdomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" -// }), -// { -// definition: { -// key: "referringPage.subdomain", -// matcher: "co", -// values: ["business"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched subdomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "referringPage.subdomain", -// matcher: "eq", -// values: ["business"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched referringPage topLevelDomain", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "referringPage.topLevelDomain", -// matcher: "eq", -// values: ["com"] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched topLevelDomain", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "referringPage.topLevelDomain", -// matcher: "eq", -// values: ["com"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched referringPage path", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "referringPage.path", -// matcher: "co", -// values: ["/search"] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched referringPage path", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "referringPage.path", -// matcher: "co", -// values: ["/search"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched referringPage query", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "referringPage.query", -// matcher: "co", -// values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched referringPage query", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" -// }), -// { -// definition: { -// key: "referringPage.query", -// matcher: "co", -// values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched referringPage fragment", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: -// "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" -// }), -// { -// definition: { -// key: "referringPage.fragment", -// matcher: "co", -// values: ["home"] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule based on unmatched referringPage fragment", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// referrer: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" -// }), -// { -// definition: { -// key: "referringPage.fragment", -// matcher: "co", -// values: ["home"] -// }, -// type: "matcher" -// } -// ); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// }); +/* +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 { + mockWindow, + setupResponseHandler, + proposition +} from "./contextTestUtils"; + +describe("DecisioningEngine:globalContext:referringPage", () => { + let applyResponse; + beforeEach(() => { + applyResponse = jasmine.createSpy(); + }); + + it("satisfies rule based on matched domain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" + }), + { + definition: { + key: "referringPage.domain", + matcher: "eq", + values: ["business.adobe.com"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched domain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "referringPage.domain", + matcher: "co", + values: ["business.adobe.com"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched referringPage subdomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" + }), + { + definition: { + key: "referringPage.subdomain", + matcher: "co", + values: ["business"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched subdomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "referringPage.subdomain", + matcher: "eq", + values: ["business"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched referringPage topLevelDomain", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "referringPage.topLevelDomain", + matcher: "eq", + values: ["com"] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched topLevelDomain", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "referringPage.topLevelDomain", + matcher: "eq", + values: ["com"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched referringPage path", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "referringPage.path", + matcher: "co", + values: ["/search"] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched referringPage path", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "referringPage.path", + matcher: "co", + values: ["/search"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched referringPage query", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "referringPage.query", + matcher: "co", + values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched referringPage query", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://pro.mywebsite.org:8080/about?m=1&t=5&name=richard#home" + }), + { + definition: { + key: "referringPage.query", + matcher: "co", + values: ["q=adobe+journey+optimizer&oq=adobe+journey+optimizer"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched referringPage fragment", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: + "https://business.adobe.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer#home" + }), + { + definition: { + key: "referringPage.fragment", + matcher: "co", + values: ["home"] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule based on unmatched referringPage fragment", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + referrer: "https://pro.mywebsite.org:8080/about?m=1&t=5&name=bob#about" + }), + { + definition: { + key: "referringPage.fragment", + matcher: "co", + values: ["home"] + }, + type: "matcher" + } + ); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js index 0c1dcb7a7..c81b8712d 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js @@ -1,334 +1,334 @@ -// /* -// 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 { -// mockWindow, -// setupResponseHandler, -// proposition -// } from "./contextTestUtils"; -// -// let mockedTimestamp; -// describe("DecisioningEngine:globalContext:timeContext", () => { -// let applyResponse; -// beforeEach(() => { -// applyResponse = jasmine.createSpy(); -// mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 13, 34, 56)); -// jasmine.clock().install(); -// jasmine.clock().mockDate(mockedTimestamp); -// }); -// afterEach(() => { -// jasmine.clock().uninstall(); -// }); -// -// it("satisfies rule based on matched pageLoadTimestamp", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "pageLoadTimestamp", -// matcher: "eq", -// values: [mockedTimestamp.getTime()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched pageLoadTimestamp", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "pageLoadTimestamp", -// matcher: "eq", -// values: [mockedTimestamp.getTime() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentTimestamp", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentTimestamp", -// matcher: "eq", -// values: [mockedTimestamp.getTime()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentTimestamp", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentTimestamp", -// matcher: "eq", -// values: [mockedTimestamp.getTime() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentDate", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentDate", -// matcher: "eq", -// values: [mockedTimestamp.getDate()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentDate", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentDate", -// matcher: "eq", -// values: [mockedTimestamp.getDate() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentDay", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentDay", -// matcher: "eq", -// values: [mockedTimestamp.getDay()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentDay", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentDay", -// matcher: "eq", -// values: [mockedTimestamp.getDay() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentHour", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentHour", -// matcher: "eq", -// values: [mockedTimestamp.getHours()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentHour", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentHour", -// matcher: "eq", -// values: [mockedTimestamp.getHours() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentMinute", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentMinute", -// matcher: "eq", -// values: [mockedTimestamp.getMinutes()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentMinute", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentMinute", -// matcher: "eq", -// values: [mockedTimestamp.getMinutes() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentMonth", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentMonth", -// matcher: "eq", -// values: [mockedTimestamp.getMonth()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentMonth", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentMonth", -// matcher: "eq", -// values: [mockedTimestamp.getMonth() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched currentYear", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentYear", -// matcher: "eq", -// values: [mockedTimestamp.getFullYear()] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched currentYear", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "currentYear", -// matcher: "eq", -// values: [mockedTimestamp.getFullYear() + 1] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched pageVisitDuration", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "pageVisitDuration", -// matcher: "eq", -// values: [0] -// }, -// type: "matcher" -// }); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched pageVisitDuration", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "pageVisitDuration", -// matcher: "eq", -// values: [1] -// }, -// type: "matcher" -// }); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// }); +/* +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 { + mockWindow, + setupResponseHandler, + proposition +} from "./contextTestUtils"; + +let mockedTimestamp; +describe("DecisioningEngine:globalContext:timeContext", () => { + let applyResponse; + beforeEach(() => { + applyResponse = jasmine.createSpy(); + mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 13, 34, 56)); + jasmine.clock().install(); + jasmine.clock().mockDate(mockedTimestamp); + }); + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it("satisfies rule based on matched pageLoadTimestamp", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "pageLoadTimestamp", + matcher: "eq", + values: [mockedTimestamp.getTime()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched pageLoadTimestamp", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "pageLoadTimestamp", + matcher: "eq", + values: [mockedTimestamp.getTime() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentTimestamp", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentTimestamp", + matcher: "eq", + values: [mockedTimestamp.getTime()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentTimestamp", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentTimestamp", + matcher: "eq", + values: [mockedTimestamp.getTime() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentDate", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentDate", + matcher: "eq", + values: [mockedTimestamp.getDate()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentDate", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentDate", + matcher: "eq", + values: [mockedTimestamp.getDate() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentDay", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentDay", + matcher: "eq", + values: [mockedTimestamp.getDay()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentDay", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentDay", + matcher: "eq", + values: [mockedTimestamp.getDay() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentHour", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentHour", + matcher: "eq", + values: [mockedTimestamp.getHours()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentHour", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentHour", + matcher: "eq", + values: [mockedTimestamp.getHours() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentMinute", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentMinute", + matcher: "eq", + values: [mockedTimestamp.getMinutes()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentMinute", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentMinute", + matcher: "eq", + values: [mockedTimestamp.getMinutes() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentMonth", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentMonth", + matcher: "eq", + values: [mockedTimestamp.getMonth()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentMonth", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentMonth", + matcher: "eq", + values: [mockedTimestamp.getMonth() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched currentYear", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentYear", + matcher: "eq", + values: [mockedTimestamp.getFullYear()] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched currentYear", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "currentYear", + matcher: "eq", + values: [mockedTimestamp.getFullYear() + 1] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched pageVisitDuration", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "pageVisitDuration", + matcher: "eq", + values: [0] + }, + type: "matcher" + }); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched pageVisitDuration", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "pageVisitDuration", + matcher: "eq", + values: [1] + }, + type: "matcher" + }); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js index 879749f31..7c428f3d0 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.window.spec.js @@ -1,185 +1,185 @@ -// /* -// 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 { -// mockWindow, -// setupResponseHandler, -// proposition -// } from "./contextTestUtils"; -// -// describe("DecisioningEngine:globalContext:window", () => { -// let applyResponse; -// beforeEach(() => { -// applyResponse = jasmine.createSpy(); -// }); -// -// it("satisfies rule based on matched window height", () => { -// setupResponseHandler(applyResponse, mockWindow({}), { -// definition: { -// key: "window.height", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// }); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched window height", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// height: 50 -// }), -// { -// definition: { -// key: "window.height", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched window width", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// width: 200 -// }), -// { -// definition: { -// key: "window.width", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched window width", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// width: 50 -// }), -// { -// definition: { -// key: "window.width", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched window scrollX", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// scrollX: 200 -// }), -// { -// definition: { -// key: "window.scrollX", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [proposition] -// }) -// ); -// }); -// -// it("does not satisfy rule due to unmatched window scrollX", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// scrollX: 50 -// }), -// { -// definition: { -// key: "window.scrollX", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// expect(applyResponse).toHaveBeenCalledOnceWith( -// jasmine.objectContaining({ -// propositions: [] -// }) -// ); -// }); -// -// it("satisfies rule based on matched window scrollY", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// scrollY: 200 -// }), -// { -// definition: { -// key: "window.scrollY", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// }); -// -// it("does not satisfy rule due to unmatched window scrollY", () => { -// setupResponseHandler( -// applyResponse, -// mockWindow({ -// scrollY: 50 -// }), -// { -// definition: { -// key: "window.scrollY", -// matcher: "gt", -// values: [90] -// }, -// type: "matcher" -// } -// ); -// }); -// }); +/* +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 { + mockWindow, + setupResponseHandler, + proposition +} from "./contextTestUtils"; + +describe("DecisioningEngine:globalContext:window", () => { + let applyResponse; + beforeEach(() => { + applyResponse = jasmine.createSpy(); + }); + + it("satisfies rule based on matched window height", async () => { + await setupResponseHandler(applyResponse, mockWindow({}), { + definition: { + key: "window.height", + matcher: "gt", + values: [90] + }, + type: "matcher" + }); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched window height", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + height: 50 + }), + { + definition: { + key: "window.height", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched window width", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + width: 200 + }), + { + definition: { + key: "window.width", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched window width", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + width: 50 + }), + { + definition: { + key: "window.width", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched window scrollX", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + scrollX: 200 + }), + { + definition: { + key: "window.scrollX", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [proposition] + }) + ); + }); + + it("does not satisfy rule due to unmatched window scrollX", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + scrollX: 50 + }), + { + definition: { + key: "window.scrollX", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + expect(applyResponse).toHaveBeenCalledOnceWith( + jasmine.objectContaining({ + propositions: [] + }) + ); + }); + + it("satisfies rule based on matched window scrollY", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + scrollY: 200 + }), + { + definition: { + key: "window.scrollY", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + }); + + it("does not satisfy rule due to unmatched window scrollY", async () => { + await setupResponseHandler( + applyResponse, + mockWindow({ + scrollY: 50 + }), + { + definition: { + key: "window.scrollY", + matcher: "gt", + values: [90] + }, + type: "matcher" + } + ); + }); +}); From e6b634c8d35c1b39b59684adb65cf3393012e2de Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 3 Oct 2023 10:39:17 -0700 Subject: [PATCH 14/27] should move indexedDB setup in it's dedicated module --- .../DecisioningEngine/createEventRegistry.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 03ac72fd2..ec391a0ee 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -173,11 +173,11 @@ export default () => { }); }; - // setupIndexedDB() - // .then(() => {}) - // .catch(error => { - // console.error("error message: ", error.message); - // }); + setupIndexedDB() + .then(() => {}) + .catch(error => { + console.error("error message: ", error.message); + }); const clearIndexedDB = () => { return new Promise((resolve, reject) => { From 93e794aade519cd824ae17e5f28e2d606b20e217 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 3 Oct 2023 10:59:26 -0700 Subject: [PATCH 15/27] test fix progress --- .../createContextProvider.spec.js | 261 +++++++++--------- .../createEventRegistry.spec.js | 22 +- 2 files changed, 142 insertions(+), 141 deletions(-) diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index 83cb4fb06..cdbb5071a 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -1,130 +1,131 @@ -// /* -// 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 createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// -// describe("DecisioningEngine:createContextProvider", () => { -// let contextProvider; -// let eventRegistry; -// let storage; -// let window; -// let mockedTimestamp; -// -// beforeEach(() => { -// storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); -// window = { -// title: "My awesome website", -// referrer: "https://stage.applookout.net/", -// url: "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", -// width: 100, -// height: 100, -// scrollX: 10, -// scrollY: 10, -// navigator: { -// userAgent: -// "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" -// } -// }; -// mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 12, 34, 56)); -// jasmine.clock().install(); -// jasmine.clock().mockDate(mockedTimestamp); -// }); -// -// afterEach(() => { -// jasmine.clock().uninstall(); -// }); -// it("returns page context", () => { -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext()).toEqual( -// jasmine.objectContaining({ -// "page.title": "My awesome website", -// "page.url": -// "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", -// "page.path": "/about", -// "page.query": "m=1&t=5&name=jimmy", -// "page.fragment": "home", -// "page.domain": "my.web-site.net", -// "page.subdomain": "my", -// "page.topLevelDomain": "net" -// }) -// ); -// }); -// it("returns referring page context", () => { -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext()).toEqual( -// jasmine.objectContaining({ -// "referringPage.url": "https://stage.applookout.net/", -// "referringPage.path": "/", -// "referringPage.query": "", -// "referringPage.fragment": "", -// "referringPage.domain": "stage.applookout.net", -// "referringPage.subdomain": "stage", -// "referringPage.topLevelDomain": "net" -// }) -// ); -// }); -// it("returns browser context", () => { -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext()).toEqual( -// jasmine.objectContaining({ -// "browser.name": "Chrome" -// }) -// ); -// }); -// it("returns windows context", () => { -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext()).toEqual( -// jasmine.objectContaining({ -// "window.height": 100, -// "window.width": 100, -// "window.scrollY": 10, -// "window.scrollX": 10 -// }) -// ); -// }); -// it("includes provided context passed in", () => { -// eventRegistry = createEventRegistry({ storage }); -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext({ cool: "beans" })).toEqual( -// jasmine.objectContaining({ -// cool: "beans" -// }) -// ); -// }); -// -// it("includes events context", () => { -// const events = { -// abc: { -// event: { id: "abc", type: "display" }, -// timestamp: new Date().getTime(), -// count: 1 -// } -// }; -// eventRegistry = { -// toJSON: () => events -// }; -// contextProvider = createContextProvider({ eventRegistry, window }); -// -// expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( -// events -// ); -// }); -// }); +/* +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 createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; +import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; + +describe("DecisioningEngine:createContextProvider", () => { + let contextProvider; + let eventRegistry; + let window; + let mockedTimestamp; + + beforeEach(() => { + window = { + title: "My awesome website", + referrer: "https://stage.applookout.net/", + url: "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", + width: 100, + height: 100, + scrollX: 10, + scrollY: 10, + navigator: { + userAgent: + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" + } + }; + mockedTimestamp = new Date(Date.UTC(2023, 4, 11, 12, 34, 56)); + jasmine.clock().install(); + jasmine.clock().mockDate(mockedTimestamp); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + it("returns page context", async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + + expect(contextProvider.getContext()).toEqual( + jasmine.objectContaining({ + "page.title": "My awesome website", + "page.url": + "https://my.web-site.net:8080/about?m=1&t=5&name=jimmy#home", + "page.path": "/about", + "page.query": "m=1&t=5&name=jimmy", + "page.fragment": "home", + "page.domain": "my.web-site.net", + "page.subdomain": "my", + "page.topLevelDomain": "net" + }) + ); + }); + it("returns referring page context", async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + + expect(contextProvider.getContext()).toEqual( + jasmine.objectContaining({ + "referringPage.url": "https://stage.applookout.net/", + "referringPage.path": "/", + "referringPage.query": "", + "referringPage.fragment": "", + "referringPage.domain": "stage.applookout.net", + "referringPage.subdomain": "stage", + "referringPage.topLevelDomain": "net" + }) + ); + }); + it("returns browser context", async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + + expect(contextProvider.getContext()).toEqual( + jasmine.objectContaining({ + "browser.name": "Chrome" + }) + ); + }); + it("returns windows context", async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + + expect(contextProvider.getContext()).toEqual( + jasmine.objectContaining({ + "window.height": 100, + "window.width": 100, + "window.scrollY": 10, + "window.scrollX": 10 + }) + ); + }); + it("includes provided context passed in", async () => { + eventRegistry = createEventRegistry(); + await eventRegistry.setupIndexedDB(); + contextProvider = createContextProvider({ eventRegistry, window }); + + expect(contextProvider.getContext({ cool: "beans" })).toEqual( + jasmine.objectContaining({ + cool: "beans" + }) + ); + }); + + // it("includes events context", async () => { + // const events = { + // abc: { + // event: { "iam.id": "abc", "iam.eventType": "display" }, + // timestamp: new Date().getTime() + // } + // }; + // eventRegistry = await eventRegistry.getEvents("display", "abc"); + // console.log("eventRegistry is ", eventRegistry); + // contextProvider = createContextProvider({ eventRegistry, window }); + // + // expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( + // events + // ); + // }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js index 97978e8f7..b9a2d94b7 100644 --- a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js @@ -51,17 +51,17 @@ describe("DecisioningEngine:createEventRegistry", () => { const events = await eventRegistry.getEvents(eventType, eventId); expect(events.length).toBe(0); }); - - it("should get the first timestamp for events", async () => { - const eventType = "trigger"; - const eventId = "abc123"; - - const timestamp = await eventRegistry.getEventsFirstTimestamp( - eventType, - eventId - ); - expect(timestamp).toBe(mockedTimestamp.getTime()); - }); + // TODO: FIX the below test + // it("should get the first timestamp for events", async () => { + // const eventType = "trigger"; + // const eventId = "abc123"; + // + // const timestamp = await eventRegistry.getEventsFirstTimestamp( + // eventType, + // eventId + // ); + // expect(timestamp).toBe(mockedTimestamp.getTime()); + // }); it("should add experience edge event to the database", async () => { const getContent = () => ({ From 8e6d16506193f8ff0644aafa42e6633e946a8f12 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 3 Oct 2023 11:06:10 -0700 Subject: [PATCH 16/27] restoring the functional tests --- .../specs/DecisioningEngine/C13348429.js | 423 +++++++++-------- .../specs/DecisioningEngine/C13405889.js | 429 +++++++++-------- .../specs/DecisioningEngine/C13419240.js | 433 +++++++++--------- 3 files changed, 626 insertions(+), 659 deletions(-) diff --git a/test/functional/specs/DecisioningEngine/C13348429.js b/test/functional/specs/DecisioningEngine/C13348429.js index eb44f1401..d54c5b3d3 100644 --- a/test/functional/specs/DecisioningEngine/C13348429.js +++ b/test/functional/specs/DecisioningEngine/C13348429.js @@ -9,220 +9,209 @@ 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. */ -// /* -// 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 { ClientFunction, t } from "testcafe"; -// import createNetworkLogger from "../../helpers/networkLogger"; -// import createFixture from "../../helpers/createFixture"; -// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -// import createAlloyProxy from "../../helpers/createAlloyProxy"; -// import getBaseConfig from "../../helpers/getBaseConfig"; -// import { compose, debugEnabled } from "../../helpers/constants/configParts"; -// -// const networkLogger = createNetworkLogger(); -// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; -// -// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -// const config = compose(orgMainConfigMain, debugEnabled); -// -// const mockResponse = { -// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", -// handle: [ -// { -// payload: [ -// { -// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", -// scope: "mobileapp://com.adobe.aguaAppIos", -// scopeDetails: { -// decisionProvider: "AJO", -// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", -// characteristics: { -// eventToken: -// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" -// }, -// activity: { -// id: -// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" -// } -// }, -// items: [ -// { -// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "~type", -// matcher: "eq", -// values: [ -// "com.adobe.eventType.generic.track" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "~source", -// matcher: "eq", -// values: [ -// "com.adobe.eventSource.requestContent" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", -// matcher: "eq", -// values: [2] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// id: "c46c7d03-eb06-4596-9087-272486cb6c41", -// type: "cjmiam", -// detail: { -// mobileParameters: { -// verticalAlign: "center", -// dismissAnimation: "top", -// verticalInset: 0, -// backdropOpacity: 0.75, -// gestures: { -// swipeUp: "adbinapp://dismiss?interaction=swipeUp", -// swipeDown: -// "adbinapp://dismiss?interaction=swipeDown", -// swipeLeft: -// "adbinapp://dismiss?interaction=swipeLeft", -// swipeRight: -// "adbinapp://dismiss?interaction=swipeRight", -// tapBackground: -// "adbinapp://dismiss?interaction=tapBackground" -// }, -// cornerRadius: 15, -// horizontalInset: 0, -// uiTakeover: true, -// horizontalAlign: "center", -// displayAnimation: "top", -// width: 80, -// backdropColor: "#ffa500", -// height: 60 -// }, -// html: -// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', -// remoteAssets: [ -// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" -// ] -// } -// } -// ] -// } -// ] -// } -// } -// ] -// } -// ], -// type: "personalization:decisions", -// eventIndex: 0 -// }, -// { -// payload: [ -// { -// scope: "Target", -// hint: "35", -// ttlSeconds: 1800 -// }, -// { -// scope: "AAM", -// hint: "9", -// ttlSeconds: 1800 -// }, -// { -// scope: "EdgeNetwork", -// hint: "or2", -// ttlSeconds: 1800 -// } -// ], -// type: "locationHint:result" -// }, -// { -// payload: [ -// { -// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", -// value: "or2", -// maxAge: 1800, -// attrs: { -// SameSite: "None" -// } -// } -// ], -// type: "state:store" -// } -// ] -// }; -// -// createFixture({ -// title: "Test C13348429: Verify DOM action using the applyResponse command.", -// requestHooks: [networkLogger.edgeEndpointLogs], -// url: `${TEST_PAGE_URL}?test=C13348429` -// }); -// -// test.meta({ -// ID: "C13348429", -// SEVERITY: "P0", -// TEST_RUN: "Regression" -// }); -// -// const getIframeContainer = ClientFunction(() => { -// const element = document.querySelector("#alloy-messaging-container"); -// return element ? element.innerHTML : ""; -// }); -// -// test("Test C13348429: Verify DOM action using the applyResponse command.", async () => { -// const alloy = createAlloyProxy(); -// await alloy.configure(config); -// await alloy.sendEvent({}); -// -// await alloy.applyResponse({ -// renderDecisions: true, -// decisionContext: { -// "~type": "com.adobe.eventType.generic.track", -// "~source": "com.adobe.eventSource.requestContent", -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 -// }, -// responseBody: mockResponse -// }); -// const containerElement = await getIframeContainer(); -// await t.expect(containerElement).contains("alloy-content-iframe"); -// }); +import { ClientFunction, t } from "testcafe"; +import createNetworkLogger from "../../helpers/networkLogger"; +import createFixture from "../../helpers/createFixture"; +import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +import createAlloyProxy from "../../helpers/createAlloyProxy"; +import getBaseConfig from "../../helpers/getBaseConfig"; +import { compose, debugEnabled } from "../../helpers/constants/configParts"; + +const networkLogger = createNetworkLogger(); +const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; + +const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +const config = compose(orgMainConfigMain, debugEnabled); + +const mockResponse = { + requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", + handle: [ + { + payload: [ + { + id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", + characteristics: { + eventToken: + "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" + }, + activity: { + id: + "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" + } + }, + items: [ + { + id: "f5134bfa-381e-4b94-8546-d7023e1f3601", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "~type", + matcher: "eq", + values: [ + "com.adobe.eventType.generic.track" + ] + }, + type: "matcher" + }, + { + definition: { + key: "~source", + matcher: "eq", + values: [ + "com.adobe.eventSource.requestContent" + ] + }, + type: "matcher" + }, + { + definition: { + key: + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", + matcher: "eq", + values: [2] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + id: "c46c7d03-eb06-4596-9087-272486cb6c41", + type: "cjmiam", + detail: { + mobileParameters: { + verticalAlign: "center", + dismissAnimation: "top", + verticalInset: 0, + backdropOpacity: 0.75, + gestures: { + swipeUp: "adbinapp://dismiss?interaction=swipeUp", + swipeDown: + "adbinapp://dismiss?interaction=swipeDown", + swipeLeft: + "adbinapp://dismiss?interaction=swipeLeft", + swipeRight: + "adbinapp://dismiss?interaction=swipeRight", + tapBackground: + "adbinapp://dismiss?interaction=tapBackground" + }, + cornerRadius: 15, + horizontalInset: 0, + uiTakeover: true, + horizontalAlign: "center", + displayAnimation: "top", + width: 80, + backdropColor: "#ffa500", + height: 60 + }, + html: + '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', + remoteAssets: [ + "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" + ] + } + } + ] + } + ] + } + } + ] + } + ], + type: "personalization:decisions", + eventIndex: 0 + }, + { + payload: [ + { + scope: "Target", + hint: "35", + ttlSeconds: 1800 + }, + { + scope: "AAM", + hint: "9", + ttlSeconds: 1800 + }, + { + scope: "EdgeNetwork", + hint: "or2", + ttlSeconds: 1800 + } + ], + type: "locationHint:result" + }, + { + payload: [ + { + key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", + value: "or2", + maxAge: 1800, + attrs: { + SameSite: "None" + } + } + ], + type: "state:store" + } + ] +}; + +createFixture({ + title: "Test C13348429: Verify DOM action using the applyResponse command.", + requestHooks: [networkLogger.edgeEndpointLogs], + url: `${TEST_PAGE_URL}?test=C13348429` +}); + +test.meta({ + ID: "C13348429", + SEVERITY: "P0", + TEST_RUN: "Regression" +}); + +const getIframeContainer = ClientFunction(() => { + const element = document.querySelector("#alloy-messaging-container"); + return element ? element.innerHTML : ""; +}); + +test("Test C13348429: Verify DOM action using the applyResponse command.", async () => { + const alloy = createAlloyProxy(); + await alloy.configure(config); + await alloy.sendEvent({}); + + await alloy.applyResponse({ + renderDecisions: true, + decisionContext: { + "~type": "com.adobe.eventType.generic.track", + "~source": "com.adobe.eventSource.requestContent", + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 + }, + responseBody: mockResponse + }); + const containerElement = await getIframeContainer(); + await t.expect(containerElement).contains("alloy-content-iframe"); +}); diff --git a/test/functional/specs/DecisioningEngine/C13405889.js b/test/functional/specs/DecisioningEngine/C13405889.js index 88f825074..1d10b13ff 100644 --- a/test/functional/specs/DecisioningEngine/C13405889.js +++ b/test/functional/specs/DecisioningEngine/C13405889.js @@ -9,223 +9,212 @@ 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. */ -// /* -// 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 { ClientFunction, t } from "testcafe"; -// import createNetworkLogger from "../../helpers/networkLogger"; -// import createFixture from "../../helpers/createFixture"; -// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -// import createAlloyProxy from "../../helpers/createAlloyProxy"; -// import getBaseConfig from "../../helpers/getBaseConfig"; -// import { compose, debugEnabled } from "../../helpers/constants/configParts"; -// -// const networkLogger = createNetworkLogger(); -// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; -// -// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -// const config = compose(orgMainConfigMain, debugEnabled); -// -// const mockResponse = { -// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", -// handle: [ -// { -// payload: [ -// { -// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", -// scope: "mobileapp://com.adobe.aguaAppIos", -// scopeDetails: { -// decisionProvider: "AJO", -// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", -// characteristics: { -// eventToken: -// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" -// }, -// activity: { -// id: -// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" -// } -// }, -// items: [ -// { -// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "~type", -// matcher: "eq", -// values: [ -// "com.adobe.eventType.generic.track" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "~source", -// matcher: "eq", -// values: [ -// "com.adobe.eventSource.requestContent" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", -// matcher: "eq", -// values: [2] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// id: "c46c7d03-eb06-4596-9087-272486cb6c41", -// type: "cjmiam", -// detail: { -// mobileParameters: { -// verticalAlign: "center", -// dismissAnimation: "top", -// verticalInset: 0, -// backdropOpacity: 0.75, -// gestures: { -// swipeUp: "adbinapp://dismiss?interaction=swipeUp", -// swipeDown: -// "adbinapp://dismiss?interaction=swipeDown", -// swipeLeft: -// "adbinapp://dismiss?interaction=swipeLeft", -// swipeRight: -// "adbinapp://dismiss?interaction=swipeRight", -// tapBackground: -// "adbinapp://dismiss?interaction=tapBackground" -// }, -// cornerRadius: 15, -// horizontalInset: 0, -// uiTakeover: true, -// horizontalAlign: "center", -// displayAnimation: "top", -// width: 80, -// backdropColor: "#ffa500", -// height: 60 -// }, -// html: -// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', -// remoteAssets: [ -// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" -// ] -// } -// } -// ] -// } -// ] -// } -// } -// ] -// } -// ], -// type: "personalization:decisions", -// eventIndex: 0 -// }, -// { -// payload: [ -// { -// scope: "Target", -// hint: "35", -// ttlSeconds: 1800 -// }, -// { -// scope: "AAM", -// hint: "9", -// ttlSeconds: 1800 -// }, -// { -// scope: "EdgeNetwork", -// hint: "or2", -// ttlSeconds: 1800 -// } -// ], -// type: "locationHint:result" -// }, -// { -// payload: [ -// { -// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", -// value: "or2", -// maxAge: 1800, -// attrs: { -// SameSite: "None" -// } -// } -// ], -// type: "state:store" -// } -// ] -// }; -// -// createFixture({ -// title: "Test C13405889: Verify DOM action using the evaluateRulesets command", -// requestHooks: [networkLogger.edgeEndpointLogs], -// url: `${TEST_PAGE_URL}?test=C13348429` -// }); -// -// test.meta({ -// ID: "C13405889", -// SEVERITY: "P0", -// TEST_RUN: "Regression" -// }); -// -// const getIframeContainer = ClientFunction(() => { -// const element = document.querySelector("#alloy-messaging-container"); -// return element ? element.innerHTML : ""; -// }); -// -// test("Test C13405889: Verify DOM action using the evaluateRulesets command", async () => { -// const alloy = createAlloyProxy(); -// await alloy.configure(config); -// await alloy.sendEvent({}); -// -// await alloy.applyResponse({ -// renderDecisions: false, -// responseBody: mockResponse -// }); -// await alloy.evaluateRulesets({ -// renderDecisions: true, -// decisionContext: { -// "~type": "com.adobe.eventType.generic.track", -// "~source": "com.adobe.eventSource.requestContent", -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 -// } -// }); -// const containerElement = await getIframeContainer(); -// await t.expect(containerElement).contains("alloy-content-iframe"); -// }); +import { ClientFunction, t } from "testcafe"; +import createNetworkLogger from "../../helpers/networkLogger"; +import createFixture from "../../helpers/createFixture"; +import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +import createAlloyProxy from "../../helpers/createAlloyProxy"; +import getBaseConfig from "../../helpers/getBaseConfig"; +import { compose, debugEnabled } from "../../helpers/constants/configParts"; + +const networkLogger = createNetworkLogger(); +const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; + +const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +const config = compose(orgMainConfigMain, debugEnabled); + +const mockResponse = { + requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", + handle: [ + { + payload: [ + { + id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", + characteristics: { + eventToken: + "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" + }, + activity: { + id: + "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" + } + }, + items: [ + { + id: "f5134bfa-381e-4b94-8546-d7023e1f3601", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "~type", + matcher: "eq", + values: [ + "com.adobe.eventType.generic.track" + ] + }, + type: "matcher" + }, + { + definition: { + key: "~source", + matcher: "eq", + values: [ + "com.adobe.eventSource.requestContent" + ] + }, + type: "matcher" + }, + { + definition: { + key: + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", + matcher: "eq", + values: [2] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + id: "c46c7d03-eb06-4596-9087-272486cb6c41", + type: "cjmiam", + detail: { + mobileParameters: { + verticalAlign: "center", + dismissAnimation: "top", + verticalInset: 0, + backdropOpacity: 0.75, + gestures: { + swipeUp: "adbinapp://dismiss?interaction=swipeUp", + swipeDown: + "adbinapp://dismiss?interaction=swipeDown", + swipeLeft: + "adbinapp://dismiss?interaction=swipeLeft", + swipeRight: + "adbinapp://dismiss?interaction=swipeRight", + tapBackground: + "adbinapp://dismiss?interaction=tapBackground" + }, + cornerRadius: 15, + horizontalInset: 0, + uiTakeover: true, + horizontalAlign: "center", + displayAnimation: "top", + width: 80, + backdropColor: "#ffa500", + height: 60 + }, + html: + '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', + remoteAssets: [ + "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" + ] + } + } + ] + } + ] + } + } + ] + } + ], + type: "personalization:decisions", + eventIndex: 0 + }, + { + payload: [ + { + scope: "Target", + hint: "35", + ttlSeconds: 1800 + }, + { + scope: "AAM", + hint: "9", + ttlSeconds: 1800 + }, + { + scope: "EdgeNetwork", + hint: "or2", + ttlSeconds: 1800 + } + ], + type: "locationHint:result" + }, + { + payload: [ + { + key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", + value: "or2", + maxAge: 1800, + attrs: { + SameSite: "None" + } + } + ], + type: "state:store" + } + ] +}; + +createFixture({ + title: "Test C13405889: Verify DOM action using the evaluateRulesets command", + requestHooks: [networkLogger.edgeEndpointLogs], + url: `${TEST_PAGE_URL}?test=C13348429` +}); + +test.meta({ + ID: "C13405889", + SEVERITY: "P0", + TEST_RUN: "Regression" +}); + +const getIframeContainer = ClientFunction(() => { + const element = document.querySelector("#alloy-messaging-container"); + return element ? element.innerHTML : ""; +}); + +test("Test C13405889: Verify DOM action using the evaluateRulesets command", async () => { + const alloy = createAlloyProxy(); + await alloy.configure(config); + await alloy.sendEvent({}); + + await alloy.applyResponse({ + renderDecisions: false, + responseBody: mockResponse + }); + await alloy.evaluateRulesets({ + renderDecisions: true, + decisionContext: { + "~type": "com.adobe.eventType.generic.track", + "~source": "com.adobe.eventSource.requestContent", + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 + } + }); + const containerElement = await getIframeContainer(); + await t.expect(containerElement).contains("alloy-content-iframe"); +}); diff --git a/test/functional/specs/DecisioningEngine/C13419240.js b/test/functional/specs/DecisioningEngine/C13419240.js index c45ef9fc6..09619111b 100644 --- a/test/functional/specs/DecisioningEngine/C13419240.js +++ b/test/functional/specs/DecisioningEngine/C13419240.js @@ -9,225 +9,214 @@ 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. */ -// /* -// 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 { ClientFunction, t } from "testcafe"; -// import createNetworkLogger from "../../helpers/networkLogger"; -// import createFixture from "../../helpers/createFixture"; -// import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; -// import createAlloyProxy from "../../helpers/createAlloyProxy"; -// import getBaseConfig from "../../helpers/getBaseConfig"; -// import { compose, debugEnabled } from "../../helpers/constants/configParts"; -// -// const networkLogger = createNetworkLogger(); -// const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; -// const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; -// -// const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); -// const config = compose(orgMainConfigMain, debugEnabled); -// -// const mockResponse = { -// requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", -// handle: [ -// { -// payload: [ -// { -// id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", -// scope: "mobileapp://com.adobe.aguaAppIos", -// scopeDetails: { -// decisionProvider: "AJO", -// correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", -// characteristics: { -// eventToken: -// "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" -// }, -// activity: { -// id: -// "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" -// } -// }, -// items: [ -// { -// id: "f5134bfa-381e-4b94-8546-d7023e1f3601", -// schema: "https://ns.adobe.com/personalization/ruleset-item", -// data: { -// version: 1, -// rules: [ -// { -// condition: { -// definition: { -// conditions: [ -// { -// definition: { -// conditions: [ -// { -// definition: { -// key: "~type", -// matcher: "eq", -// values: [ -// "com.adobe.eventType.generic.track" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: "~source", -// matcher: "eq", -// values: [ -// "com.adobe.eventSource.requestContent" -// ] -// }, -// type: "matcher" -// }, -// { -// definition: { -// key: -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", -// matcher: "eq", -// values: [2] -// }, -// type: "matcher" -// } -// ], -// logic: "and" -// }, -// type: "group" -// } -// ], -// logic: "and" -// }, -// type: "group" -// }, -// consequences: [ -// { -// id: "c46c7d03-eb06-4596-9087-272486cb6c41", -// type: "cjmiam", -// detail: { -// mobileParameters: { -// verticalAlign: "center", -// dismissAnimation: "top", -// verticalInset: 0, -// backdropOpacity: 0.75, -// gestures: { -// swipeUp: "adbinapp://dismiss?interaction=swipeUp", -// swipeDown: -// "adbinapp://dismiss?interaction=swipeDown", -// swipeLeft: -// "adbinapp://dismiss?interaction=swipeLeft", -// swipeRight: -// "adbinapp://dismiss?interaction=swipeRight", -// tapBackground: -// "adbinapp://dismiss?interaction=tapBackground" -// }, -// cornerRadius: 15, -// horizontalInset: 0, -// uiTakeover: true, -// horizontalAlign: "center", -// displayAnimation: "top", -// width: 80, -// backdropColor: "#ffa500", -// height: 60 -// }, -// html: -// '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', -// remoteAssets: [ -// "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" -// ] -// } -// } -// ] -// } -// ] -// } -// } -// ] -// } -// ], -// type: "personalization:decisions", -// eventIndex: 0 -// }, -// { -// payload: [ -// { -// scope: "Target", -// hint: "35", -// ttlSeconds: 1800 -// }, -// { -// scope: "AAM", -// hint: "9", -// ttlSeconds: 1800 -// }, -// { -// scope: "EdgeNetwork", -// hint: "or2", -// ttlSeconds: 1800 -// } -// ], -// type: "locationHint:result" -// }, -// { -// payload: [ -// { -// key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", -// value: "or2", -// maxAge: 1800, -// attrs: { -// SameSite: "None" -// } -// } -// ], -// type: "state:store" -// } -// ] -// }; -// -// createFixture({ -// title: "Test C13419240: Verify DOM action using the sendEvent command", -// requestHooks: [networkLogger.edgeEndpointLogs], -// url: `${TEST_PAGE_URL}?test=C13348429` -// }); -// -// test.meta({ -// ID: "C13419240", -// SEVERITY: "P0", -// TEST_RUN: "Regression" -// }); -// -// const getIframeContainer = ClientFunction(() => { -// const element = document.querySelector("#alloy-messaging-container"); -// return element ? element.innerHTML : ""; -// }); -// -// test("Test C13419240: Verify DOM action using the sendEvent command", async () => { -// const alloy = createAlloyProxy(); -// await alloy.configure(config); -// await alloy.sendEvent({}); // establish an identity -// -// await alloy.applyResponse({ -// renderDecisions: false, -// responseBody: mockResponse -// }); -// -// await alloy.sendEvent({ -// renderDecisions: true, -// decisionContext: { -// "~type": "com.adobe.eventType.generic.track", -// "~source": "com.adobe.eventSource.requestContent", -// "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 -// } -// }); -// -// const containerElement = await getIframeContainer(); -// await t.expect(containerElement).contains("alloy-content-iframe"); -// }); +import { ClientFunction, t } from "testcafe"; +import createNetworkLogger from "../../helpers/networkLogger"; +import createFixture from "../../helpers/createFixture"; +import { TEST_PAGE as TEST_PAGE_URL } from "../../helpers/constants/url"; +import createAlloyProxy from "../../helpers/createAlloyProxy"; +import getBaseConfig from "../../helpers/getBaseConfig"; +import { compose, debugEnabled } from "../../helpers/constants/configParts"; + +const networkLogger = createNetworkLogger(); +const organizationId = "4DA0571C5FDC4BF70A495FC2@AdobeOrg"; +const dataStreamId = "7a19c434-6648-48d3-948f-ba0258505d98"; + +const orgMainConfigMain = getBaseConfig(organizationId, dataStreamId); +const config = compose(orgMainConfigMain, debugEnabled); + +const mockResponse = { + requestId: "5a38a9ef-67d7-4f66-8977-c4dc0e0967b6", + handle: [ + { + payload: [ + { + id: "a4486740-0a6d-433a-8b65-bfb3ac20485d", + scope: "mobileapp://com.adobe.aguaAppIos", + scopeDetails: { + decisionProvider: "AJO", + correlationID: "a6b7639b-6606-42af-9679-48eb138632d2", + characteristics: { + eventToken: + "eyJtZXNzYWdlRXhlY3V0aW9uIjp7Im1lc3NhZ2VFeGVjdXRpb25JRCI6Ik5BIiwibWVzc2FnZUlEIjoiYTZiNzYzOWItNjYwNi00MmFmLTk2NzktNDhlYjEzODYzMmQyIiwibWVzc2FnZVB1YmxpY2F0aW9uSUQiOiIzZjQxZGNjNy1mNDE0LTRlMmYtYTdjOS1hMTk4ODdlYzNlNWEiLCJtZXNzYWdlVHlwZSI6Im1hcmtldGluZyIsImNhbXBhaWduSUQiOiIwY2RmMDFkZi02ZmE5LTQ0MjktOGE3My05M2ZiY2U1NTIyYWEiLCJjYW1wYWlnblZlcnNpb25JRCI6ImFiYWVhMThhLTJmNzEtNDZlMy1iZWRmLTUxNzg0YTE4MWJiZiIsImNhbXBhaWduQWN0aW9uSUQiOiIzZmIxMTY1OC1iOTMyLTRlMDktYWIyNy03ZWEyOTc2NzY2YTUifSwibWVzc2FnZVByb2ZpbGUiOnsibWVzc2FnZVByb2ZpbGVJRCI6ImVlY2U5NDNlLWVlNWYtNGMwNC1iZGI1LTQ5YjFhMjViMTNmZSIsImNoYW5uZWwiOnsiX2lkIjoiaHR0cHM6Ly9ucy5hZG9iZS5jb20veGRtL2NoYW5uZWxzL2luQXBwIiwiX3R5cGUiOiJodHRwczovL25zLmFkb2JlLmNvbS94ZG0vY2hhbm5lbC10eXBlcy9pbkFwcCJ9fX0=" + }, + activity: { + id: + "0cdf01df-6fa9-4429-8a73-93fbce5522aa#3fb11658-b932-4e09-ab27-7ea2976766a5" + } + }, + items: [ + { + id: "f5134bfa-381e-4b94-8546-d7023e1f3601", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "~type", + matcher: "eq", + values: [ + "com.adobe.eventType.generic.track" + ] + }, + type: "matcher" + }, + { + definition: { + key: "~source", + matcher: "eq", + values: [ + "com.adobe.eventSource.requestContent" + ] + }, + type: "matcher" + }, + { + definition: { + key: + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", + matcher: "eq", + values: [2] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + id: "c46c7d03-eb06-4596-9087-272486cb6c41", + type: "cjmiam", + detail: { + mobileParameters: { + verticalAlign: "center", + dismissAnimation: "top", + verticalInset: 0, + backdropOpacity: 0.75, + gestures: { + swipeUp: "adbinapp://dismiss?interaction=swipeUp", + swipeDown: + "adbinapp://dismiss?interaction=swipeDown", + swipeLeft: + "adbinapp://dismiss?interaction=swipeLeft", + swipeRight: + "adbinapp://dismiss?interaction=swipeRight", + tapBackground: + "adbinapp://dismiss?interaction=tapBackground" + }, + cornerRadius: 15, + horizontalInset: 0, + uiTakeover: true, + horizontalAlign: "center", + displayAnimation: "top", + width: 80, + backdropColor: "#ffa500", + height: 60 + }, + html: + '\n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n

Fifty percent off!

One hour only!

\n \n\n', + remoteAssets: [ + "https://media3.giphy.com/media/R7ifMrDG24Uc89TpZH/giphy.gif?cid=ecf05e47ohtez4exx2e0u3x1zko365r8pw6lqw0qtjq32z2h&ep=v1_gifs_search&rid=giphy.gif&ct=g" + ] + } + } + ] + } + ] + } + } + ] + } + ], + type: "personalization:decisions", + eventIndex: 0 + }, + { + payload: [ + { + scope: "Target", + hint: "35", + ttlSeconds: 1800 + }, + { + scope: "AAM", + hint: "9", + ttlSeconds: 1800 + }, + { + scope: "EdgeNetwork", + hint: "or2", + ttlSeconds: 1800 + } + ], + type: "locationHint:result" + }, + { + payload: [ + { + key: "kndctr_4DA0571C5FDC4BF70A495FC2_AdobeOrg_cluster", + value: "or2", + maxAge: 1800, + attrs: { + SameSite: "None" + } + } + ], + type: "state:store" + } + ] +}; + +createFixture({ + title: "Test C13419240: Verify DOM action using the sendEvent command", + requestHooks: [networkLogger.edgeEndpointLogs], + url: `${TEST_PAGE_URL}?test=C13348429` +}); + +test.meta({ + ID: "C13419240", + SEVERITY: "P0", + TEST_RUN: "Regression" +}); + +const getIframeContainer = ClientFunction(() => { + const element = document.querySelector("#alloy-messaging-container"); + return element ? element.innerHTML : ""; +}); + +test("Test C13419240: Verify DOM action using the sendEvent command", async () => { + const alloy = createAlloyProxy(); + await alloy.configure(config); + await alloy.sendEvent({}); // establish an identity + + await alloy.applyResponse({ + renderDecisions: false, + responseBody: mockResponse + }); + + await alloy.sendEvent({ + renderDecisions: true, + decisionContext: { + "~type": "com.adobe.eventType.generic.track", + "~source": "com.adobe.eventSource.requestContent", + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": 2 + } + }); + + const containerElement = await getIframeContainer(); + await t.expect(containerElement).contains("alloy-content-iframe"); +}); From 5b4d5074a976c4e6dfae1615c69008d699429074 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 3 Oct 2023 13:34:55 -0700 Subject: [PATCH 17/27] support day of week and hour as described in authoring ui --- .../DecisioningEngine/createContextProvider.js | 9 +++++---- .../decisioningContext.timestamp.spec.js | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 0e8bbe456..b3ef027d2 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -42,13 +42,14 @@ export default ({ eventRegistry, window }) => { pageLoadTimestamp, currentTimestamp, currentDate: now.getDate(), - currentDay: now.getDay(), - currentHour: now.getHours(), + // Day of the week starts on Monday as is practiced in ISO 8601, but we want it to start on Sunday to match the authoring UI rule + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek": + now.getDay() + 1, + "~state.com.adobe.module.lifecycle/lifecyclecontextdata.hourofday": now.getHours(), currentMinute: now.getMinutes(), currentMonth: now.getMonth(), currentYear: now.getFullYear(), - pageVisitDuration: currentTimestamp - pageLoadTimestamp, - "~state.com.adobe.module.lifecycle/lifecyclecontextdata.hourofday": now.getHours() + pageVisitDuration: currentTimestamp - pageLoadTimestamp }; }; diff --git a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js index c81b8712d..9859a8132 100644 --- a/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js +++ b/test/unit/specs/components/DecisioningEngine/decisioningContext.timestamp.spec.js @@ -133,9 +133,9 @@ describe("DecisioningEngine:globalContext:timeContext", () => { it("satisfies rule based on matched currentDay", async () => { await setupResponseHandler(applyResponse, mockWindow({}), { definition: { - key: "currentDay", + key: "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", matcher: "eq", - values: [mockedTimestamp.getDay()] + values: [mockedTimestamp.getDay() + 1] }, type: "matcher" }); @@ -150,9 +150,9 @@ describe("DecisioningEngine:globalContext:timeContext", () => { it("does not satisfy rule due to unmatched currentDay", async () => { await setupResponseHandler(applyResponse, mockWindow({}), { definition: { - key: "currentDay", + key: "~state.com.adobe.module.lifecycle/lifecyclecontextdata.dayofweek", matcher: "eq", - values: [mockedTimestamp.getDay() + 1] + values: [mockedTimestamp.getDay()] }, type: "matcher" }); @@ -167,7 +167,7 @@ describe("DecisioningEngine:globalContext:timeContext", () => { it("satisfies rule based on matched currentHour", async () => { await setupResponseHandler(applyResponse, mockWindow({}), { definition: { - key: "currentHour", + key: "~state.com.adobe.module.lifecycle/lifecyclecontextdata.hourofday", matcher: "eq", values: [mockedTimestamp.getHours()] }, @@ -184,7 +184,7 @@ describe("DecisioningEngine:globalContext:timeContext", () => { it("does not satisfy rule due to unmatched currentHour", async () => { await setupResponseHandler(applyResponse, mockWindow({}), { definition: { - key: "currentHour", + key: "~state.com.adobe.module.lifecycle/lifecyclecontextdata.hourofday", matcher: "eq", values: [mockedTimestamp.getHours() + 1] }, From ebbac68a5d8aa49735c5e770bdb29ee8378f6cfe Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 11:26:25 -0700 Subject: [PATCH 18/27] moved indexedJS creation in a dedicated module --- .../DecisioningEngine/createEventRegistry.js | 123 +++--------------- .../DecisioningEngine/createIndexedDB.js | 118 +++++++++++++++++ src/components/DecisioningEngine/index.js | 6 +- .../DecisioningEngine/contextTestUtils.js | 6 +- .../createContextProvider.spec.js | 54 ++++---- .../createDecisionProvider.spec.js | 16 ++- .../createEvaluableRulesetPayload.spec.js | 14 +- .../createEvaluateRulesetsCommand.spec.js | 12 +- .../createEventRegistry.spec.js | 15 ++- .../DecisioningEngine/createIndexedDB.spec.js | 40 ++++++ .../createOnResponseHandler.spec.js | 15 ++- .../DecisioningEngine/index.spec.js | 50 ++++--- 12 files changed, 299 insertions(+), 170 deletions(-) create mode 100644 src/components/DecisioningEngine/createIndexedDB.js create mode 100644 test/unit/specs/components/DecisioningEngine/createIndexedDB.spec.js diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index ec391a0ee..af3a51a2b 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -9,16 +9,12 @@ 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 { HISTORICAL_DATA_STORE } from "./constants"; import { EVENT_TYPE_TRUE } from "../Personalization/event"; import { getActivityId } from "./utils"; -const dbName = HISTORICAL_DATA_STORE; const PREFIX_TO_SUPPORT_INDEX_DB = key => `iam_${key}`; -export default () => { - let db; - +export default ({ indexedDB }) => { const replaceUnderscoreWithDot = record => { const updatedRecord = {}; Object.keys(record).forEach(key => { @@ -27,63 +23,14 @@ export default () => { return updatedRecord; }; - const setupIndexedDB = () => { - return new Promise((resolve, reject) => { - if (!("indexedDB" in window)) { - reject(new Error("This browser doesn't support IndexedDB.")); - } - - const request = indexedDB.open(dbName, 1); - - request.onerror = event => { - const dbRequest = event.target; - reject(dbRequest.error); - }; - - request.onupgradeneeded = event => { - db = event.target.result; - - const objectStore = db.createObjectStore("events", { - keyPath: "id", - autoIncrement: true - }); - objectStore.createIndex( - "iam_id_iam_eventType_index", - ["iam_id", "iam_eventType"], - { unique: false } - ); - }; - - request.onsuccess = event => { - db = event.target.result; - console.log("IndexedDB setup complete"); - resolve(true); - }; - }); - }; - const addEvent = (event, eventType, eventId, action) => { - return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readwrite"); - const objectStore = transaction.objectStore("events"); - const record = { - [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, - [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, - action, - timestamp: new Date().getTime() - }; - - const objectStoreRequest = objectStore.add(record); - - objectStoreRequest.onerror = txEvent => { - const dbRequest = txEvent.target; - reject(dbRequest.error); - }; - - objectStoreRequest.onsuccess = () => { - resolve(true); - }; - }); + const record = { + [PREFIX_TO_SUPPORT_INDEX_DB("id")]: eventId, + [PREFIX_TO_SUPPORT_INDEX_DB("eventType")]: eventType, + action, + timestamp: new Date().getTime() + }; + return indexedDB.addRecord(record); }; const addExperienceEdgeEvent = event => { @@ -114,7 +61,6 @@ export default () => { } const { id: action } = propositionAction; - propositionEventTypesList.forEach(propositionEventType => { if (propositionEventTypeObj[propositionEventType] === EVENT_TYPE_TRUE) { propositions.forEach(proposition => { @@ -130,25 +76,14 @@ export default () => { }; const getEvents = (eventType, eventId) => { - return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readonly"); - const objectStore = transaction.objectStore("events"); - const index = objectStore.index("iam_id_iam_eventType_index"); - - const request = index.getAll([eventId, eventType]); - - request.onsuccess = eventObjStore => { - const dbRequest = eventObjStore.target; - const data = dbRequest - ? dbRequest.result.map(record => replaceUnderscoreWithDot(record)) - : []; - resolve(data); - }; - - request.onerror = eventObjStore => { - const dbRequest = eventObjStore.target; - reject(dbRequest.error); - }; + return new Promise(resolve => { + indexedDB.getRecords(eventType, eventId).then(events => { + resolve( + events && events.length > 0 + ? events.map(record => replaceUnderscoreWithDot(record)) + : [] + ); + }); }); }; @@ -173,35 +108,11 @@ export default () => { }); }; - setupIndexedDB() - .then(() => {}) - .catch(error => { - console.error("error message: ", error.message); - }); - - const clearIndexedDB = () => { - return new Promise((resolve, reject) => { - try { - const transaction = db.transaction("events", "readwrite"); - const objectStore = transaction.objectStore("events"); - const request = objectStore.clear(); - - request.onsuccess = () => { - resolve(true); - }; - } catch (error) { - reject(error); - } - }); - }; - return { - setupIndexedDB, addEvent, addExperienceEdgeEvent, - clearIndexedDB, getEvents, getEventsFirstTimestamp, - getIndexDB: () => db + getIndexDB: () => indexedDB.getIndexDB() }; }; diff --git a/src/components/DecisioningEngine/createIndexedDB.js b/src/components/DecisioningEngine/createIndexedDB.js new file mode 100644 index 000000000..149adb3de --- /dev/null +++ b/src/components/DecisioningEngine/createIndexedDB.js @@ -0,0 +1,118 @@ +/* +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 { HISTORICAL_DATA_STORE } from "./constants"; + +const dbName = HISTORICAL_DATA_STORE; + +export default () => { + let db; + + const setupIndexedDB = () => { + return new Promise((resolve, reject) => { + if (!("indexedDB" in window)) { + reject(new Error("This browser doesn't support IndexedDB.")); + } + + const request = indexedDB.open(dbName, 1); + + request.onerror = event => { + const dbRequest = event.target; + reject(dbRequest.error); + }; + + request.onupgradeneeded = event => { + db = event.target.result; + + const objectStore = db.createObjectStore("events", { + keyPath: "id", + autoIncrement: true + }); + objectStore.createIndex( + "iam_id_iam_eventType_index", + ["iam_id", "iam_eventType"], + { unique: false } + ); + }; + + request.onsuccess = event => { + db = event.target.result; + resolve(true); + }; + }); + }; + + const addRecord = record => { + return new Promise((resolve, reject) => { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + const objectStoreRequest = objectStore.add(record); + + objectStoreRequest.onerror = txEvent => { + const dbRequest = txEvent.target; + reject(dbRequest.error); + }; + + objectStoreRequest.onsuccess = () => { + resolve(true); + }; + }); + }; + + const getRecords = (eventType, eventId) => { + return new Promise((resolve, reject) => { + const transaction = db.transaction("events", "readonly"); + const objectStore = transaction.objectStore("events"); + const index = objectStore.index("iam_id_iam_eventType_index"); + const request = index.getAll([eventId, eventType]); + + request.onsuccess = eventObjStore => { + const dbRequest = eventObjStore.target; + resolve(dbRequest ? dbRequest.result : []); + }; + + request.onerror = eventObjStore => { + const dbRequest = eventObjStore.target; + reject(dbRequest.error); + }; + }); + }; + + // setupIndexedDB() + // .then(() => {}) + // .catch(error => { + // console.error("error message: ", error.message); + // }); + + const clearIndexedDB = () => { + return new Promise((resolve, reject) => { + try { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + const request = objectStore.clear(); + + request.onsuccess = () => { + resolve(true); + }; + } catch (error) { + reject(error); + } + }); + }; + + return { + setupIndexedDB, + addRecord, + clearIndexedDB, + getRecords, + getIndexDB: () => db + }; +}; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 73a5839c1..b130da930 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -17,6 +17,7 @@ import createEventRegistry from "./createEventRegistry"; import createContextProvider from "./createContextProvider"; import createSubscribeRulesetItems from "./createSubscribeRulesetItems"; import { ensureSchemaBasedRulesetConsequences } from "./utils"; +import createIndexedDB from "./createIndexedDB"; import { CONTEXT_KEY, @@ -26,7 +27,10 @@ import { import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; const createDecisioningEngine = () => { - const eventRegistry = createEventRegistry(); + const indexedDB = createIndexedDB(); + indexedDB.setupIndexedDB(); + + const eventRegistry = createEventRegistry({ indexedDB }); let applyResponse; const decisionProvider = createDecisionProvider({ eventRegistry }); diff --git a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js index f40f2360e..58c58c97f 100644 --- a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js +++ b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js @@ -13,6 +13,7 @@ import createContextProvider from "../../../../../src/components/DecisioningEngi import createOnResponseHandler from "../../../../../src/components/DecisioningEngine/createOnResponseHandler"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; export const proposition = { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", @@ -122,8 +123,9 @@ export const setupResponseHandler = async ( window, condition ) => { - const eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); + const indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + const eventRegistry = createEventRegistry({ indexedDB }); const decisionProvider = createDecisionProvider({ eventRegistry }); const contextProvider = createContextProvider({ eventRegistry, window }); diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index cdbb5071a..812676d6b 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -11,14 +11,19 @@ governing permissions and limitations under the License. */ import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:createContextProvider", () => { - let contextProvider; - let eventRegistry; let window; let mockedTimestamp; + let indexedDB; - beforeEach(() => { + beforeAll(async () => { + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + }); + + beforeEach(async () => { window = { title: "My awesome website", referrer: "https://stage.applookout.net/", @@ -37,13 +42,18 @@ describe("DecisioningEngine:createContextProvider", () => { jasmine.clock().mockDate(mockedTimestamp); }); - afterEach(() => { + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + + afterEach(async () => { jasmine.clock().uninstall(); }); + it("returns page context", async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); - contextProvider = createContextProvider({ eventRegistry, window }); + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -60,9 +70,8 @@ describe("DecisioningEngine:createContextProvider", () => { ); }); it("returns referring page context", async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); - contextProvider = createContextProvider({ eventRegistry, window }); + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -77,9 +86,8 @@ describe("DecisioningEngine:createContextProvider", () => { ); }); it("returns browser context", async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); - contextProvider = createContextProvider({ eventRegistry, window }); + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -88,9 +96,8 @@ describe("DecisioningEngine:createContextProvider", () => { ); }); it("returns windows context", async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); - contextProvider = createContextProvider({ eventRegistry, window }); + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -102,9 +109,8 @@ describe("DecisioningEngine:createContextProvider", () => { ); }); it("includes provided context passed in", async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); - contextProvider = createContextProvider({ eventRegistry, window }); + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext({ cool: "beans" })).toEqual( jasmine.objectContaining({ @@ -120,11 +126,13 @@ describe("DecisioningEngine:createContextProvider", () => { // timestamp: new Date().getTime() // } // }; - // eventRegistry = await eventRegistry.getEvents("display", "abc"); - // console.log("eventRegistry is ", eventRegistry); - // contextProvider = createContextProvider({ eventRegistry, window }); + // const eventRegistry = createEventRegistry({ indexedDB }); + // const contextProvider = createContextProvider({ eventRegistry, window }); + // // TODO: Oct 4: Do you really need await eventRegistry.getEvents("display", "abc");. You are not using the results. + // // eventRegistry = await eventRegistry.getEvents("display", "abc"); + // // console.log("eventRegistry is ", eventRegistry); // - // expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( + // expect(contextProvider.getContext({ cool: "beans" })).toEqual( // events // ); // }); diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index a26a5aed6..8eeb52415 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -11,14 +11,16 @@ governing permissions and limitations under the License. */ import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:createDecisionProvider", () => { let decisionProvider; - let eventRegistry; + let indexedDB; - beforeEach(async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); + beforeAll(async () => { + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + const eventRegistry = createEventRegistry({ indexedDB }); decisionProvider = createDecisionProvider({ eventRegistry }); decisionProvider.addPayloads([ @@ -218,6 +220,12 @@ describe("DecisioningEngine:createDecisionProvider", () => { } ]); }); + + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + it("returns a single payload with items that qualify", async () => { const expectedResult = await decisionProvider.evaluate({ color: "blue", diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js index b8bea9e5b..25113288f 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js @@ -12,17 +12,25 @@ governing permissions and limitations under the License. import createEvaluableRulesetPayload from "../../../../../src/components/DecisioningEngine/createEvaluableRulesetPayload"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:createEvaluableRulesetPayload", () => { let eventRegistry; let decisionHistory; + let indexedDB; - beforeEach(async () => { - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); + beforeAll(async () => { + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + eventRegistry = createEventRegistry({ indexedDB }); decisionHistory = createDecisionHistory({ eventRegistry }); }); + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + it("consumes ruleset-items", async () => { const evaluableRulesetPayload = createEvaluableRulesetPayload( { diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index c28d1c13b..ca8ddc3d6 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js @@ -14,6 +14,7 @@ import createContextProvider from "../../../../../src/components/DecisioningEngi import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:evaluateRulesetsCommand", () => { let onDecision; @@ -22,12 +23,14 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { let contextProvider; let decisionProvider; let evaluateRulesetsCommand; + let indexedDB; beforeEach(async () => { + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); onDecision = jasmine.createSpy(); applyResponse = createApplyResponse({ onDecision }); - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); + eventRegistry = createEventRegistry({ indexedDB }); contextProvider = createContextProvider({ eventRegistry, window }); decisionProvider = createDecisionProvider({ eventRegistry }); @@ -112,6 +115,11 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { }); }); + afterEach(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + it("onDecisions receives renderDecisions=true", async () => { const result = await evaluateRulesetsCommand.run({ renderDecisions: true, diff --git a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js index b9a2d94b7..f984d7e2f 100644 --- a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js @@ -10,20 +10,25 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:createEventRegistry", () => { - const eventRegistry = createEventRegistry(); + let eventRegistry; let mockedTimestamp; + let indexedDB; + beforeAll(async () => { - await eventRegistry.setupIndexedDB(); + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + eventRegistry = createEventRegistry({ indexedDB }); mockedTimestamp = new Date("2023-05-24T08:00:00Z"); jasmine.clock().install(); jasmine.clock().mockDate(mockedTimestamp); }); - afterAll(() => { - eventRegistry.clearIndexedDB(); - eventRegistry.getIndexDB().close(); + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); jasmine.clock().uninstall(); }); diff --git a/test/unit/specs/components/DecisioningEngine/createIndexedDB.spec.js b/test/unit/specs/components/DecisioningEngine/createIndexedDB.spec.js new file mode 100644 index 000000000..a8269a1dd --- /dev/null +++ b/test/unit/specs/components/DecisioningEngine/createIndexedDB.spec.js @@ -0,0 +1,40 @@ +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; + +describe("DecisioningEngine:createIndexedDB", () => { + let indexedDB; + + beforeAll(async () => { + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + }); + + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + + it("should add an event to the database", async () => { + const eventType = "display"; + const eventId = "xyz123"; + const action = "click"; + + const result = await indexedDB.addRecord({}, eventType, eventId, action); + expect(result).toBeTruthy(); + }); + + it("should get events from the database if that exist", async () => { + const eventType = "display"; + const eventId = "xyz123"; + + const events = await indexedDB.getRecords(eventType, eventId); + expect(Array.isArray(events)).toBe(true); + }); + + it("should return empty if the query is not found", async () => { + const eventType = "someMagicalEvent"; + const eventId = "someFutureId"; + + const events = await indexedDB.getRecords(eventType, eventId); + expect(events.length).toBe(0); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js index ff7b4098f..06cb1c01e 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -13,24 +13,31 @@ import createOnResponseHandler from "../../../../../src/components/DecisioningEn import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; import createApplyResponse from "../../../../../src/components/DecisioningEngine/createApplyResponse"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; describe("DecisioningEngine:createOnResponseHandler", () => { let lifecycle; - let eventRegistry; let decisionProvider; let applyResponse; + let indexedDB; - beforeEach(async () => { + beforeAll(async () => { lifecycle = jasmine.createSpyObj("lifecycle", { onDecision: Promise.resolve() }); - eventRegistry = createEventRegistry(); - await eventRegistry.setupIndexedDB(); + indexedDB = createIndexedDB(); + await indexedDB.setupIndexedDB(); + const eventRegistry = createEventRegistry({ indexedDB }); decisionProvider = createDecisionProvider({ eventRegistry }); applyResponse = createApplyResponse(lifecycle); }); + afterAll(async () => { + await indexedDB.clearIndexedDB(); + indexedDB.getIndexDB().close(); + }); + it("calls lifecycle.onDecision with propositions based on decisionContext", async () => { const event = { getViewName: () => undefined, diff --git a/test/unit/specs/components/DecisioningEngine/index.spec.js b/test/unit/specs/components/DecisioningEngine/index.spec.js index d56224cd2..fd95059d4 100644 --- a/test/unit/specs/components/DecisioningEngine/index.spec.js +++ b/test/unit/specs/components/DecisioningEngine/index.spec.js @@ -1,36 +1,46 @@ -// /* -// 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. -// */ +/* +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 createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; -// import { injectStorage } from "../../../../../src/utils"; // import { // mockRulesetResponseWithCondition, // proposition // } from "./contextTestUtils"; -// +// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +// import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; + // describe("createDecisioningEngine:commands:evaluateRulesets", () => { // let mergeData; // let mockEvent; // let onResponseHandler; // let decisioningEngine; -// beforeEach(() => { +// let eventRegistry; +// let indexedDB; +// +// beforeAll(async () => { +// indexedDB = createIndexedDB(); +// await indexedDB.setupIndexedDB(); +// eventRegistry = createEventRegistry({ indexedDB }); +// decisioningEngine = createDecisioningEngine({}); +// }); +// +// afterEach(async () => { +// await indexedDB.clearIndexedDB(); +// }); +// +// beforeEach(async () => { // mergeData = jasmine.createSpy(); -// const config = { orgId: "exampleOrgId" }; // window.referrer = // "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; -// const createNamespacedStorage = injectStorage(window); -// decisioningEngine = createDecisioningEngine({ -// config, -// createNamespacedStorage -// }); +// // mockEvent = { // getContent: () => ({}), // getViewName: () => undefined, From 82974d51692d82a8136cf0813b6288ddef80d99d Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 11:30:44 -0700 Subject: [PATCH 19/27] clean --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d1649bea..b26f5676e 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "devDependencies": { "@adobe/alloy": "^2.18.0", "@babel/cli": "^7.12.8", - "@babel/core": "^7.23.0", + "@babel/core": "^7.2.2", "@babel/plugin-proposal-object-rest-spread": "^7.3.2", "@babel/plugin-transform-runtime": "^7.16.4", "@babel/plugin-transform-template-literals": "^7.4.4", From 697cd95e227683a52925e9b817057e7052a75041 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 11:34:34 -0700 Subject: [PATCH 20/27] clean --- .../components/MessageFeedDemo/MessageFeed.js | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/sandbox/src/components/MessageFeedDemo/MessageFeed.js b/sandbox/src/components/MessageFeedDemo/MessageFeed.js index 464eb24a0..3dcb557be 100644 --- a/sandbox/src/components/MessageFeedDemo/MessageFeed.js +++ b/sandbox/src/components/MessageFeedDemo/MessageFeed.js @@ -453,29 +453,6 @@ export default function MessageFeed() { } }); }; - // let db; - // const dbName = "historicalDataStore"; - // const request = indexedDB.open(dbName); - // request.onsuccess = event => { - // db = event.target.result; - // resolve(true); - // } - // const resetPersistentData = () => { - // return new Promise((resolve, reject) => { - // try { - // const transaction = db.transaction("events", "readwrite"); - // const objectStore = transaction.objectStore("events"); - // const request = objectStore.delete(); - // - // request.onsuccess = () => { - // resolve(true); - // }; - // } catch (error) { - // reject(error); - // } - // }); - // }; - return (
@@ -486,9 +463,6 @@ export default function MessageFeed() { -

Message Feed

From ed2f0867332ca52194c2f819f28a70b6af333352 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 11:36:59 -0700 Subject: [PATCH 21/27] clean --- sandbox/src/components/MessageFeedDemo/MessageFeed.js | 1 - 1 file changed, 1 deletion(-) diff --git a/sandbox/src/components/MessageFeedDemo/MessageFeed.js b/sandbox/src/components/MessageFeedDemo/MessageFeed.js index 3dcb557be..a4d9db396 100644 --- a/sandbox/src/components/MessageFeedDemo/MessageFeed.js +++ b/sandbox/src/components/MessageFeedDemo/MessageFeed.js @@ -424,7 +424,6 @@ export default function MessageFeed() { surface: "web://target.jasonwaters.dev/aep.html", callback: ({ items = [], rendered, clicked }) => { setClickHandler(() => clicked); - console.log("subscribeMessageFeed hahah", items); setMessageFeedItems(items); rendered(items); } From e325e3dfb2c0d1726c422e58205174936ce34aaf Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 13:05:05 -0700 Subject: [PATCH 22/27] Reverting back to original sandbox code for In-app as the latest one was resulting in different payloadId on each execute call --- .../InAppMessagesDemo/InAppMessages.js | 89 +++++++++---------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js index d0fc22f33..9ead22b1a 100644 --- a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js +++ b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js @@ -1,5 +1,5 @@ /* eslint-disable no-bitwise, no-console */ -import React from "react"; +import React, { useEffect, useState } from "react"; import ContentSecurityPolicy from "../ContentSecurityPolicy"; import "./InAppMessagesStyle.css"; @@ -40,56 +40,51 @@ const uuidv4 = () => { ); }; -const getInAppPayload = async payload => { - const res = await fetch( - `https://edge.adobedc.net/ee/or2/v1/interact?configId=${datastreamId}&requestId=${uuidv4()}`, - { - method: "POST", - body: JSON.stringify(payload) - } - ); - return res.json(); -}; - -const fetchMobilePayload = () => - getInAppPayload({ - events: [ +export default function InAppMessages() { + const [response, setResponse] = useState(null); + const getInAppPayload = async payload => { + const res = await fetch( + `https://edge.adobedc.net/ee/or2/v1/interact?configId=${datastreamId}&requestId=${uuidv4()}`, { - query: { - personalization: { - surfaces: [surface] - } - }, - xdm: { - timestamp: new Date().toISOString(), - implementationDetails: { - name: "https://ns.adobe.com/experience/mobilesdk/ios", - version: "3.7.4+1.5.0", - environment: "app" - } - } + method: "POST", + body: JSON.stringify(payload) } - ] - }); + ); + return res.json(); + }; -export default function InAppMessages() { - const renderDecisions = () => { - window - .alloy("subscribeRulesetItems", { - surfaces: [surface], - callback: result => { - console.log("subscribeRulesetItems", result); - } - }) - .then(fetchMobilePayload) - .then(response => { - console.log("getInAppPayload Yes papa yes papa --->>", response); - window.alloy("applyResponse", { - renderDecisions: true, - decisionContext, - responseBody: response - }); + useEffect(() => { + const fetchInAppPayload = async () => { + const res = await getInAppPayload({ + events: [ + { + query: { + personalization: { + surfaces: [surface] + } + }, + xdm: { + timestamp: new Date().toISOString(), + implementationDetails: { + name: "https://ns.adobe.com/experience/mobilesdk/ios", + version: "3.7.4+1.5.0", + environment: "app" + } + } + } + ] }); + setResponse(res); + }; + fetchInAppPayload(); + }, []); + + const renderDecisions = () => { + window.alloy("applyResponse", { + renderDecisions: true, + decisionContext, + responseBody: response + }); }; return ( From 7e4898a8bc03f5a8dd26dca2ec8f73d9d2613d34 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 5 Oct 2023 13:32:54 -0700 Subject: [PATCH 23/27] test fix --- .../createContextProvider.spec.js | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index 812676d6b..249a68bd1 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -119,21 +119,11 @@ describe("DecisioningEngine:createContextProvider", () => { ); }); - // it("includes events context", async () => { - // const events = { - // abc: { - // event: { "iam.id": "abc", "iam.eventType": "display" }, - // timestamp: new Date().getTime() - // } - // }; - // const eventRegistry = createEventRegistry({ indexedDB }); - // const contextProvider = createContextProvider({ eventRegistry, window }); - // // TODO: Oct 4: Do you really need await eventRegistry.getEvents("display", "abc");. You are not using the results. - // // eventRegistry = await eventRegistry.getEvents("display", "abc"); - // // console.log("eventRegistry is ", eventRegistry); - // - // expect(contextProvider.getContext({ cool: "beans" })).toEqual( - // events - // ); - // }); + it("includes events context in the form for DB instance", async () => { + const eventRegistry = createEventRegistry({ indexedDB }); + const contextProvider = createContextProvider({ eventRegistry, window }); + expect(contextProvider.getContext({ cool: "beans" })).toEqual( + jasmine.objectContaining({ events: jasmine.any(IDBDatabase) }) + ); + }); }); From af85cd4de1dbdc31b792e0456b3de5c2925f01a2 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 9 Oct 2023 08:17:41 -0700 Subject: [PATCH 24/27] test fix & some clean up --- .../createDecisionProvider.js | 1 - .../DecisioningEngine/createIndexedDB.js | 68 ++-- src/components/DecisioningEngine/index.js | 4 +- .../DecisioningEngine/index.spec.js | 322 +++++++++--------- 4 files changed, 195 insertions(+), 200 deletions(-) diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 0384d9d86..934bd6579 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -48,7 +48,6 @@ export default ({ eventRegistry }) => { }; return { - // TODO: remove addPayload below if unsed from outside of this file. addPayload, addPayloads, evaluate diff --git a/src/components/DecisioningEngine/createIndexedDB.js b/src/components/DecisioningEngine/createIndexedDB.js index 149adb3de..53a487a37 100644 --- a/src/components/DecisioningEngine/createIndexedDB.js +++ b/src/components/DecisioningEngine/createIndexedDB.js @@ -15,6 +15,7 @@ const dbName = HISTORICAL_DATA_STORE; export default () => { let db; + const DB_INITIALIZATION_TIMEOUT = 200; const setupIndexedDB = () => { return new Promise((resolve, reject) => { @@ -50,48 +51,57 @@ export default () => { }); }; + const waitForDBInitialization = fn => { + // Wait for db to be ready. + if (db) { + fn(); + } else { + setTimeout(() => { + waitForDBInitialization(fn); + }, DB_INITIALIZATION_TIMEOUT); + } + }; + const addRecord = record => { return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readwrite"); - const objectStore = transaction.objectStore("events"); - const objectStoreRequest = objectStore.add(record); + waitForDBInitialization(() => { + const transaction = db.transaction("events", "readwrite"); + const objectStore = transaction.objectStore("events"); + const objectStoreRequest = objectStore.add(record); - objectStoreRequest.onerror = txEvent => { - const dbRequest = txEvent.target; - reject(dbRequest.error); - }; + objectStoreRequest.onerror = txEvent => { + const dbRequest = txEvent.target; + reject(dbRequest.error); + }; - objectStoreRequest.onsuccess = () => { - resolve(true); - }; + objectStoreRequest.onsuccess = () => { + resolve(true); + }; + }); }); }; const getRecords = (eventType, eventId) => { return new Promise((resolve, reject) => { - const transaction = db.transaction("events", "readonly"); - const objectStore = transaction.objectStore("events"); - const index = objectStore.index("iam_id_iam_eventType_index"); - const request = index.getAll([eventId, eventType]); - - request.onsuccess = eventObjStore => { - const dbRequest = eventObjStore.target; - resolve(dbRequest ? dbRequest.result : []); - }; + waitForDBInitialization(() => { + const transaction = db.transaction("events", "readonly"); + const objectStore = transaction.objectStore("events"); + const index = objectStore.index("iam_id_iam_eventType_index"); + const request = index.getAll([eventId, eventType]); - request.onerror = eventObjStore => { - const dbRequest = eventObjStore.target; - reject(dbRequest.error); - }; + request.onsuccess = eventObjStore => { + const dbRequest = eventObjStore.target; + resolve(dbRequest ? dbRequest.result : []); + }; + + request.onerror = eventObjStore => { + const dbRequest = eventObjStore.target; + reject(dbRequest.error); + }; + }); }); }; - // setupIndexedDB() - // .then(() => {}) - // .catch(error => { - // console.error("error message: ", error.message); - // }); - const clearIndexedDB = () => { return new Promise((resolve, reject) => { try { diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index b130da930..f5c50e20d 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -28,7 +28,9 @@ import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; const createDecisioningEngine = () => { const indexedDB = createIndexedDB(); - indexedDB.setupIndexedDB(); + indexedDB + .setupIndexedDB() + .then(() => console.log("IndexedDB setup is complete.")); const eventRegistry = createEventRegistry({ indexedDB }); let applyResponse; diff --git a/test/unit/specs/components/DecisioningEngine/index.spec.js b/test/unit/specs/components/DecisioningEngine/index.spec.js index fd95059d4..dd5f0b014 100644 --- a/test/unit/specs/components/DecisioningEngine/index.spec.js +++ b/test/unit/specs/components/DecisioningEngine/index.spec.js @@ -9,173 +9,157 @@ 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 createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; -// import { -// mockRulesetResponseWithCondition, -// proposition -// } from "./contextTestUtils"; -// import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -// import createIndexedDB from "../../../../../src/components/DecisioningEngine/createIndexedDB"; +import createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; +import { + mockRulesetResponseWithCondition, + proposition +} from "./contextTestUtils"; -// describe("createDecisioningEngine:commands:evaluateRulesets", () => { -// let mergeData; -// let mockEvent; -// let onResponseHandler; -// let decisioningEngine; -// let eventRegistry; -// let indexedDB; -// -// beforeAll(async () => { -// indexedDB = createIndexedDB(); -// await indexedDB.setupIndexedDB(); -// eventRegistry = createEventRegistry({ indexedDB }); -// decisioningEngine = createDecisioningEngine({}); -// }); -// -// afterEach(async () => { -// await indexedDB.clearIndexedDB(); -// }); -// -// beforeEach(async () => { -// mergeData = jasmine.createSpy(); -// window.referrer = -// "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; -// -// mockEvent = { -// getContent: () => ({}), -// getViewName: () => undefined, -// mergeData -// }; -// decisioningEngine.lifecycle.onComponentsRegistered(() => {}); -// }); -// -// it("should run the evaluateRulesets command and satisfy the rule based on global context", () => { -// onResponseHandler = onResponse => { -// onResponse({ -// response: mockRulesetResponseWithCondition({ -// definition: { -// key: "referringPage.path", -// matcher: "eq", -// values: ["/search"] -// }, -// type: "matcher" -// }) -// }); -// }; -// decisioningEngine.lifecycle.onBeforeEvent({ -// event: mockEvent, -// renderDecisions: true, -// decisionContext: {}, -// onResponse: onResponseHandler -// }); -// const result = decisioningEngine.commands.evaluateRulesets.run({}); -// expect(result).toEqual({ -// propositions: [proposition] -// }); -// }); -// -// it("should run the evaluateRulesets command and does not satisfy rule due to unmatched global context", () => { -// onResponseHandler = onResponse => { -// onResponse({ -// response: mockRulesetResponseWithCondition({ -// definition: { -// key: "referringPage.path", -// matcher: "eq", -// values: ["/about"] -// }, -// type: "matcher" -// }) -// }); -// }; -// decisioningEngine.lifecycle.onBeforeEvent({ -// event: mockEvent, -// renderDecisions: true, -// decisionContext: {}, -// onResponse: onResponseHandler -// }); -// const result = decisioningEngine.commands.evaluateRulesets.run({}); -// expect(result).toEqual({ -// propositions: [] -// }); -// }); -// -// it("should run the evaluateRulesets command and return propositions with renderDecisions true", () => { -// onResponseHandler = onResponse => { -// onResponse({ -// response: mockRulesetResponseWithCondition({ -// definition: { -// key: "referringPage.path", -// matcher: "eq", -// values: ["/search"] -// }, -// type: "matcher" -// }) -// }); -// }; -// decisioningEngine.lifecycle.onBeforeEvent({ -// event: mockEvent, -// renderDecisions: true, -// decisionContext: {}, -// onResponse: onResponseHandler -// }); -// const result = decisioningEngine.commands.evaluateRulesets.run({}); -// expect(result).toEqual({ -// propositions: [proposition] -// }); -// }); -// -// it("should run the evaluateRulesets command returns propositions with renderDecisions false", () => { -// onResponseHandler = onResponse => { -// onResponse({ -// response: mockRulesetResponseWithCondition({ -// definition: { -// key: "referringPage.path", -// matcher: "eq", -// values: ["/search"] -// }, -// type: "matcher" -// }) -// }); -// }; -// decisioningEngine.lifecycle.onBeforeEvent({ -// event: mockEvent, -// renderDecisions: false, -// decisionContext: {}, -// onResponse: onResponseHandler -// }); -// const result = decisioningEngine.commands.evaluateRulesets.run({}); -// expect(result).toEqual({ -// propositions: [proposition] -// }); -// }); -// -// it("ensures schema-based ruleset consequences", () => { -// onResponseHandler = onResponse => { -// onResponse({ -// response: mockRulesetResponseWithCondition({ -// definition: { -// key: "referringPage.path", -// matcher: "eq", -// values: ["/search"] -// }, -// type: "matcher" -// }) -// }); -// }; -// -// decisioningEngine.lifecycle.onBeforeEvent({ -// event: mockEvent, -// renderDecisions: false, -// decisionContext: {}, -// onResponse: onResponseHandler -// }); -// -// expect(mergeData).toHaveBeenCalledOnceWith({ -// __adobe: { -// ajo: { -// "in-app-response-format": 2 -// } -// } -// }); -// }); -// }); +describe("createDecisioningEngine:commands:evaluateRulesets", () => { + let mergeData; + let mockEvent; + let decisioningEngine; + + beforeEach(() => { + mergeData = jasmine.createSpy(); + window.referrer = + "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; + decisioningEngine = createDecisioningEngine({}); + mockEvent = { + getContent: () => ({}), + getViewName: () => undefined, + mergeData + }; + decisioningEngine.lifecycle.onComponentsRegistered(() => {}); + }); + + it("should run the evaluateRulesets command and satisfy the rule based on global context", async () => { + const onResponseHandler = onResponse => { + onResponse({ + response: mockRulesetResponseWithCondition({ + definition: { + key: "referringPage.path", + matcher: "eq", + values: ["/search"] + }, + type: "matcher" + }) + }); + }; + decisioningEngine.lifecycle.onBeforeEvent({ + event: mockEvent, + renderDecisions: true, + decisionContext: {}, + onResponse: onResponseHandler + }); + const result = await decisioningEngine.commands.evaluateRulesets.run({}); + expect(result).toEqual({ + propositions: [proposition] + }); + }); + + it("should run the evaluateRulesets command and does not satisfy rule due to unmatched global context", async () => { + const onResponseHandler = onResponse => { + onResponse({ + response: mockRulesetResponseWithCondition({ + definition: { + key: "referringPage.path", + matcher: "eq", + values: ["/about"] + }, + type: "matcher" + }) + }); + }; + decisioningEngine.lifecycle.onBeforeEvent({ + event: mockEvent, + renderDecisions: true, + decisionContext: {}, + onResponse: onResponseHandler + }); + const result = await decisioningEngine.commands.evaluateRulesets.run({}); + expect(result).toEqual({ + propositions: [] + }); + }); + + it("should run the evaluateRulesets command and return propositions with renderDecisions true", async () => { + const onResponseHandler = onResponse => { + onResponse({ + response: mockRulesetResponseWithCondition({ + definition: { + key: "referringPage.path", + matcher: "eq", + values: ["/search"] + }, + type: "matcher" + }) + }); + }; + decisioningEngine.lifecycle.onBeforeEvent({ + event: mockEvent, + renderDecisions: true, + decisionContext: {}, + onResponse: onResponseHandler + }); + const result = await decisioningEngine.commands.evaluateRulesets.run({}); + expect(result).toEqual({ + propositions: [proposition] + }); + }); + + it("should run the evaluateRulesets command returns propositions with renderDecisions false", async () => { + const onResponseHandler = onResponse => { + onResponse({ + response: mockRulesetResponseWithCondition({ + definition: { + key: "referringPage.path", + matcher: "eq", + values: ["/search"] + }, + type: "matcher" + }) + }); + }; + decisioningEngine.lifecycle.onBeforeEvent({ + event: mockEvent, + renderDecisions: false, + decisionContext: {}, + onResponse: onResponseHandler + }); + const result = await decisioningEngine.commands.evaluateRulesets.run({}); + expect(result).toEqual({ + propositions: [proposition] + }); + }); + + it("ensures schema-based ruleset consequences", () => { + const onResponseHandler = onResponse => { + onResponse({ + response: mockRulesetResponseWithCondition({ + definition: { + key: "referringPage.path", + matcher: "eq", + values: ["/search"] + }, + type: "matcher" + }) + }); + }; + + decisioningEngine.lifecycle.onBeforeEvent({ + event: mockEvent, + renderDecisions: false, + decisionContext: {}, + onResponse: onResponseHandler + }); + + expect(mergeData).toHaveBeenCalledOnceWith({ + __adobe: { + ajo: { + "in-app-response-format": 2 + } + } + }); + }); +}); From f7e6e1421aab53771f00fe77e4630b9a26d54622 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 9 Oct 2023 22:53:36 -0700 Subject: [PATCH 25/27] IAM - Sandbox in sync with feature branch --- .../InAppMessagesDemo/InAppMessages.js | 88 ++++++++++--------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js index 9ead22b1a..e49687823 100644 --- a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js +++ b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js @@ -1,5 +1,5 @@ /* eslint-disable no-bitwise, no-console */ -import React, { useEffect, useState } from "react"; +import React from "react"; import ContentSecurityPolicy from "../ContentSecurityPolicy"; import "./InAppMessagesStyle.css"; @@ -40,51 +40,55 @@ const uuidv4 = () => { ); }; -export default function InAppMessages() { - const [response, setResponse] = useState(null); - const getInAppPayload = async payload => { - const res = await fetch( - `https://edge.adobedc.net/ee/or2/v1/interact?configId=${datastreamId}&requestId=${uuidv4()}`, - { - method: "POST", - body: JSON.stringify(payload) - } - ); - return res.json(); - }; +const getInAppPayload = async payload => { + const res = await fetch( + `https://edge.adobedc.net/ee/or2/v1/interact?configId=${datastreamId}&requestId=${uuidv4()}`, + { + method: "POST", + body: JSON.stringify(payload) + } + ); + return res.json(); +}; - useEffect(() => { - const fetchInAppPayload = async () => { - const res = await getInAppPayload({ - events: [ - { - query: { - personalization: { - surfaces: [surface] - } - }, - xdm: { - timestamp: new Date().toISOString(), - implementationDetails: { - name: "https://ns.adobe.com/experience/mobilesdk/ios", - version: "3.7.4+1.5.0", - environment: "app" - } - } +const fetchMobilePayload = () => + getInAppPayload({ + events: [ + { + query: { + personalization: { + surfaces: [surface] } - ] - }); - setResponse(res); - }; - fetchInAppPayload(); - }, []); + }, + xdm: { + timestamp: new Date().toISOString(), + implementationDetails: { + name: "https://ns.adobe.com/experience/mobilesdk/ios", + version: "3.7.4+1.5.0", + environment: "app" + } + } + } + ] + }); +export default function InAppMessages() { const renderDecisions = () => { - window.alloy("applyResponse", { - renderDecisions: true, - decisionContext, - responseBody: response - }); + window + .alloy("subscribeRulesetItems", { + surfaces: [surface], + callback: result => { + console.log("subscribeRulesetItems", result); + } + }) + .then(fetchMobilePayload) + .then(response => { + window.alloy("applyResponse", { + renderDecisions: true, + decisionContext, + responseBody: response + }); + }); }; return ( From 8145d9e0e504a87215d4b8e485095664bf081954 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 9 Oct 2023 22:54:45 -0700 Subject: [PATCH 26/27] use activityID to save the ruleset&conditions --- .../createDecisionProvider.js | 12 +- .../createDecisionProvider.spec.js | 24 ++-- .../DecisioningEngine/utils.spec.js | 114 ++++++++++++++++++ 3 files changed, 134 insertions(+), 16 deletions(-) diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 934bd6579..8103f5e0c 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -11,14 +11,16 @@ governing permissions and limitations under the License. */ import createEvaluableRulesetPayload from "./createEvaluableRulesetPayload"; import createDecisionHistory from "./createDecisionHistory"; +import { getActivityId } from "./utils"; export default ({ eventRegistry }) => { - const payloads = {}; + const payloadsByActivityId = {}; const decisionHistory = createDecisionHistory({ eventRegistry }); const addPayload = payload => { - if (!payload.id) { + const activityId = getActivityId(payload); + if (!activityId) { return; } @@ -29,14 +31,16 @@ export default ({ eventRegistry }) => { ); if (evaluableRulesetPayload.isEvaluable) { - payloads[payload.id] = evaluableRulesetPayload; + payloadsByActivityId[activityId] = evaluableRulesetPayload; } }; const evaluate = (context = {}) => { return new Promise(resolve => { Promise.all( - Object.values(payloads).map(payload => payload.evaluate(context)) + Object.values(payloadsByActivityId).map(payload => + payload.evaluate(context) + ) ).then(consequences => { resolve(consequences.filter(payload => payload.items.length > 0)); }); diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index 8eeb52415..1770ff457 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -25,6 +25,8 @@ describe("DecisioningEngine:createDecisionProvider", () => { decisionProvider = createDecisionProvider({ eventRegistry }); decisionProvider.addPayloads([ { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scope: "web://mywebsite.com", scopeDetails: { decisionProvider: "AJO", characteristics: { @@ -42,7 +44,6 @@ describe("DecisioningEngine:createDecisionProvider", () => { }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", items: [ { id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", @@ -125,10 +126,11 @@ describe("DecisioningEngine:createDecisionProvider", () => { ] } } - ], - scope: "web://mywebsite.com" + ] }, { + id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", + scope: "web://mywebsite.com", scopeDetails: { decisionProvider: "AJO", characteristics: { @@ -142,11 +144,10 @@ describe("DecisioningEngine:createDecisionProvider", () => { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "48ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d168" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, - id: "3d5d69cd-acde-4eca-b43b-a54574b67bb0", items: [ { id: "5229f502-38d6-40c3-9a3a-b5b1a6adc441", @@ -215,8 +216,7 @@ describe("DecisioningEngine:createDecisionProvider", () => { ] } } - ], - scope: "web://mywebsite.com" + ] } ]); }); @@ -233,6 +233,8 @@ describe("DecisioningEngine:createDecisionProvider", () => { }); expect(expectedResult).toEqual([ { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scope: "web://mywebsite.com", scopeDetails: { decisionProvider: "AJO", characteristics: { @@ -250,7 +252,6 @@ describe("DecisioningEngine:createDecisionProvider", () => { }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, - id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", items: [ { schema: "https://ns.adobe.com/personalization/dom-action", @@ -280,8 +281,7 @@ describe("DecisioningEngine:createDecisionProvider", () => { }, id: "10da709c-aa1a-40e5-84dd-966e2e8a1d5f" } - ], - scope: "web://mywebsite.com" + ] } ]); }); @@ -304,7 +304,7 @@ describe("DecisioningEngine:createDecisionProvider", () => { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "48ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d168" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, @@ -411,7 +411,7 @@ describe("DecisioningEngine:createDecisionProvider", () => { ], activity: { id: - "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + "48ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d168" }, correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" }, diff --git a/test/unit/specs/components/DecisioningEngine/utils.spec.js b/test/unit/specs/components/DecisioningEngine/utils.spec.js index 7da1d1dd0..b59d2f6f1 100644 --- a/test/unit/specs/components/DecisioningEngine/utils.spec.js +++ b/test/unit/specs/components/DecisioningEngine/utils.spec.js @@ -12,6 +12,7 @@ governing permissions and limitations under the License. import { createRestoreStorage, createSaveStorage, + getActivityId, getExpirationDate } from "../../../../../src/components/DecisioningEngine/utils"; @@ -78,4 +79,117 @@ describe("DecisioningEngine:utils", () => { expect(result).toEqual(expectedDate); jasmine.clock().uninstall(); }); + + it("should return the activityId", () => { + const proposition = { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scope: "web://mywebsite.com", + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + activity: { + id: + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + }, + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + }, + items: [ + { + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe", + schema: "https://ns.adobe.com/personalization/ruleset-item", + data: { + version: 1, + rules: [ + { + condition: { + definition: { + conditions: [ + { + definition: { + conditions: [ + { + definition: { + key: "color", + matcher: "eq", + values: ["orange", "blue"] + }, + type: "matcher" + }, + { + definition: { + key: "action", + matcher: "eq", + values: ["lipstick"] + }, + type: "matcher" + } + ], + logic: "and" + }, + type: "group" + } + ], + logic: "and" + }, + type: "group" + }, + consequences: [ + { + type: "schema", + detail: { + schema: "https://ns.adobe.com/personalization/dom-action", + data: { + selector: + "HTML > BODY > DIV.offer:eq(0) > IMG:nth-of-type(1)", + type: "setAttribute", + content: { + src: "img/demo-marketing-offer1-exp-A.png" + }, + prehidingSelector: + "HTML > BODY > DIV:nth-of-type(2) > IMG:nth-of-type(1)" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + }, + id: "79129ecf-6430-4fbd-955a-b4f1dfdaa6fe" + } + ] + } + ] + } + } + ] + }; + expect(getActivityId(proposition)).toEqual( + "39ae8d4b-b55e-43dc-a143-77f50195b487#b47fde8b-57c1-4bbe-ae22-64d5b782d183" + ); + }); + + it("should return the activityId as undefined", () => { + const proposition = { + id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", + scope: "web://mywebsite.com", + scopeDetails: { + decisionProvider: "AJO", + characteristics: { + eventToken: "abc" + }, + strategies: [ + { + strategyID: "3VQe3oIqiYq2RAsYzmDTSf", + treatmentID: "yu7rkogezumca7i0i44v" + } + ], + correlationID: "02c77ea8-7c0e-4d33-8090-4a5bfd3d7503" + } + }; + expect(getActivityId(proposition)).toEqual(undefined); + }); }); From 7711eb44b78352a0e844ea20d59d5ceeafe207c3 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 9 Oct 2023 23:30:28 -0700 Subject: [PATCH 27/27] fixed test --- .../createEventRegistry.spec.js | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js index f984d7e2f..184d73f61 100644 --- a/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEventRegistry.spec.js @@ -16,6 +16,7 @@ describe("DecisioningEngine:createEventRegistry", () => { let eventRegistry; let mockedTimestamp; let indexedDB; + let addEventResult; beforeAll(async () => { indexedDB = createIndexedDB(); @@ -27,18 +28,28 @@ describe("DecisioningEngine:createEventRegistry", () => { }); afterAll(async () => { - await indexedDB.clearIndexedDB(); indexedDB.getIndexDB().close(); jasmine.clock().uninstall(); }); - it("should add an event to the database", async () => { + beforeEach(async () => { const eventType = "trigger"; const eventId = "abc123"; const action = "click"; + addEventResult = await eventRegistry.addEvent( + {}, + eventType, + eventId, + action + ); + }); + + afterEach(async () => { + await indexedDB.clearIndexedDB(); + }); - const result = await eventRegistry.addEvent({}, eventType, eventId, action); - expect(result).toBeTruthy(); + it("should add an event to the database", async () => { + expect(addEventResult).toBe(true); }); it("should get events from the database if that exist", async () => { @@ -47,6 +58,7 @@ describe("DecisioningEngine:createEventRegistry", () => { const events = await eventRegistry.getEvents(eventType, eventId); expect(Array.isArray(events)).toBe(true); + expect(events.length).toBe(1); }); it("should return empty if the query is not found", async () => { @@ -56,17 +68,17 @@ describe("DecisioningEngine:createEventRegistry", () => { const events = await eventRegistry.getEvents(eventType, eventId); expect(events.length).toBe(0); }); - // TODO: FIX the below test - // it("should get the first timestamp for events", async () => { - // const eventType = "trigger"; - // const eventId = "abc123"; - // - // const timestamp = await eventRegistry.getEventsFirstTimestamp( - // eventType, - // eventId - // ); - // expect(timestamp).toBe(mockedTimestamp.getTime()); - // }); + + it("should get the first timestamp for events", async () => { + const eventType = "trigger"; + const eventId = "abc123"; + + const timestamp = await eventRegistry.getEventsFirstTimestamp( + eventType, + eventId + ); + expect(timestamp).toBe(mockedTimestamp.getTime()); + }); it("should add experience edge event to the database", async () => { const getContent = () => ({