From 9b8ec711aaa4c862b5693fee99d9dd68f7767ddd Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Thu, 19 Oct 2023 22:30:29 -0700 Subject: [PATCH 1/9] config flag to enable storage in localStorage --- .../createNoopEventRegistry.js | 23 +++++++++++++ src/components/DecisioningEngine/index.js | 16 ++++++--- src/core/config/createCoreConfigs.js | 1 + .../createNoopEventRegistry.spec.js | 33 +++++++++++++++++++ .../DecisioningEngine/index.spec.js | 5 ++- 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/components/DecisioningEngine/createNoopEventRegistry.js create mode 100644 test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js diff --git a/src/components/DecisioningEngine/createNoopEventRegistry.js b/src/components/DecisioningEngine/createNoopEventRegistry.js new file mode 100644 index 000000000..2251683da --- /dev/null +++ b/src/components/DecisioningEngine/createNoopEventRegistry.js @@ -0,0 +1,23 @@ +/* +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. +*/ +const noop = () => { + return {}; +}; + +export default () => { + return { + addExperienceEdgeEvent: noop, + addEvent: noop, + getEvent: noop, + toJSON: noop + }; +}; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 93974750b..1ad8c675a 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -22,13 +22,19 @@ import { MOBILE_EVENT_TYPE } from "./constants"; import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; +import createNoopEventRegistery from "./createNoopEventRegistry"; const createDecisioningEngine = ({ config, createNamespacedStorage }) => { - const { orgId } = config; - const storage = createNamespacedStorage( - `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` - ); - const eventRegistry = createEventRegistry({ storage: storage.persistent }); + const { orgId, personalizationStorageEnabled } = config; + let eventRegistry; + if (personalizationStorageEnabled) { + const storage = createNamespacedStorage( + `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` + ); + eventRegistry = createEventRegistry({ storage: storage.persistent }); + } else { + eventRegistry = createNoopEventRegistery(); + } let applyResponse; const decisionProvider = createDecisionProvider({ eventRegistry }); diff --git a/src/core/config/createCoreConfigs.js b/src/core/config/createCoreConfigs.js index 224c989b6..c4703b65a 100644 --- a/src/core/config/createCoreConfigs.js +++ b/src/core/config/createCoreConfigs.js @@ -38,6 +38,7 @@ export default () => orgId: string() .unique() .required(), + personalizationStorageEnabled: boolean().default(true), onBeforeEventSend: callback().default(noop), edgeConfigOverrides: validateConfigOverride }).deprecated("edgeConfigId", string().unique(), "datastreamId"); diff --git a/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js new file mode 100644 index 000000000..3aeb6bdaf --- /dev/null +++ b/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js @@ -0,0 +1,33 @@ +import createNoopEventRegistry from "../../../../../src/components/DecisioningEngine/createNoopEventRegistry"; + +describe("createNoopEventRegistry", () => { + let instance; + + beforeEach(() => { + instance = createNoopEventRegistry(); + }); + + it("should return a valid instance", () => { + expect(instance).toBeDefined(); + }); + + it("addExperienceEdgeEvent should return an empty object", () => { + const result = instance.addExperienceEdgeEvent(); + expect(result).toEqual({}); + }); + + it("addEvent should return an empty object", () => { + const result = instance.addEvent(); + expect(result).toEqual({}); + }); + + it("getEvent should return an empty object", () => { + const result = instance.getEvent(); + expect(result).toEqual({}); + }); + + it("toJSON should return an empty object", () => { + const result = instance.toJSON(); + expect(result).toEqual({}); + }); +}); diff --git a/test/unit/specs/components/DecisioningEngine/index.spec.js b/test/unit/specs/components/DecisioningEngine/index.spec.js index c5fa73d17..cfb5adaee 100644 --- a/test/unit/specs/components/DecisioningEngine/index.spec.js +++ b/test/unit/specs/components/DecisioningEngine/index.spec.js @@ -23,7 +23,10 @@ describe("createDecisioningEngine:commands:evaluateRulesets", () => { let decisioningEngine; beforeEach(() => { mergeData = jasmine.createSpy(); - const config = { orgId: "exampleOrgId" }; + const config = { + orgId: "exampleOrgId", + personalizationStorageEnabled: true + }; window.referrer = "https://www.google.com/search?q=adobe+journey+optimizer&oq=adobe+journey+optimizer"; const createNamespacedStorage = injectStorage(window); From a15832163d79a8101d2db1636d50a6f9549673d5 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 23 Oct 2023 22:30:00 -0700 Subject: [PATCH 2/9] based on consent set event registry --- .../DecisioningEngine/createEventContext.js | 49 ++++++++++++++++++ .../createNoopEventRegistry.js | 10 ++-- src/components/DecisioningEngine/index.js | 50 ++++++++++++------- 3 files changed, 86 insertions(+), 23 deletions(-) create mode 100644 src/components/DecisioningEngine/createEventContext.js diff --git a/src/components/DecisioningEngine/createEventContext.js b/src/components/DecisioningEngine/createEventContext.js new file mode 100644 index 000000000..79d182db1 --- /dev/null +++ b/src/components/DecisioningEngine/createEventContext.js @@ -0,0 +1,49 @@ +/* +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 createNoopEventRegistry from "./createNoopEventRegistry"; + +export default () => { + let currentEventRegistry = createNoopEventRegistry(); + + const addExperienceEdgeEvent = event => { + return currentEventRegistry.addExperienceEdgeEvent(event); + }; + + const addEvent = (event, eventType, eventId, action) => { + return currentEventRegistry.addEvent(event, eventType, eventId, action); + }; + + const getEvent = (eventType, eventId) => { + return currentEventRegistry.getEvent(eventType, eventId); + }; + + const toJSON = () => { + return currentEventRegistry.toJSON(); + }; + + const clear = () => { + currentEventRegistry.clear(); + }; + + const setCurrentEventRegistry = eventRegistry => { + currentEventRegistry = eventRegistry; + }; + + return { + addExperienceEdgeEvent, + addEvent, + getEvent, + toJSON, + setCurrentEventRegistry, + clear + }; +}; diff --git a/src/components/DecisioningEngine/createNoopEventRegistry.js b/src/components/DecisioningEngine/createNoopEventRegistry.js index 2251683da..9f0f3ec78 100644 --- a/src/components/DecisioningEngine/createNoopEventRegistry.js +++ b/src/components/DecisioningEngine/createNoopEventRegistry.js @@ -9,15 +9,15 @@ 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. */ -const noop = () => { +const EMPTY_OBJECT = () => { return {}; }; export default () => { return { - addExperienceEdgeEvent: noop, - addEvent: noop, - getEvent: noop, - toJSON: noop + addExperienceEdgeEvent: EMPTY_OBJECT, + addEvent: EMPTY_OBJECT, + getEvent: EMPTY_OBJECT, + toJSON: EMPTY_OBJECT }; }; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 1ad8c675a..bacf335ca 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -22,30 +22,27 @@ import { MOBILE_EVENT_TYPE } from "./constants"; import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; -import createNoopEventRegistery from "./createNoopEventRegistry"; +import createEventContext from "./createEventContext"; +import createNoopEventRegistry from "./createNoopEventRegistry"; -const createDecisioningEngine = ({ config, createNamespacedStorage }) => { +const createDecisioningEngine = ({ + config, + createNamespacedStorage, + consent +}) => { const { orgId, personalizationStorageEnabled } = config; - let eventRegistry; - if (personalizationStorageEnabled) { - const storage = createNamespacedStorage( - `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` - ); - eventRegistry = createEventRegistry({ storage: storage.persistent }); - } else { - eventRegistry = createNoopEventRegistery(); - } - let applyResponse; - - const decisionProvider = createDecisionProvider({ eventRegistry }); - const contextProvider = createContextProvider({ eventRegistry, window }); - + const storage = createNamespacedStorage( + `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` + ); + const eventContext = createEventContext(); + const decisionProvider = createDecisionProvider({ eventContext }); + const contextProvider = createContextProvider({ eventContext, window }); const evaluateRulesetsCommand = createEvaluateRulesetsCommand({ contextProvider, decisionProvider }); - const subscribeRulesetItems = createSubscribeRulesetItems(); + let applyResponse; return { lifecycle: { @@ -54,6 +51,23 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { }, onComponentsRegistered(tools) { applyResponse = createApplyResponse(tools.lifecycle); + if (personalizationStorageEnabled) { + consent + .awaitConsent() + .then(() => { + const eventRegistry = createEventRegistry({ + storage: storage.persistent + }); + eventContext.setCurrentEventRegistry(eventRegistry); + }) + .catch(() => { + // If consent is rejected, we want to clear the local storage. + if (storage) { + storage.persistent.clear(); + } + eventContext.setCurrentEventRegistry(createNoopEventRegistry()); + }); + } }, onBeforeEvent({ event, @@ -75,7 +89,7 @@ const createDecisioningEngine = ({ config, createNamespacedStorage }) => { }) ); - eventRegistry.addExperienceEdgeEvent(event); + eventContext.addExperienceEdgeEvent(event); } }, commands: { From b42f4ab7cf80ad03ed5ae661c05a58db84a0d8ba Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 23 Oct 2023 22:30:59 -0700 Subject: [PATCH 3/9] tests --- .../createContextProvider.js | 4 +-- .../createDecisionHistory.js | 4 +-- .../createDecisionProvider.js | 6 ++--- .../createEvaluableRulesetPayload.js | 4 +-- .../DecisioningEngine/contextTestUtils.js | 8 +++--- .../createContextProvider.spec.js | 26 ++++++++++++++----- .../createDecisionHistory.spec.js | 11 +++++--- .../createDecisionProvider.spec.js | 7 +++-- .../createEvaluableRulesetPayload.spec.js | 6 ++++- .../createEvaluateRulesetsCommand.spec.js | 8 ++++-- .../createEventContext.spec.js | 0 .../createOnResponseHandler.spec.js | 7 +++-- .../DecisioningEngine/index.spec.js | 15 ++++++++--- 13 files changed, 74 insertions(+), 32 deletions(-) create mode 100644 test/unit/specs/components/DecisioningEngine/createEventContext.spec.js diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 303465a4d..4fe2aeb28 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -14,7 +14,7 @@ import parseUrl from "../../utils/parseUrl"; import flattenObject from "../../utils/flattenObject"; import libraryVersion from "../../constants/libraryVersion"; -export default ({ eventRegistry, window }) => { +export default ({ eventContext, window }) => { const pageLoadTimestamp = new Date().getTime(); const getBrowserContext = () => { return { @@ -90,7 +90,7 @@ export default ({ eventRegistry, window }) => { ...addedContext }; - return { ...flattenObject(context), events: eventRegistry.toJSON() }; + return { ...flattenObject(context), events: eventContext.toJSON() }; }; return { getContext diff --git a/src/components/DecisioningEngine/createDecisionHistory.js b/src/components/DecisioningEngine/createDecisionHistory.js index 1360c3f99..28053b8a8 100644 --- a/src/components/DecisioningEngine/createDecisionHistory.js +++ b/src/components/DecisioningEngine/createDecisionHistory.js @@ -11,12 +11,12 @@ governing permissions and limitations under the License. */ import { PropositionEventType } from "../../constants/propositionEventType"; -export default ({ eventRegistry }) => { +export default ({ eventContext }) => { const recordQualified = id => { if (!id) { return undefined; } - return eventRegistry.addEvent({}, PropositionEventType.TRIGGER, id); + return eventContext.addEvent({}, PropositionEventType.TRIGGER, id); }; return { recordQualified }; diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 77beb7245..33705b906 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -13,10 +13,10 @@ import createEvaluableRulesetPayload from "./createEvaluableRulesetPayload"; import createDecisionHistory from "./createDecisionHistory"; import { getActivityId } from "./utils"; -export default ({ eventRegistry }) => { +export default ({ eventContext }) => { const payloadsBasedOnActivityId = {}; - const decisionHistory = createDecisionHistory({ eventRegistry }); + const decisionHistory = createDecisionHistory({ eventContext }); const addPayload = payload => { const activityId = getActivityId(payload); @@ -26,7 +26,7 @@ export default ({ eventRegistry }) => { const evaluableRulesetPayload = createEvaluableRulesetPayload( payload, - eventRegistry, + eventContext, decisionHistory ); diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index d1fa20995..ea69c5ca5 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -44,7 +44,7 @@ const isRulesetItem = item => { } }; -export default (payload, eventRegistry, decisionHistory) => { +export default (payload, eventContext, decisionHistory) => { const consequenceAdapter = createConsequenceAdapter(); const activityId = getActivityId(payload); const items = []; @@ -64,7 +64,7 @@ export default (payload, eventRegistry, decisionHistory) => { }; const evaluate = context => { - const displayEvent = eventRegistry.getEvent(DISPLAY, activityId); + const displayEvent = eventContext.getEvent(DISPLAY, activityId); const displayedDate = displayEvent ? displayEvent.firstTimestamp diff --git a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js index 322d7e191..792bc6fa4 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; export const proposition = { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", @@ -124,9 +125,10 @@ export const setupResponseHandler = (applyResponse, window, condition) => { "clear" ]); const eventRegistry = createEventRegistry({ storage }); - const decisionProvider = createDecisionProvider({ eventRegistry }); - - const contextProvider = createContextProvider({ eventRegistry, window }); + const eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + const decisionProvider = createDecisionProvider({ eventContext }); + const contextProvider = createContextProvider({ eventContext, window }); const onResponseHandler = createOnResponseHandler({ renderDecisions: true, diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index 3dbd6aeca..22848fde7 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -11,6 +11,7 @@ governing permissions and limitations under the License. */ import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createContextProvider", () => { let contextProvider; @@ -18,6 +19,7 @@ describe("DecisioningEngine:createContextProvider", () => { let storage; let window; let mockedTimestamp; + let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); @@ -44,7 +46,9 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns page context", () => { eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -62,7 +66,9 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns referring page context", () => { eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -78,7 +84,9 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns browser context", () => { eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -88,7 +96,9 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns windows context", () => { eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -101,7 +111,9 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("includes provided context passed in", () => { eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext({ cool: "beans" })).toEqual( jasmine.objectContaining({ @@ -121,7 +133,9 @@ describe("DecisioningEngine:createContextProvider", () => { eventRegistry = { toJSON: () => events }; - contextProvider = createContextProvider({ eventRegistry, window }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( events diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js index ff775adb8..e1e1254a6 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js @@ -11,17 +11,20 @@ governing permissions and limitations under the License. */ import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:decisionHistory", () => { let storage; let history; + let eventRegistry; + let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - - history = createDecisionHistory({ - eventRegistry: createEventRegistry({ storage, saveDelay: 10 }) - }); + eventRegistry = createEventRegistry({ storage, saveDelay: 10 }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + history = createDecisionHistory({ eventContext }); }); it("records decision time", () => { diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index 3a4b48109..0ebecdc49 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -11,17 +11,20 @@ governing permissions and limitations under the License. */ import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; +import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createDecisionProvider", () => { let decisionProvider; let storage; let eventRegistry; + let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - - decisionProvider = createDecisionProvider({ eventRegistry }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + decisionProvider = createDecisionProvider({ eventContext }); decisionProvider.addPayloads([ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js index c24130324..2bf1d1025 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js @@ -12,16 +12,20 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createEvaluableRulesetPayload", () => { let storage; let eventRegistry; let decisionHistory; + let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - decisionHistory = createDecisionHistory({ eventRegistry }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + decisionHistory = createDecisionHistory({ eventContext }); }); it("consumes ruleset-items", () => { diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index 7c5bd3889..de778593c 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:evaluateRulesetsCommand", () => { let onDecision; @@ -23,15 +24,18 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { let contextProvider; let decisionProvider; let evaluateRulesetsCommand; + let eventContext; beforeEach(() => { onDecision = jasmine.createSpy(); applyResponse = createApplyResponse({ onDecision }); storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); + eventContext = createEventContext(); eventRegistry = createEventRegistry({ storage }); - contextProvider = createContextProvider({ eventRegistry, window }); - decisionProvider = createDecisionProvider({ eventRegistry }); + eventContext.setCurrentEventRegistry(eventRegistry); + contextProvider = createContextProvider({ eventContext, window }); + decisionProvider = createDecisionProvider({ eventContext }); decisionProvider.addPayload({ id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", diff --git a/test/unit/specs/components/DecisioningEngine/createEventContext.spec.js b/test/unit/specs/components/DecisioningEngine/createEventContext.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..026ab24d3 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -13,6 +13,7 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createOnResponseHandler", () => { let lifecycle; @@ -20,6 +21,7 @@ describe("DecisioningEngine:createOnResponseHandler", () => { let eventRegistry; let decisionProvider; let applyResponse; + let eventContext; beforeEach(() => { lifecycle = jasmine.createSpyObj("lifecycle", { @@ -28,8 +30,9 @@ describe("DecisioningEngine:createOnResponseHandler", () => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - - decisionProvider = createDecisionProvider({ eventRegistry }); + eventContext = createEventContext(); + eventContext.setCurrentEventRegistry(eventRegistry); + decisionProvider = createDecisionProvider({ eventContext }); applyResponse = createApplyResponse(lifecycle); }); diff --git a/test/unit/specs/components/DecisioningEngine/index.spec.js b/test/unit/specs/components/DecisioningEngine/index.spec.js index cfb5adaee..2b0177825 100644 --- a/test/unit/specs/components/DecisioningEngine/index.spec.js +++ b/test/unit/specs/components/DecisioningEngine/index.spec.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. */ import createDecisioningEngine from "../../../../../src/components/DecisioningEngine/index"; -import { injectStorage } from "../../../../../src/utils"; +import { defer, injectStorage } from "../../../../../src/utils"; import { mockRulesetResponseWithCondition, proposition @@ -21,8 +21,15 @@ describe("createDecisioningEngine:commands:evaluateRulesets", () => { let mockEvent; let onResponseHandler; let decisioningEngine; - beforeEach(() => { + let awaitConsentDeferred; + let consent; + + beforeEach(async () => { mergeData = jasmine.createSpy(); + awaitConsentDeferred = defer(); + consent = jasmine.createSpyObj("consent", { + awaitConsent: awaitConsentDeferred.promise + }); const config = { orgId: "exampleOrgId", personalizationStorageEnabled: true @@ -32,7 +39,8 @@ describe("createDecisioningEngine:commands:evaluateRulesets", () => { const createNamespacedStorage = injectStorage(window); decisioningEngine = createDecisioningEngine({ config, - createNamespacedStorage + createNamespacedStorage, + consent }); mockEvent = { getContent: () => ({}), @@ -40,6 +48,7 @@ describe("createDecisioningEngine:commands:evaluateRulesets", () => { mergeData }; decisioningEngine.lifecycle.onComponentsRegistered(() => {}); + await awaitConsentDeferred.resolve(); }); it("should run the evaluateRulesets command and satisfy the rule based on global context", () => { From a8433e52a7dd2ae52add619a3a73da5f5e9d645b Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Mon, 23 Oct 2023 22:33:10 -0700 Subject: [PATCH 4/9] for sandbox testing --- sandbox/src/components/InAppMessagesDemo/InAppMessages.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js index 8d5f46a69..738ec167f 100644 --- a/sandbox/src/components/InAppMessagesDemo/InAppMessages.js +++ b/sandbox/src/components/InAppMessagesDemo/InAppMessages.js @@ -55,8 +55,14 @@ const { alloyInstance } = config[configKey]; +const getURLParams = key => { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get(key); +}; + if (alloyInstance !== window.alloy) { alloyInstance("configure", { + defaultConsent: getURLParams("defaultConsent") || "in", datastreamId, orgId, edgeDomain, From 7d42d0e53d05f9e702d3a55b60efba6ca8b32ca6 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 24 Oct 2023 10:27:56 -0700 Subject: [PATCH 5/9] fix after test --- src/components/DecisioningEngine/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index bacf335ca..946bd9ee6 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -31,9 +31,6 @@ const createDecisioningEngine = ({ consent }) => { const { orgId, personalizationStorageEnabled } = config; - const storage = createNamespacedStorage( - `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` - ); const eventContext = createEventContext(); const decisionProvider = createDecisionProvider({ eventContext }); const contextProvider = createContextProvider({ eventContext, window }); @@ -52,6 +49,9 @@ const createDecisioningEngine = ({ onComponentsRegistered(tools) { applyResponse = createApplyResponse(tools.lifecycle); if (personalizationStorageEnabled) { + const storage = createNamespacedStorage( + `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` + ); consent .awaitConsent() .then(() => { From 5aa28a61d9f9609f9e4ede5195be24a26526ef96 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 24 Oct 2023 18:00:10 -0700 Subject: [PATCH 6/9] in-memory storage --- .../createContextProvider.js | 4 +- .../createDecisionHistory.js | 4 +- .../createDecisionProvider.js | 6 +-- .../DecisioningEngine/createEventContext.js | 49 ------------------- .../DecisioningEngine/createEventRegistry.js | 38 ++++++++++---- .../createNoopEventRegistry.js | 23 --------- src/components/DecisioningEngine/index.js | 33 +++++++------ src/components/DecisioningEngine/utils.js | 14 ++++++ .../createContextProvider.spec.js | 26 +++------- .../createEventContext.spec.js | 0 .../createNoopEventRegistry.spec.js | 33 ------------- 11 files changed, 72 insertions(+), 158 deletions(-) delete mode 100644 src/components/DecisioningEngine/createEventContext.js delete mode 100644 src/components/DecisioningEngine/createNoopEventRegistry.js delete mode 100644 test/unit/specs/components/DecisioningEngine/createEventContext.spec.js delete mode 100644 test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js diff --git a/src/components/DecisioningEngine/createContextProvider.js b/src/components/DecisioningEngine/createContextProvider.js index 4fe2aeb28..303465a4d 100644 --- a/src/components/DecisioningEngine/createContextProvider.js +++ b/src/components/DecisioningEngine/createContextProvider.js @@ -14,7 +14,7 @@ import parseUrl from "../../utils/parseUrl"; import flattenObject from "../../utils/flattenObject"; import libraryVersion from "../../constants/libraryVersion"; -export default ({ eventContext, window }) => { +export default ({ eventRegistry, window }) => { const pageLoadTimestamp = new Date().getTime(); const getBrowserContext = () => { return { @@ -90,7 +90,7 @@ export default ({ eventContext, window }) => { ...addedContext }; - return { ...flattenObject(context), events: eventContext.toJSON() }; + return { ...flattenObject(context), events: eventRegistry.toJSON() }; }; return { getContext diff --git a/src/components/DecisioningEngine/createDecisionHistory.js b/src/components/DecisioningEngine/createDecisionHistory.js index 28053b8a8..1360c3f99 100644 --- a/src/components/DecisioningEngine/createDecisionHistory.js +++ b/src/components/DecisioningEngine/createDecisionHistory.js @@ -11,12 +11,12 @@ governing permissions and limitations under the License. */ import { PropositionEventType } from "../../constants/propositionEventType"; -export default ({ eventContext }) => { +export default ({ eventRegistry }) => { const recordQualified = id => { if (!id) { return undefined; } - return eventContext.addEvent({}, PropositionEventType.TRIGGER, id); + return eventRegistry.addEvent({}, PropositionEventType.TRIGGER, id); }; return { recordQualified }; diff --git a/src/components/DecisioningEngine/createDecisionProvider.js b/src/components/DecisioningEngine/createDecisionProvider.js index 33705b906..77beb7245 100644 --- a/src/components/DecisioningEngine/createDecisionProvider.js +++ b/src/components/DecisioningEngine/createDecisionProvider.js @@ -13,10 +13,10 @@ import createEvaluableRulesetPayload from "./createEvaluableRulesetPayload"; import createDecisionHistory from "./createDecisionHistory"; import { getActivityId } from "./utils"; -export default ({ eventContext }) => { +export default ({ eventRegistry }) => { const payloadsBasedOnActivityId = {}; - const decisionHistory = createDecisionHistory({ eventContext }); + const decisionHistory = createDecisionHistory({ eventRegistry }); const addPayload = payload => { const activityId = getActivityId(payload); @@ -26,7 +26,7 @@ export default ({ eventContext }) => { const evaluableRulesetPayload = createEvaluableRulesetPayload( payload, - eventContext, + eventRegistry, decisionHistory ); diff --git a/src/components/DecisioningEngine/createEventContext.js b/src/components/DecisioningEngine/createEventContext.js deleted file mode 100644 index 79d182db1..000000000 --- a/src/components/DecisioningEngine/createEventContext.js +++ /dev/null @@ -1,49 +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 createNoopEventRegistry from "./createNoopEventRegistry"; - -export default () => { - let currentEventRegistry = createNoopEventRegistry(); - - const addExperienceEdgeEvent = event => { - return currentEventRegistry.addExperienceEdgeEvent(event); - }; - - const addEvent = (event, eventType, eventId, action) => { - return currentEventRegistry.addEvent(event, eventType, eventId, action); - }; - - const getEvent = (eventType, eventId) => { - return currentEventRegistry.getEvent(eventType, eventId); - }; - - const toJSON = () => { - return currentEventRegistry.toJSON(); - }; - - const clear = () => { - currentEventRegistry.clear(); - }; - - const setCurrentEventRegistry = eventRegistry => { - currentEventRegistry = eventRegistry; - }; - - return { - addExperienceEdgeEvent, - addEvent, - getEvent, - toJSON, - setCurrentEventRegistry, - clear - }; -}; diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 22a060a2b..0ac394681 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -47,15 +47,22 @@ export const createEventPruner = ( }; 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 events = restore({}); + let currentStorage = storage; + let restore; + let save; + let events; + const updateStorage = () => { + restore = createRestoreStorage(currentStorage, STORAGE_KEY); + save = createSaveStorage( + currentStorage, + STORAGE_KEY, + saveDelay, + createEventPruner(MAX_EVENT_RECORDS, RETENTION_PERIOD) + ); + events = restore({}); + }; + updateStorage(); + const addEvent = (event, eventType, eventId, action) => { if (!events[eventType]) { events[eventType] = {}; @@ -134,5 +141,16 @@ export default ({ storage, saveDelay = DEFAULT_SAVE_DELAY }) => { return events[eventType][eventId]; }; - return { addExperienceEdgeEvent, addEvent, getEvent, toJSON: () => events }; + const setStorage = newStorage => { + currentStorage = newStorage; + updateStorage(); + }; + + return { + addExperienceEdgeEvent, + addEvent, + getEvent, + toJSON: () => events, + setStorage + }; }; diff --git a/src/components/DecisioningEngine/createNoopEventRegistry.js b/src/components/DecisioningEngine/createNoopEventRegistry.js deleted file mode 100644 index 9f0f3ec78..000000000 --- a/src/components/DecisioningEngine/createNoopEventRegistry.js +++ /dev/null @@ -1,23 +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. -*/ -const EMPTY_OBJECT = () => { - return {}; -}; - -export default () => { - return { - addExperienceEdgeEvent: EMPTY_OBJECT, - addEvent: EMPTY_OBJECT, - getEvent: EMPTY_OBJECT, - toJSON: EMPTY_OBJECT - }; -}; diff --git a/src/components/DecisioningEngine/index.js b/src/components/DecisioningEngine/index.js index 946bd9ee6..7fb43a2dd 100644 --- a/src/components/DecisioningEngine/index.js +++ b/src/components/DecisioningEngine/index.js @@ -22,8 +22,7 @@ import { MOBILE_EVENT_TYPE } from "./constants"; import createEvaluateRulesetsCommand from "./createEvaluateRulesetsCommand"; -import createEventContext from "./createEventContext"; -import createNoopEventRegistry from "./createNoopEventRegistry"; +import { clearLocalStorage, createInMemoryStorage } from "./utils"; const createDecisioningEngine = ({ config, @@ -31,9 +30,19 @@ const createDecisioningEngine = ({ consent }) => { const { orgId, personalizationStorageEnabled } = config; - const eventContext = createEventContext(); - const decisionProvider = createDecisionProvider({ eventContext }); - const contextProvider = createContextProvider({ eventContext, window }); + const storage = createNamespacedStorage( + `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` + ); + if (!personalizationStorageEnabled) { + clearLocalStorage(storage.persistent); + } + + const eventRegistry = createEventRegistry({ + storage: createInMemoryStorage() + }); + const decisionProvider = createDecisionProvider({ eventRegistry }); + const contextProvider = createContextProvider({ eventRegistry, window }); + const evaluateRulesetsCommand = createEvaluateRulesetsCommand({ contextProvider, decisionProvider @@ -49,23 +58,15 @@ const createDecisioningEngine = ({ onComponentsRegistered(tools) { applyResponse = createApplyResponse(tools.lifecycle); if (personalizationStorageEnabled) { - const storage = createNamespacedStorage( - `${sanitizeOrgIdForCookieName(orgId)}.decisioning.` - ); consent .awaitConsent() .then(() => { - const eventRegistry = createEventRegistry({ - storage: storage.persistent - }); - eventContext.setCurrentEventRegistry(eventRegistry); + eventRegistry.setStorage(storage.persistent); }) .catch(() => { - // If consent is rejected, we want to clear the local storage. if (storage) { - storage.persistent.clear(); + clearLocalStorage(storage.persistent); } - eventContext.setCurrentEventRegistry(createNoopEventRegistry()); }); } }, @@ -89,7 +90,7 @@ const createDecisioningEngine = ({ }) ); - eventContext.addExperienceEdgeEvent(event); + eventRegistry.addExperienceEdgeEvent(event); } }, commands: { diff --git a/src/components/DecisioningEngine/utils.js b/src/components/DecisioningEngine/utils.js index bb13e312a..811b1542d 100644 --- a/src/components/DecisioningEngine/utils.js +++ b/src/components/DecisioningEngine/utils.js @@ -49,3 +49,17 @@ export const getActivityId = proposition => { return id; }; +export const createInMemoryStorage = () => { + const inMemoryStorage = {}; + return { + getItem: key => { + return key in inMemoryStorage ? inMemoryStorage[key] : null; + }, + setItem: (key, value) => { + inMemoryStorage[key] = value; + } + }; +}; +export const clearLocalStorage = storage => { + storage.clear(); +}; diff --git a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js index 22848fde7..3dbd6aeca 100644 --- a/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createContextProvider.spec.js @@ -11,7 +11,6 @@ governing permissions and limitations under the License. */ import createContextProvider from "../../../../../src/components/DecisioningEngine/createContextProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createContextProvider", () => { let contextProvider; @@ -19,7 +18,6 @@ describe("DecisioningEngine:createContextProvider", () => { let storage; let window; let mockedTimestamp; - let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); @@ -46,9 +44,7 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns page context", () => { eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -66,9 +62,7 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns referring page context", () => { eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -84,9 +78,7 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns browser context", () => { eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -96,9 +88,7 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("returns windows context", () => { eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext()).toEqual( jasmine.objectContaining({ @@ -111,9 +101,7 @@ describe("DecisioningEngine:createContextProvider", () => { }); it("includes provided context passed in", () => { eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext({ cool: "beans" })).toEqual( jasmine.objectContaining({ @@ -133,9 +121,7 @@ describe("DecisioningEngine:createContextProvider", () => { eventRegistry = { toJSON: () => events }; - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); + contextProvider = createContextProvider({ eventRegistry, window }); expect(contextProvider.getContext({ cool: "beans" }).events).toEqual( events diff --git a/test/unit/specs/components/DecisioningEngine/createEventContext.spec.js b/test/unit/specs/components/DecisioningEngine/createEventContext.spec.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js b/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js deleted file mode 100644 index 3aeb6bdaf..000000000 --- a/test/unit/specs/components/DecisioningEngine/createNoopEventRegistry.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import createNoopEventRegistry from "../../../../../src/components/DecisioningEngine/createNoopEventRegistry"; - -describe("createNoopEventRegistry", () => { - let instance; - - beforeEach(() => { - instance = createNoopEventRegistry(); - }); - - it("should return a valid instance", () => { - expect(instance).toBeDefined(); - }); - - it("addExperienceEdgeEvent should return an empty object", () => { - const result = instance.addExperienceEdgeEvent(); - expect(result).toEqual({}); - }); - - it("addEvent should return an empty object", () => { - const result = instance.addEvent(); - expect(result).toEqual({}); - }); - - it("getEvent should return an empty object", () => { - const result = instance.getEvent(); - expect(result).toEqual({}); - }); - - it("toJSON should return an empty object", () => { - const result = instance.toJSON(); - expect(result).toEqual({}); - }); -}); From 493205539c77fd1df767d963b66eaaf452cc4351 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Tue, 24 Oct 2023 18:01:05 -0700 Subject: [PATCH 7/9] tests --- .../createEvaluableRulesetPayload.js | 4 ++-- .../components/DecisioningEngine/contextTestUtils.js | 7 ++----- .../DecisioningEngine/createDecisionHistory.spec.js | 11 ++++------- .../DecisioningEngine/createDecisionProvider.spec.js | 6 +----- .../createEvaluableRulesetPayload.spec.js | 6 +----- .../createEvaluateRulesetsCommand.spec.js | 8 ++------ .../DecisioningEngine/createOnResponseHandler.spec.js | 6 +----- 7 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js index ea69c5ca5..d1fa20995 100644 --- a/src/components/DecisioningEngine/createEvaluableRulesetPayload.js +++ b/src/components/DecisioningEngine/createEvaluableRulesetPayload.js @@ -44,7 +44,7 @@ const isRulesetItem = item => { } }; -export default (payload, eventContext, decisionHistory) => { +export default (payload, eventRegistry, decisionHistory) => { const consequenceAdapter = createConsequenceAdapter(); const activityId = getActivityId(payload); const items = []; @@ -64,7 +64,7 @@ export default (payload, eventContext, decisionHistory) => { }; const evaluate = context => { - const displayEvent = eventContext.getEvent(DISPLAY, activityId); + const displayEvent = eventRegistry.getEvent(DISPLAY, activityId); const displayedDate = displayEvent ? displayEvent.firstTimestamp diff --git a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js index 792bc6fa4..d57432a3f 100644 --- a/test/unit/specs/components/DecisioningEngine/contextTestUtils.js +++ b/test/unit/specs/components/DecisioningEngine/contextTestUtils.js @@ -13,7 +13,6 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; export const proposition = { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", @@ -125,10 +124,8 @@ export const setupResponseHandler = (applyResponse, window, condition) => { "clear" ]); const eventRegistry = createEventRegistry({ storage }); - const eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - const decisionProvider = createDecisionProvider({ eventContext }); - const contextProvider = createContextProvider({ eventContext, window }); + const decisionProvider = createDecisionProvider({ eventRegistry }); + const contextProvider = createContextProvider({ eventRegistry, window }); const onResponseHandler = createOnResponseHandler({ renderDecisions: true, diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js index e1e1254a6..ff775adb8 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionHistory.spec.js @@ -11,20 +11,17 @@ governing permissions and limitations under the License. */ import createDecisionHistory from "../../../../../src/components/DecisioningEngine/createDecisionHistory"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:decisionHistory", () => { let storage; let history; - let eventRegistry; - let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventRegistry = createEventRegistry({ storage, saveDelay: 10 }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - history = createDecisionHistory({ eventContext }); + + history = createDecisionHistory({ + eventRegistry: createEventRegistry({ storage, saveDelay: 10 }) + }); }); it("records decision time", () => { diff --git a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js index 0ebecdc49..062eb42ea 100644 --- a/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createDecisionProvider.spec.js @@ -11,20 +11,16 @@ governing permissions and limitations under the License. */ import createDecisionProvider from "../../../../../src/components/DecisioningEngine/createDecisionProvider"; import createEventRegistry from "../../../../../src/components/DecisioningEngine/createEventRegistry"; -import createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createDecisionProvider", () => { let decisionProvider; let storage; let eventRegistry; - let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - decisionProvider = createDecisionProvider({ eventContext }); + decisionProvider = createDecisionProvider({ eventRegistry }); decisionProvider.addPayloads([ { id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js index 2bf1d1025..c24130324 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluableRulesetPayload.spec.js @@ -12,20 +12,16 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createEvaluableRulesetPayload", () => { let storage; let eventRegistry; let decisionHistory; - let eventContext; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - decisionHistory = createDecisionHistory({ eventContext }); + decisionHistory = createDecisionHistory({ eventRegistry }); }); it("consumes ruleset-items", () => { diff --git a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js index de778593c..7c5bd3889 100644 --- a/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createEvaluateRulesetsCommand.spec.js @@ -14,7 +14,6 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:evaluateRulesetsCommand", () => { let onDecision; @@ -24,18 +23,15 @@ describe("DecisioningEngine:evaluateRulesetsCommand", () => { let contextProvider; let decisionProvider; let evaluateRulesetsCommand; - let eventContext; beforeEach(() => { onDecision = jasmine.createSpy(); applyResponse = createApplyResponse({ onDecision }); storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); - eventContext = createEventContext(); eventRegistry = createEventRegistry({ storage }); - eventContext.setCurrentEventRegistry(eventRegistry); - contextProvider = createContextProvider({ eventContext, window }); - decisionProvider = createDecisionProvider({ eventContext }); + contextProvider = createContextProvider({ eventRegistry, window }); + decisionProvider = createDecisionProvider({ eventRegistry }); decisionProvider.addPayload({ id: "2e4c7b28-b3e7-4d5b-ae6a-9ab0b44af87e", diff --git a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js index 026ab24d3..f2d2fe136 100644 --- a/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js +++ b/test/unit/specs/components/DecisioningEngine/createOnResponseHandler.spec.js @@ -13,7 +13,6 @@ 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 createEventContext from "../../../../../src/components/DecisioningEngine/createEventContext"; describe("DecisioningEngine:createOnResponseHandler", () => { let lifecycle; @@ -21,7 +20,6 @@ describe("DecisioningEngine:createOnResponseHandler", () => { let eventRegistry; let decisionProvider; let applyResponse; - let eventContext; beforeEach(() => { lifecycle = jasmine.createSpyObj("lifecycle", { @@ -30,9 +28,7 @@ describe("DecisioningEngine:createOnResponseHandler", () => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); eventRegistry = createEventRegistry({ storage }); - eventContext = createEventContext(); - eventContext.setCurrentEventRegistry(eventRegistry); - decisionProvider = createDecisionProvider({ eventContext }); + decisionProvider = createDecisionProvider({ eventRegistry }); applyResponse = createApplyResponse(lifecycle); }); From c8137464f4db10af738c33d44447470af2ca798c Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Wed, 25 Oct 2023 10:10:43 -0700 Subject: [PATCH 8/9] utils tests --- .../DecisioningEngine/utils.spec.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/unit/specs/components/DecisioningEngine/utils.spec.js b/test/unit/specs/components/DecisioningEngine/utils.spec.js index 1d2d0478a..474013594 100644 --- a/test/unit/specs/components/DecisioningEngine/utils.spec.js +++ b/test/unit/specs/components/DecisioningEngine/utils.spec.js @@ -10,6 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ import { + createInMemoryStorage, createRestoreStorage, createSaveStorage, getActivityId, @@ -18,9 +19,11 @@ import { describe("DecisioningEngine:utils", () => { let storage; + let inMemoryStorage; beforeEach(() => { storage = jasmine.createSpyObj("storage", ["getItem", "setItem", "clear"]); + inMemoryStorage = createInMemoryStorage(); }); it("restores from storage", () => { @@ -191,4 +194,27 @@ describe("DecisioningEngine:utils", () => { }; expect(getActivityId(proposition)).toEqual(undefined); }); + it("should set and retrieve an item from in-memory storage", () => { + const key = "testKey"; + const value = "testValue"; + inMemoryStorage.setItem(key, value); + const retrievedValue = inMemoryStorage.getItem(key); + expect(retrievedValue).toEqual(value); + }); + + it("should return null for a non-existent item", () => { + const key = "nonExistentKey"; + const retrievedValue = inMemoryStorage.getItem(key); + expect(retrievedValue).toBeNull(); + }); + + it("should overwrite the value for an existing key", () => { + const key = "existingKey"; + const originalValue = "originalValue"; + const updatedValue = "updatedValue"; + inMemoryStorage.setItem(key, originalValue); + inMemoryStorage.setItem(key, updatedValue); + const retrievedValue = inMemoryStorage.getItem(key); + expect(retrievedValue).toEqual(updatedValue); + }); }); From 085060da9622db330b728c604a6484f324a92389 Mon Sep 17 00:00:00 2001 From: Happy Shandilya Date: Wed, 25 Oct 2023 13:27:43 -0700 Subject: [PATCH 9/9] use setStorage only --- .../DecisioningEngine/createEventRegistry.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/DecisioningEngine/createEventRegistry.js b/src/components/DecisioningEngine/createEventRegistry.js index 69e04815c..21893860d 100644 --- a/src/components/DecisioningEngine/createEventRegistry.js +++ b/src/components/DecisioningEngine/createEventRegistry.js @@ -50,7 +50,9 @@ export default ({ storage }) => { let restore; let save; let events; - const updateStorage = () => { + const setStorage = newStorage => { + currentStorage = newStorage; + restore = createRestoreStorage(currentStorage, STORAGE_KEY); save = createSaveStorage( currentStorage, @@ -59,7 +61,8 @@ export default ({ storage }) => { ); events = restore({}); }; - updateStorage(); + + setStorage(storage); const addEvent = (event, eventType, eventId, action) => { if (!events[eventType]) { @@ -139,11 +142,6 @@ export default ({ storage }) => { return events[eventType][eventId]; }; - const setStorage = newStorage => { - currentStorage = newStorage; - updateStorage(); - }; - return { addExperienceEdgeEvent, addEvent,