diff --git a/src/helpers/cart-helper.js b/src/helpers/cart-helper.js
index 1920df3c..22b0dcdb 100644
--- a/src/helpers/cart-helper.js
+++ b/src/helpers/cart-helper.js
@@ -165,8 +165,9 @@ export function getCartTotal(order) {
export function getRecalibrationTotal(order) {
const itemsWithRecalibration = getServiceLineItems(order)
.filter((item) => item.requiresRecalibration);
- const recalibrationLineItems = itemsWithRecalibration.map((item) => {
- return item.childParts?.find((child) => child.partType === partTypeStrings.RECALIBRATION || child.partType === partTypeStrings.ADAS_RECALIBRATION) ?? {};
+
+ const recalibrationLineItems = itemsWithRecalibration.flatMap((item) => {
+ return item.childParts?.filter((child) => child.partType === partTypeStrings.RECALIBRATION || child.partType === partTypeStrings.ADAS_RECALIBRATION) ?? [];
});
return getPriceOfLineItems(recalibrationLineItems);
diff --git a/src/helpers/cart-helper.spec.js b/src/helpers/cart-helper.spec.js
index 5a70feab..c57eaa86 100644
--- a/src/helpers/cart-helper.spec.js
+++ b/src/helpers/cart-helper.spec.js
@@ -4,6 +4,7 @@ import {
getDeductible,
getLineItems,
getMobileFeeLineItem, getNonServiceLineItems,
+ getRecalibrationTotal,
getRecycleFeeLineItem, getSalesTax,
getServiceLineItems, getSubtotal, isOrderITAC, isOrderNoComp,
isOrderUnverified
@@ -25,7 +26,7 @@ describe('cart-helper', () => {
};
}
- function createDummyFeeItem(partNumber, partType, price, salesTax) {
+ function createDummyItemWithPartType(partNumber, partType, price, salesTax) {
return {
partNumber,
partType,
@@ -56,8 +57,8 @@ describe('cart-helper', () => {
const glassLineItem = createDummyItem('glass', 40, 2);
const otherLineItem = createDummyItem('other', 50, 3);
const vapsLineItem = createDummyItem('vaps', 60, 4);
- const mobileFeeLineItem = createDummyFeeItem(null, partTypeStrings.MOBILE_FEE, 70, 5);
- const recycleFeeLineItem = createDummyFeeItem(partNumberStrings.RECYCLE_FEE, null, 80, 6);
+ const mobileFeeLineItem = createDummyItemWithPartType(null, partTypeStrings.MOBILE_FEE, 70, 5);
+ const recycleFeeLineItem = createDummyItemWithPartType(partNumberStrings.RECYCLE_FEE, null, 80, 6);
const defaultLineItems = {
supportingItems: [supportingLineItem],
@@ -592,4 +593,99 @@ describe('cart-helper', () => {
});
});
});
+
+ describe('getRecalibrationTotal', () => {
+ test('Returns total price of recalibration items when there is only 1', () => {
+ // Arrange
+ const recalibrationItem = createDummyItemWithPartType('recal', partTypeStrings.RECALIBRATION, 25, 2);
+ const lineItemWithRecal = {
+ ...glassLineItem,
+ requiresRecalibration: true,
+ childParts: [recalibrationItem]
+ };
+ const order = {
+ lineItems: {
+ ...defaultLineItems,
+ glassParts: [lineItemWithRecal]
+ }
+ };
+
+ // Act
+ const result = getRecalibrationTotal(order);
+
+ // Assert
+ expect(result).toBe(25);
+ });
+ test('Returns total price of recalibration items when there are multiple', () => {
+ // Arrange
+ const recalibrationItem = createDummyItemWithPartType('recal', partTypeStrings.RECALIBRATION, 25, 2);
+ const thirdRecalibrationItem = createDummyItemWithPartType('third-recal', partTypeStrings.ADAS_RECALIBRATION, 35, 3);
+ const lineItemWithRecal = {
+ ...glassLineItem,
+ requiresRecalibration: true,
+ childParts: [recalibrationItem, thirdRecalibrationItem]
+ };
+ const order = {
+ lineItems: {
+ ...defaultLineItems,
+ glassParts: [lineItemWithRecal]
+ }
+ };
+
+ // Act
+ const result = getRecalibrationTotal(order);
+
+ // Assert
+ expect(result).toBe(60);
+ });
+
+ test('Returns 0 when no items require recalibration', () => {
+ // Arrange
+ const order = {
+ lineItems: defaultLineItems
+ };
+
+ // Act
+ const result = getRecalibrationTotal(order);
+
+ // Assert
+ expect(result).toBe(0);
+ });
+
+ test('Returns 0 when line items are null', () => {
+ // Arrange
+ const order = {
+ lineItems: nullLineItems
+ };
+
+ // Act
+ const result = getRecalibrationTotal(order);
+
+ // Assert
+ expect(result).toBe(0);
+ });
+
+ test('Filters out non-recalibration child parts', () => {
+ // Arrange
+ const recalibrationItem = createDummyItemWithPartType('recal', partTypeStrings.RECALIBRATION, 25, 2);
+ const otherChildItem = createDummyItem('other-child', 15, 1);
+ const lineItemWithRecal = {
+ ...glassLineItem,
+ requiresRecalibration: true,
+ childParts: [recalibrationItem, otherChildItem]
+ };
+ const order = {
+ lineItems: {
+ ...defaultLineItems,
+ glassParts: [lineItemWithRecal]
+ }
+ };
+
+ // Act
+ const result = getRecalibrationTotal(order);
+
+ // Assert
+ expect(result).toBe(25);
+ });
+ });
});
diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue
index 51595359..6576f745 100644
--- a/src/layouts/coverage-statement/coverage-statement.vue
+++ b/src/layouts/coverage-statement/coverage-statement.vue
@@ -60,6 +60,10 @@
+
+
@@ -357,6 +361,9 @@ export default {
return this.isITACQuoteVisible
|| this.isNoCompQuoteVisible
|| (this.showDeductibleOnly && this.deductibleValue > 0);
+ },
+ MAPolicy() {
+ return useMainStore().customerData.addressQuestions.state === "MA";
}
},
watch: {
diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js
index 6480a508..2c8c298d 100644
--- a/src/mixins/analytics-mixin.js
+++ b/src/mixins/analytics-mixin.js
@@ -7,7 +7,8 @@ import {
regenerateUserId,
regenerateDeviceId,
setSessionIdIfUnset,
- setSessionKeyIfUnset
+ setSessionKeyIfUnset,
+ updateSessionIdCookie
} from '@/helpers/cookie-helper';
import applicationConfig from '@/constants/application-config';
import queryStrings from '@/constants/query-strings';
@@ -52,12 +53,25 @@ export default {
}
return '';
},
- logPageView(pageEvent) {
+ async validateSession() {
+ const emptySessionId = '00000000-0000-0000-0000-000000000000';
+
+ if (this.noSession()) {
+ await this.initSession();
+ }
+
+ const sessionId = getSessionIdValue();
+ if (sessionId && sessionId !== emptySessionId) {
+ updateSessionIdCookie();
+ }
+ },
+ async logPageView(pageEvent) {
const store = useMainStore();
const currentPageName = this.getPageNameByQueryString();
+ //await this.validateSession();
const payload = {
- userId: getDeviceIdValue(),
+ userId: getUserIdValue(),
sessionKey: getSessionKeyValue(),
pageName: currentPageName,
referralSequenceNumber: store.order.referralSequenceNumber,
@@ -69,15 +83,16 @@ export default {
experimentsForUser: store.applicationUser.experiments
};
- store.logPageView(payload);
+ await store.logPageView(payload);
},
- logCustomEvent(category, action, label, value) {
+ async logCustomEvent(category, action, label, value) {
const store = useMainStore();
const currentPageName = this.getPageNameByQueryString();
+ //await this.validateSession();
const payload = {
- userId: getDeviceIdValue(),
+ userId: getUserIdValue(),
sessionKey: getSessionKeyValue(),
pageName: currentPageName,
referralSequenceNumber: store.order.referralSequenceNumber,
@@ -91,9 +106,9 @@ export default {
experimentsForUser: store.applicationUser.experiments
};
- store.logCustomEvent(payload);
+ await store.logCustomEvent(payload);
},
- pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null, value = undefined) {
+ async pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null, value = undefined) {
const currentPageName = this.getPageNameByQueryString();
const labelToLog = getValueToLog(label, valueToLogType);
@@ -109,14 +124,14 @@ export default {
pushToDataLayerIfDefined(eventToBePushed);
if (pushToLogApp) {
- this.logCustomEvent(category, action, labelToLog, value);
+ await this.logCustomEvent(category, action, labelToLog, value);
}
},
pushGenericObjectToGA(object) {
pushToDataLayerIfDefined(object);
},
- pushPageViewToGA() {
+ async pushPageViewToGA() {
const currentPageName = this.getPageNameByQueryString();
const pageViewEvent = {
event: GaEvents.PAGE_VIEW_EVENT,
@@ -126,7 +141,7 @@ export default {
pushToDataLayerIfDefined(pageViewEvent);
- this.logPageView(analyticsPageEvents.ENTRY);
+ await this.logPageView(analyticsPageEvents.ENTRY);
},
pushOrderToDataLayer() {
@@ -533,6 +548,7 @@ export default {
},
async initSession() {
+
regenerateDeviceId();
regenerateUserId();
diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js
index 2c65e505..a13806c1 100644
--- a/src/mixins/analytics-mixin.spec.js
+++ b/src/mixins/analytics-mixin.spec.js
@@ -8,29 +8,32 @@ import {
ValueToLogTypes
} from '@/constants/analytics';
import { useMainStore } from '@/store';
+import crypto from 'crypto';
+
+global.crypto = crypto;
describe('analyticsMixin.js', () => {
- test('logPageView: calls dispatch with type and payload', () => {
+ test('logPageView: calls dispatch with type and payload', async () => {
const payload = {};
const testCookieValue = {
sid: '10000000-0000-0000-0000-000000000001'
};
- setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) });
+ setupCookies({ ISSCookieValue: JSON.stringify(testCookieValue) });
- useMainStore().logPageView(payload);
+ await analyticsMixin.methods.logPageView(payload);
expect(useMainStore().logPageView).toBeCalled();
});
- test('logCustomEvent: calls dispatch with type and payload', () => {
- useMainStore().logCustomEvent('someCat', 'someAction', 'someLabel', 'someVal');
+ test('logCustomEvent: calls dispatch with type and payload', async () => {
+ await analyticsMixin.methods.logCustomEvent('someCat', 'someAction', 'someLabel', 'someVal');
expect(useMainStore().logCustomEvent).toBeCalled();
});
- test('pushEventToGA, should call dataLayer push and logCustomEvent too', () => {
+ test('pushEventToGA, should call dataLayer push and logCustomEvent too', async () => {
// Arrange
window.dataLayer = [];
const mockDataLayer = [];
@@ -44,13 +47,13 @@ describe('analyticsMixin.js', () => {
});
// Act
- analyticsMixin.methods.pushEventToGA('category', 'action', 'label', true);
+ await analyticsMixin.methods.pushEventToGA('category', 'action', 'label', true);
// Assert
expect(mockDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
});
- test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 only logs last 5 of label', () => {
+ test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 only logs last 5 of label', async () => {
// Arrange
window.dataLayer = [];
const expectedDataLayer = [];
@@ -64,7 +67,7 @@ describe('analyticsMixin.js', () => {
});
// Act
- analyticsMixin.methods.pushEventToGA(
+ await analyticsMixin.methods.pushEventToGA(
'category',
'action',
'1111122222333333',
@@ -76,7 +79,7 @@ describe('analyticsMixin.js', () => {
expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
});
- test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 logs only the last 3 characters for a 3 character string', () => {
+ test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 logs only the last 3 characters for a 3 character string', async () => {
// Arrange
window.dataLayer = [];
const expectedDataLayer = [];
@@ -90,7 +93,7 @@ describe('analyticsMixin.js', () => {
});
// Act
- analyticsMixin.methods.pushEventToGA(
+ await analyticsMixin.methods.pushEventToGA(
'category',
'action',
'111',
diff --git a/src/router/index.js b/src/router/index.js
index 81dca7e3..2a332ab6 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -35,14 +35,10 @@ const routes = [
return await GoToAccessIsDenied(next);
}
+ await analyticsMixin.methods.validateSession();
+
// Do not run these for the main entry page - as it is not part of the user flow.
if (issPageToUse !== issPageValues.ENTRY_PAGE) {
- if (analyticsMixin.methods.noSession()) {
- await analyticsMixin.methods.initSession();
- } else {
- updateSessionIdCookie();
- }
-
try {
await runExperiments(issPageToUse);
} catch (error) {
diff --git a/src/store/index.js b/src/store/index.js
index efd66b66..0fb6adc7 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1120,7 +1120,7 @@ export const useMainStore = defineStore({
.then((response) => {
const recalResponse = response.data;
if (recalResponse && recalResponse.recalibrationParts && recalResponse.recalibrationParts.length > 0) {
- this.addGlassPartRecalibrationInfo(partNumberChecked, recalResponse.recalibrationParts[0]);
+ this.addGlassPartRecalibrationInfo(partNumberChecked, recalResponse.recalibrationParts);
}
}));
}
@@ -1128,15 +1128,17 @@ export const useMainStore = defineStore({
await Promise.allSettled(recalPromises);
}
},
- addGlassPartRecalibrationInfo(partNumber, recalPartInformation) {
+ addGlassPartRecalibrationInfo(partNumber, recalPartArray) {
const glassPart = this.lineItems.glassParts.find((gp) => gp.partNumber === partNumber);
if (glassPart) {
- const recalChildPart = glassPart.childParts?.find((cp) => cp.partNumber === recalPartInformation.partNumber);
- if (!recalChildPart) {
- if (!Array.isArray(glassPart.childParts) || !glassPart.childParts.length) {
- glassPart.childParts = [];
+ for (const recalPartInformation of recalPartArray) {
+ const recalChildPart = glassPart.childParts?.find((cp) => cp.partNumber === recalPartInformation.partNumber);
+ if (!recalChildPart) {
+ if (!Array.isArray(glassPart.childParts) || !glassPart.childParts.length) {
+ glassPart.childParts = [];
+ }
+ glassPart.childParts.push(recalPartInformation);
}
- glassPart.childParts.push(recalPartInformation);
}
}
},
@@ -2560,7 +2562,7 @@ export const useMainStore = defineStore({
});
}
},
- logPageView({ userId, sessionKey, pageName, referralSequenceNumber, parentAccountNumber, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
+ async logPageView({ userId, sessionKey, pageName, referralSequenceNumber, parentAccountNumber, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
const payload = {
userId,
sessionKey,
@@ -2588,7 +2590,7 @@ export const useMainStore = defineStore({
}
);
},
- logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) {
+ async logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) {
if (pageName == null || pageName.length === 0) { pageName = 'none'; }
const payload = {
@@ -2625,7 +2627,7 @@ export const useMainStore = defineStore({
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN);
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN);
},
- initializeSession({ userId, sessionId, userAgent, referrer }) {
+ async initializeSession({ userId, sessionId, userAgent, referrer }) {
const payload = {
applicationName: applicationConfig.APPLICATION_NAME,
userId,