From ce988ee1205afd35b4d55e8d5a5da4bc855e9ab9 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 25 Apr 2022 08:39:17 -0400 Subject: [PATCH 1/2] CSR-18 log page events --- src/constants/endpoints.js | 4 +++ src/constants/store-actions.js | 1 + .../heritage-integration/cookie-helper.js | 15 +++++++- src/router/index.js | 33 +++++++++++++++-- src/store/index.js | 36 +++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 2325c29cd..322dab574 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -66,6 +66,10 @@ const endpoints = { LogExperimentExposureIfAssigned:{ url: "/analytics/api/v1/analytics/log-experiment-exposure", method: "POST", + }, + LogActivity:{ + url: "/analytics/api/v1/analytics/activity", + method: "POST", } }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 9e87416d4..7587907dc 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -18,6 +18,7 @@ const storeActions = { SET_REFERRAL_INFORMATION: "setReferralInformation", VALIDATE_ZIP: "validateZip", LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", + LOG_ACTIVITY: "logActivity", // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleAndDependencies", diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index bf1c56b72..d9cabc734 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -72,7 +72,7 @@ export function getDeviceIdValue(){ return cookieValueMatch[0].split('=')[1]; } - return ''; + return '00000000-0000-0000-0000-000000000000'; } /* @@ -88,6 +88,19 @@ export function getSessionKeyValue(){ return 0; } +/* + Gets value of skey cookie, returns 0 if not found. +*/ +export function getSessionIdValue(){ + const cookieValue = getCookieValueByName(cookieNames.SESSION_ID); + + if(cookieValue){ + return cookieValue; + } + + return '00000000-0000-0000-0000-000000000000'; +} + /* =========================== = PRIVATE FUNCTIONS = diff --git a/src/router/index.js b/src/router/index.js index ace5b43cc..fadcf66a1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -18,6 +18,8 @@ import store from "@/store"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; +import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; +import { settleAllPromises } from "@/helpers/layout-helper"; const routes = [ { @@ -36,7 +38,6 @@ const routes = [ async beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. try { - // If the saved session has timed out, clear the session, execute 404 logic. if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await GoToFunnelStartOn404(next); @@ -76,6 +77,7 @@ const routes = [ await GoToFunnelStartOn404(next); } + logPageEvent(to.query.fmgPage); return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } @@ -97,6 +99,8 @@ const routes = [ await GoToFunnelStartOn404(next); } + logPageEvent(to.query.fmgPage); + // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, @@ -162,7 +166,7 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery if (getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) { await saveOrder(); } - + router.push({ name: "root", query: Object.assign(optionalQuery, { @@ -264,4 +268,29 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } +async function logPageEvent(destinationFmgPageValue){ + const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, + { + userId: getDeviceIdValue(), + sessionKey: getSessionKeyValue(), + pageName: destinationFmgPageValue, + sessionId: getSessionIdValue(), + shouldUseSessionId: true, + pageEvent: { + action: '', + event: 'ENTRY', + } + }, false); + + // Settle promises and get results + const promiseResultMap = [ + { + resultKey: "logActivity", + promise: logActivityPromise, + }, + ]; + + let resultMap = await settleAllPromises(promiseResultMap); +} + export default router; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 33fa6e0f0..04c966518 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -409,6 +409,42 @@ export const actions = { }); }, + logActivity(context, { userId, sessionKey, pageName, sessionId, pageEvent, customEvent, shouldUseSessionId }) { + var customEventData = {}; + customEvent?.forEach(function(event) + { + var category = event.category; + var action = event.action; + var label = event.label; + var value = event.value; + customEventData[category] = { + category: category, + action: action, + label: label, + value: value + }; + }) + + return globalMethods.callHttpClient({ + method: endpoints.LogActivity.method, + endpoint: endpoints.LogActivity.url, + payload: { + userId: userId, + sessionKey: sessionKey, + sessionId: sessionId, + pageName: pageName, + applicationName: 'SafeliteContent', + shouldUseSessionId: shouldUseSessionId, + pageEvent: { + action: pageEvent.action, + event: pageEvent.event, + }, + customEvent: customEventData + } + }); + }, + + // Parts API Actions getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) { return globalMethods.callHttpClient({ From c71056db22ffee5b80c4a56373e5983e7b061167 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 25 Apr 2022 13:32:36 -0400 Subject: [PATCH 2/2] CSR-18 specs --- .../cookie-helper.spec.js | 16 +++++++++++- src/helpers/unit-test-helper.js | 1 + src/router/index.js | 10 ++++--- .../router-constants/analytics-page-events.js | 5 ++++ src/store/index.js | 2 +- src/store/store.spec.js | 26 +++++++++++++++++++ 6 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/router/router-constants/analytics-page-events.js diff --git a/src/helpers/heritage-integration/cookie-helper.spec.js b/src/helpers/heritage-integration/cookie-helper.spec.js index b4498f61b..03fca51b5 100644 --- a/src/helpers/heritage-integration/cookie-helper.spec.js +++ b/src/helpers/heritage-integration/cookie-helper.spec.js @@ -1,4 +1,4 @@ -import {getFunnelCookie, getDeviceIdValue, getSessionKeyValue} from "@/helpers/heritage-integration/cookie-helper.js"; +import {getFunnelCookie, getDeviceIdValue, getSessionKeyValue, getSessionIdValue} from "@/helpers/heritage-integration/cookie-helper.js"; import { removeAllTestCookies, setupCookies } from "@/helpers/unit-test-helper"; describe("cookies", () => { @@ -126,5 +126,19 @@ describe("cookies", () => { }); }); + + describe("getSessionIdValue", () => { + test("getSessionIdValue, should return GUID", () => { + // Arrange + setupCookies({}); + + // Act + const result = getSessionIdValue(); + + //Assert + expect(result).toBe('cba0c3d1-3c1b-4305-bb56-31aa50f58e27'); + + }); + }); }) \ No newline at end of file diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 20fad7ba2..753465886 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -62,6 +62,7 @@ export const cookies = { "anotherCookie": "{}", "someOtherCookie": "{}", "dxdev": "did=21b9b94a-ec23-42c1-aaac-e2ae4e4dbffe", + "sid": "cba0c3d1-3c1b-4305-bb56-31aa50f58e27", "skey": "12345" }; diff --git a/src/router/index.js b/src/router/index.js index 57a1cc3e2..985d90e11 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -21,6 +21,7 @@ import ComponentTest from "@/layouts/component-test/component-test.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import { analyticsPageEvents } from "./router-constants/analytics-page-events"; const routes = [ { @@ -78,7 +79,7 @@ const routes = [ await GoToFunnelStartOn404(next); } - logPageEvent(to.query.fmgPage); + // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } @@ -100,7 +101,7 @@ const routes = [ await GoToFunnelStartOn404(next); } - logPageEvent(to.query.fmgPage); + // logPageEvent(to.query.fmgPage, analyticsPageEvents.ENTRY); // Assign current query string parameters, as well as our fmgPage one. next({ @@ -127,6 +128,7 @@ const router = createRouter({ router.afterEach((to, from) => { baseMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); + logPageEvent(to.query[queryStrings.FMG_PAGE], analyticsPageEvents.ENTRY); }); router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { @@ -273,7 +275,7 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } -async function logPageEvent(destinationFmgPageValue){ +async function logPageEvent(destinationFmgPageValue, pageEvent){ const logActivityPromise = baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOG_ACTIVITY, { userId: getDeviceIdValue(), @@ -283,7 +285,7 @@ async function logPageEvent(destinationFmgPageValue){ shouldUseSessionId: true, pageEvent: { action: '', - event: 'ENTRY', + event: pageEvent, } }, false); diff --git a/src/router/router-constants/analytics-page-events.js b/src/router/router-constants/analytics-page-events.js new file mode 100644 index 000000000..ab4753b3d --- /dev/null +++ b/src/router/router-constants/analytics-page-events.js @@ -0,0 +1,5 @@ +const analyticsPageEvents = { + ENTRY: "ENTRY", +}; + +export { analyticsPageEvents }; diff --git a/src/store/index.js b/src/store/index.js index 04c966518..85b3e7a70 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -433,7 +433,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteContent', + applicationName: 'SafeliteDotCom', shouldUseSessionId: shouldUseSessionId, pageEvent: { action: pageEvent.action, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 7618cc25a..e5903ad64 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -617,6 +617,32 @@ describe("Actions", () => { expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, "xxx-xxx-xxx"); }); + it("logActivity action, should return nothing", async () => { + + // Arrange + const context = state; + var pageEvent = { + action: "", + event: "ENTRY", + } + + var customEvent = [{ + category: "tstCat", + action: "click", + label: "damage", + value: "psych" + }]; + + // Act + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ }); + }); + + // Assert + const response = await actions.logActivity(context, { userId: "userId", sessionKey: "sessionKey", pageName: "pageName", sessionId: "sessionId", pageEvent: pageEvent, customEvent: customEvent, shouldUseSessionId: true }); + expect(response).toEqual({}); + }); + }); describe("Getters", () => {