From adc911c3bf181001562ed0b0f7ed1ad632d510cf Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Wed, 10 Jul 2024 08:16:32 -0500 Subject: [PATCH 01/11] SSR-1411 rework save session to be awaitable --- src/helpers/order-helper.js | 13 +++---- src/layouts/bailout-page/bailout-page.spec.js | 6 ++-- src/layouts/bailout-page/bailout-page.vue | 6 ++-- src/layouts/entry-page/entry-page.vue | 4 +-- .../order-confirmation/order-confirmation.vue | 1 - src/layouts/payment-method/payment-method.vue | 8 ++--- src/layouts/payment-return/payment-return.vue | 7 +--- src/layouts/tpa-submit/tpa-submit.vue | 6 +--- src/layouts/welcome-page/welcome-page.spec.js | 10 +++--- src/layouts/welcome-page/welcome-page.vue | 34 +++++++++++++------ src/router/index.js | 14 ++------ src/router/router-constants/router-params.js | 2 +- 12 files changed, 51 insertions(+), 60 deletions(-) diff --git a/src/helpers/order-helper.js b/src/helpers/order-helper.js index 97b685cd..f96b8a2a 100644 --- a/src/helpers/order-helper.js +++ b/src/helpers/order-helper.js @@ -34,15 +34,12 @@ export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitA Will determine if to submitWorkOrder. TODO: Add more description to this */ -export async function submitWorkOrder({ - pageNameToLog, - submitAfterSave = false, - createDeleteStatusWorkOrderForPia = false -}) { +export async function submitWorkOrder({ submitType }) { + const store = useMainStore(); + store.resetSubmittedOrder(); await saveSession({ - pageNameToLog, shouldAwaitSaveSessionQueue: true, - submitAfterSave, - createDeleteStatusWorkOrderForPia + submitAfterSave: true }); + store.createSubmittedOrder(submitType); } diff --git a/src/layouts/bailout-page/bailout-page.spec.js b/src/layouts/bailout-page/bailout-page.spec.js index c3feda2c..5b0c68ee 100644 --- a/src/layouts/bailout-page/bailout-page.spec.js +++ b/src/layouts/bailout-page/bailout-page.spec.js @@ -436,19 +436,19 @@ describe('Bailout page', () => { }); }); describe('forwardButtonAction', () => { - test('should navigate to the next route', () => { + test('should navigate to the next route', async () => { // Arrange const { wrapper } = getMountedComponent(); // Act - wrapper.vm.forwardButtonAction(); + await wrapper.vm.forwardButtonAction(); // Assert expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( wrapper.vm.navigationScenarios.CLICKED_FORWARD, wrapper.vm.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); }); diff --git a/src/layouts/bailout-page/bailout-page.vue b/src/layouts/bailout-page/bailout-page.vue index 41ab3614..f13d9ba4 100644 --- a/src/layouts/bailout-page/bailout-page.vue +++ b/src/layouts/bailout-page/bailout-page.vue @@ -91,6 +91,7 @@ import canBailoutNavigateBack from '@/helpers/bailout-helper'; import BailoutCode from '@/constants/bailoutCode'; import issPageValues from '@/router/router-constants/issPage-values'; import MaskaFormattedMasks from '@/constants/maska-masks'; +import { saveSession } from '@/helpers/order-helper'; export default { name: 'bailout-page', @@ -200,13 +201,14 @@ export default { this.$route ); }, - forwardButtonAction() { + async forwardButtonAction() { this.mainStore.setBailoutContactInfo(this.bailoutPageModel); + await saveSession({ shouldAwaitSaveSessionQueue: true }); this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }, getBailoutPageModelFromStore() { diff --git a/src/layouts/entry-page/entry-page.vue b/src/layouts/entry-page/entry-page.vue index 29475742..8c4cfba3 100644 --- a/src/layouts/entry-page/entry-page.vue +++ b/src/layouts/entry-page/entry-page.vue @@ -38,7 +38,7 @@ export default { this.unauthorized = !isAuthorized; if (isAuthorized) { - await this.populateISSConfigValues(clientData); + this.populateISSConfigValues(clientData); if (clientData.parameters?.length > 0) { const finalParams = this.combineClientParameters(clientData.parameters, queryStringParams); @@ -100,7 +100,7 @@ export default { return { isAuthorized: authorized, clientData }; }, - async populateISSConfigValues(data) { + populateISSConfigValues(data) { this.mainStore.issConfig.clientName = data.accountName; this.mainStore.issConfig.clientDisplayName = data.accountName; // Defaults to use the client name. this.mainStore.issConfig.parentAccountNumber = data.parentAccountNumber; diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index 589dd87b..de1c896e 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -120,7 +120,6 @@ export default { }, mixins: [BaseFormMixin], async beforeRouteEnter(to, from, next) { - useMainStore().createSubmittedOrder(submitType.SAFELITE); // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 589f6986..8f69cab3 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -91,6 +91,7 @@ import { AppointmentTypeStrings } from '@/constants/schedule-constants'; import VehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue'; import { submitWorkOrder } from '@/helpers/order-helper.js'; import { experimentSettings } from '@/constants/experiments'; +import submitType from '@/constants/submit-type'; export default { name: 'payment-method', @@ -300,12 +301,7 @@ export default { if (this.paymentMethod === paymentMethods.PAY_AT_TIME_OF_SERVICE) { try { - await submitWorkOrder({ - pageNameToLog: 'payment-method', - submitAfterSave: true - }).then(() => { - useMainStore().resetSubmittedOrder(); - + await submitWorkOrder({ submitType: submitType.SAFELITE }).then(() => { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD, this.$route diff --git a/src/layouts/payment-return/payment-return.vue b/src/layouts/payment-return/payment-return.vue index c7814569..b4df4190 100644 --- a/src/layouts/payment-return/payment-return.vue +++ b/src/layouts/payment-return/payment-return.vue @@ -124,12 +124,8 @@ export default { }, async saveAndSubmitWorkOrder() { // Final work order submit after returning from pay in advance. - useMainStore().resetSubmittedOrder(); try { - await submitWorkOrder({ - pageNameToLog: 'payment-return', - submitAfterSave: true - }); + await submitWorkOrder({ submitType: submitType.SAFELITE }); } catch (error) { console.error(`error: response from submit work order:${error.message}`); this.navigateOnPayInAdvanceError(); @@ -138,7 +134,6 @@ export default { } showIssLoadingModal(false); - useMainStore().createSubmittedOrder(submitType.SAFELITE); this.$router.navigate( this.navigationScenarios.PAY_IN_ADVANCE_SUCCESS, this.$route diff --git a/src/layouts/tpa-submit/tpa-submit.vue b/src/layouts/tpa-submit/tpa-submit.vue index 0c1593a5..200b92b1 100644 --- a/src/layouts/tpa-submit/tpa-submit.vue +++ b/src/layouts/tpa-submit/tpa-submit.vue @@ -354,11 +354,7 @@ export default { }, async forwardButtonAction() { try { - await submitWorkOrder({ - pageNameToLog: 'tpa-submit', - submitAfterSave: true - }).then(() => { - useMainStore().createSubmittedOrder(submitType.TPA); + await submitWorkOrder({ submitType: submitType.TPA }).then(() => { this.navigate(this.navigationScenarios.CLICKED_FORWARD); }).catch((submitError) => { useMainStore().setBailout(bailoutMessage.saveSessionError(submitError.data)); diff --git a/src/layouts/welcome-page/welcome-page.spec.js b/src/layouts/welcome-page/welcome-page.spec.js index b36edb9f..9a99c48c 100644 --- a/src/layouts/welcome-page/welcome-page.spec.js +++ b/src/layouts/welcome-page/welcome-page.spec.js @@ -206,7 +206,7 @@ describe('navigation', () => { navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, undefined, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); test('if policy and vehicles are found but no duplicates, navigate to policy-vehicle page', async () => { @@ -234,7 +234,7 @@ describe('navigation', () => { navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, undefined, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); test('if policy is found, but no vehicles and no duplicates, navigate to vehicle-selection page', async () => { @@ -259,7 +259,7 @@ describe('navigation', () => { navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, undefined, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); test('if policy is found, but null vehicles and no duplicates, navigate to vehicle-selection page', async () => { @@ -285,7 +285,7 @@ describe('navigation', () => { navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, undefined, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); test('if policy is not found and no duplicates, navigate to policy-holder-details page', async () => { @@ -310,7 +310,7 @@ describe('navigation', () => { navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, undefined, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); }); test('getDuplicateReferrals throws rejected promise => navigate called', async () => { diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 454e6734..11d7614f 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -174,6 +174,8 @@ import states from '@/constants/states'; import globalRules from '@/constants/global-rules'; import routerParams from '@/router/router-constants/router-params'; import MaskaFormattedMasks from '@/constants/maska-masks'; +import { saveSession } from '@/helpers/order-helper'; +import bailoutMessage from '@/constants/bailoutMessage'; // define validation rules defineRule( @@ -299,17 +301,22 @@ export default { methods: { async forwardButtonAction() { try { - await this.configureZip(); this.mainStore.updatePolicyData(this.welcomePageModel); - await this.mainStore.getBillToInfo(); - await this.mainStore.getDuplicateReferrals(); - await this.mainStore.getCoveragePolicyInfo(); + await Promise.allSettled([ + this.configureZip().then(async () => this.mainStore.getBillToInfo()), + this.mainStore.getDuplicateReferrals(), + this.mainStore.getCoveragePolicyInfo() + ]); } catch (e) { console.error(e); // TODO: Bailout? } finally { if (!this.displayInvalidZipAlert) { - this.navigateForward(); + await saveSession({ shouldAwaitSaveSessionQueue: true }) + .catch((error) => { + this.mainStore.setBailout(bailoutMessage.saveSessionError(error.data)); + }) + .finally(() => this.navigateForward()); } } }, @@ -324,12 +331,19 @@ export default { } }, navigateForward() { - if (this.mainStore.applicationUser.duplicateOrders?.length > 0 ?? false) { + if (this.mainStore.isBailout) { + this.$router.navigate( + this.navigationScenarios.SAVE_SESSION_FAILED, + this.$route, + {}, + { [routerParams.SKIP_SAVE_SESSION]: true } + ); + } else if (this.mainStore.applicationUser.duplicateOrders?.length > 0 ?? false) { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, this.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); } else if (this.mainStore.isPolicyLookupSuccessful) { if (this.mainStore.order.policy.vehicles?.length > 0 ?? false) { @@ -339,7 +353,7 @@ export default { .CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, this.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); } else { // navigate to vehicle-selection page (manual entry) @@ -348,7 +362,7 @@ export default { .CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, this.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); } } else { @@ -357,7 +371,7 @@ export default { this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, this.$route, {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + { [routerParams.SKIP_SAVE_SESSION]: true } ); } }, diff --git a/src/router/index.js b/src/router/index.js index 7bd1c4e0..7a0c2097 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -171,17 +171,9 @@ router.afterEach(async (to, from) => { store.clearSaveSessionPromise(); } - if (to.query.issPage !== issPageValues.TPA_CONFIRMATION && to.query.issPage !== issPageValues.ORDER_CONFIRMATION) { - const saveSessionSynchronous = !!router.options.history.state[routerParams.SAVE_SESSION_SYNCHRONOUS]; - await saveSession({ shouldAwaitSaveSessionQueue: saveSessionSynchronous }).catch((error) => { - if (from.name === issPageValues.WELCOME_PAGE) { - store.setBailout(bailoutMessage.saveSessionError(error.data)); - router.navigate( - navigationScenarios.SAVE_SESSION_FAILED, - { query: { issPage: issPageValues.WELCOME_PAGE } } - ); - } - }); + const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; + if (!skipSaveSession && !store.hasSubmittedOrder()) { + await saveSession({}); } if (to.query.issPage !== issPageValues.ENTRY_PAGE) { diff --git a/src/router/router-constants/router-params.js b/src/router/router-constants/router-params.js index 2465f965..2eb3fe76 100644 --- a/src/router/router-constants/router-params.js +++ b/src/router/router-constants/router-params.js @@ -1,6 +1,6 @@ const routerParams = Object.freeze({ DISPLAY_VEHICLE_CHANGE_ALERT: 'displayVehicleChangeAlert', - SAVE_SESSION_SYNCHRONOUS: 'saveSessionSynchronous' + SKIP_SAVE_SESSION: 'skipSaveSession' }); export default routerParams; From d0810969da64a0621408fb9db5482db7b6bf3f19 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Wed, 10 Jul 2024 08:54:12 -0500 Subject: [PATCH 02/11] SSR-1411 Fix unit test --- src/layouts/welcome-page/welcome-page.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layouts/welcome-page/welcome-page.spec.js b/src/layouts/welcome-page/welcome-page.spec.js index 9a99c48c..1fd64cfd 100644 --- a/src/layouts/welcome-page/welcome-page.spec.js +++ b/src/layouts/welcome-page/welcome-page.spec.js @@ -180,7 +180,6 @@ describe('navigation', () => { await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalledTimes(0); expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(0); }); }); From f86a428158aa5288f8a595df71aaba74565ab9cc Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 10 Jul 2024 10:35:18 -0400 Subject: [PATCH 03/11] Check if fees are hidden and hide cart row Pass experiment flags to price service --- src/helpers/experiment-helper.js | 21 +++++++++++++++++++ .../cart-dropdown/cart-dropdown.vue | 6 ++++-- src/store/index.js | 3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 src/helpers/experiment-helper.js diff --git a/src/helpers/experiment-helper.js b/src/helpers/experiment-helper.js new file mode 100644 index 00000000..c0f0d3a8 --- /dev/null +++ b/src/helpers/experiment-helper.js @@ -0,0 +1,21 @@ +export function hasExperimentSetting(experimentSettings, settingName) { + return Object.hasOwn(experimentSettings, settingName); +} + +export function getExperimentSettingValue(experimentSettings, settingName) { + return hasExperimentSetting(experimentSettings, settingName) + ? experimentSettings[settingName] + : null; +} + +export function getFeatureTogglesQueryString(experimentSettings) { + const isMobileFeeHidden = getExperimentSettingValue(experimentSettings, 'HideMobileFee') === 'true'; + const isMobileFeeOverridden = getExperimentSettingValue(experimentSettings, 'OverrideMobileFee') === 'true'; + const isRecycleFeeHidden = getExperimentSettingValue(experimentSettings, 'HideRecycleFee') === 'true'; + const isRecycleFeeOverridden = getExperimentSettingValue(experimentSettings, 'OverrideRecycleFee') === 'true'; + + return `FeatureToggles.IsMobileFeeHidden=${isMobileFeeHidden}` + + `&FeatureToggles.IsMobileFeeOverridden=${isMobileFeeOverridden}` + + `&FeatureToggles.IsRecycleFeeHidden=${isRecycleFeeHidden}` + + `&FeatureToggles.IsRecycleFeeOverridden=${isRecycleFeeOverridden}`; +} diff --git a/src/iss-components/cart-dropdown/cart-dropdown.vue b/src/iss-components/cart-dropdown/cart-dropdown.vue index c7eb6a57..f181d6e8 100644 --- a/src/iss-components/cart-dropdown/cart-dropdown.vue +++ b/src/iss-components/cart-dropdown/cart-dropdown.vue @@ -322,10 +322,12 @@ export default { } }); const items = vapsCartItemsNotInPackage.filter((item) => item != null); - if (this.recycleFeeCartItem) { + const isRecycleFeeHidden = this.getSettingValue('HideRecycleFee') === 'true'; + const isMobileFeeHidden = this.getSettingValue('HideMobileFee') === 'true'; + if (this.recycleFeeCartItem && !isRecycleFeeHidden) { items.push(this.recycleFeeCartItem); } - if (this.mobileFeeCartItem) { + if (this.mobileFeeCartItem && !isMobileFeeHidden) { items.push(this.mobileFeeCartItem); } return items; diff --git a/src/store/index.js b/src/store/index.js index c36f5887..3ba9011f 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -28,6 +28,7 @@ import partNumberStrings from '@/constants/part-number-strings'; import { getLineItemsFlattened } from '@/helpers/line-items-helper'; import { buildQueryStringParameterFromArrayOfComplexObjects, getLineItemQueryString, getTaxLineItemQueryString } from '@/helpers/querystring-helper'; import coverageType from '@/constants/coverage-type'; +import { getFeatureTogglesQueryString } from '@/helpers/experiment-helper'; const storeId = 'main'; @@ -1034,6 +1035,7 @@ export const useMainStore = defineStore({ async getInsurancePriceOrderItems(availableLineItems) { const { serviceLocation, currentDeductible } = this.order; const lineItemsQueryString = getLineItemQueryString(availableLineItems, 'lineItems'); + const featureTogglesQueryString = getFeatureTogglesQueryString(this.experimentSettings); let queryString = `ParentAccountNumber=${this.order.parentAccountNumber}` @@ -1041,6 +1043,7 @@ export const useMainStore = defineStore({ + `&CTU=${serviceLocation.zipCodeCtu}` + `&Deductible=${currentDeductible ?? 0}` + `&ZipCode=${serviceLocation.zipCode}` + + `&${featureTogglesQueryString}` + `${lineItemsQueryString}`; const lineItemServerData = this.order.lineItems?.serverData; From 8c59ba9c6e8c2d2c6ff7edc77d1ba0e807a3fcd7 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Wed, 10 Jul 2024 11:31:18 -0500 Subject: [PATCH 04/11] SSR-1411 Add missing await --- src/layouts/welcome-page/welcome-page.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 11d7614f..0298a45c 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -303,7 +303,7 @@ export default { try { this.mainStore.updatePolicyData(this.welcomePageModel); await Promise.allSettled([ - this.configureZip().then(async () => this.mainStore.getBillToInfo()), + this.configureZip().then(async () => await this.mainStore.getBillToInfo()), this.mainStore.getDuplicateReferrals(), this.mainStore.getCoveragePolicyInfo() ]); From 26c6db7eb0e3c9300a46ef1091b9c14c44268ebd Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 10 Jul 2024 13:20:37 -0400 Subject: [PATCH 05/11] Use constants instead of strings Update one test file. Working on other. --- src/constants/experiments.js | 6 ++++- src/helpers/experiment-helper.js | 23 +++++++++++-------- .../cart-dropdown/cart-dropdown.spec.js | 4 ++-- .../cart-dropdown/cart-dropdown.vue | 5 ++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/constants/experiments.js b/src/constants/experiments.js index 18676ce4..ede13562 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -4,7 +4,11 @@ const experimentUniverses = Object.freeze({ const experimentSettings = Object.freeze({ GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index', - ISS_DISPLAY_PAY_IN_ADVANCE: 'DisplayPIAInsurance' + ISS_DISPLAY_PAY_IN_ADVANCE: 'DisplayPIAInsurance', + ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN: 'HideMobileFee', + ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'HideMobileFee', + ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee', + ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'HideRecycleFee' }); const experimentTriggers = Object.freeze({ diff --git a/src/helpers/experiment-helper.js b/src/helpers/experiment-helper.js index c0f0d3a8..861b2ad2 100644 --- a/src/helpers/experiment-helper.js +++ b/src/helpers/experiment-helper.js @@ -1,18 +1,21 @@ -export function hasExperimentSetting(experimentSettings, settingName) { - return Object.hasOwn(experimentSettings, settingName); +/* eslint-disable max-len */ +import { experimentSettings } from '@/constants/experiments'; + +export function hasExperimentSetting(storeExperimentSettings, settingName) { + return Object.hasOwn(storeExperimentSettings, settingName); } -export function getExperimentSettingValue(experimentSettings, settingName) { - return hasExperimentSetting(experimentSettings, settingName) - ? experimentSettings[settingName] +export function getExperimentSettingValue(storeExperimentSettings, settingName) { + return hasExperimentSetting(storeExperimentSettings, settingName) + ? storeExperimentSettings[settingName] : null; } -export function getFeatureTogglesQueryString(experimentSettings) { - const isMobileFeeHidden = getExperimentSettingValue(experimentSettings, 'HideMobileFee') === 'true'; - const isMobileFeeOverridden = getExperimentSettingValue(experimentSettings, 'OverrideMobileFee') === 'true'; - const isRecycleFeeHidden = getExperimentSettingValue(experimentSettings, 'HideRecycleFee') === 'true'; - const isRecycleFeeOverridden = getExperimentSettingValue(experimentSettings, 'OverrideRecycleFee') === 'true'; +export function getFeatureTogglesQueryString(storeExperimentSettings) { + const isMobileFeeHidden = getExperimentSettingValue(storeExperimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN) === 'true'; + const isMobileFeeOverridden = getExperimentSettingValue(storeExperimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN) === 'true'; + const isRecycleFeeHidden = getExperimentSettingValue(storeExperimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN) === 'true'; + const isRecycleFeeOverridden = getExperimentSettingValue(storeExperimentSettings, experimentSettings.ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN) === 'true'; return `FeatureToggles.IsMobileFeeHidden=${isMobileFeeHidden}` + `&FeatureToggles.IsMobileFeeOverridden=${isMobileFeeOverridden}` diff --git a/src/iss-components/cart-dropdown/cart-dropdown.spec.js b/src/iss-components/cart-dropdown/cart-dropdown.spec.js index 265a3e13..dcf6ddc7 100644 --- a/src/iss-components/cart-dropdown/cart-dropdown.spec.js +++ b/src/iss-components/cart-dropdown/cart-dropdown.spec.js @@ -3,7 +3,7 @@ import { createTestingPinia } from '@pinia/testing'; import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue'; // Supporting Files -import {getEnumName, getMountOptions} from '@/helpers/unit-test-helper.js'; +import { getEnumName, getMountOptions } from '@/helpers/unit-test-helper.js'; import { useMainStore, getDefaultState } from '@/store'; import { formatAmountInDollars } from '@/helpers/text-helper.js'; import partTypeStrings from '@/constants/part-type-strings'; @@ -43,6 +43,7 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, propsData }); useMainStore(testingPinia); + mountOptions.global.mixins[0].methods.getSettingValue = jest.fn(() => 'false'); mountOptions.global.plugins = [testingPinia]; mountOptions.data = () => (initialData); mountOptions.propsData = propsData; @@ -1338,7 +1339,6 @@ describe('cart-dropdown component', () => { const { wrapper } = getMountedComponent(storeData); formatAmountInDollars.mockReturnValueOnce(dollarAmount); - // Act const result = wrapper.vm.getDisplayed(0); diff --git a/src/iss-components/cart-dropdown/cart-dropdown.vue b/src/iss-components/cart-dropdown/cart-dropdown.vue index f181d6e8..887a99f5 100644 --- a/src/iss-components/cart-dropdown/cart-dropdown.vue +++ b/src/iss-components/cart-dropdown/cart-dropdown.vue @@ -163,6 +163,7 @@ import { formatAmountInDollars } from '@/helpers/text-helper.js'; import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/service-package-helper.js'; // Constants +import { experimentSettings } from '@/constants/experiments'; import partTypeStrings from '@/constants/part-type-strings.js'; import cartItemType from '@/constants/cart-item-type.js'; import widgetFields from '@/constants/cms-widget-fields.js'; @@ -322,8 +323,8 @@ export default { } }); const items = vapsCartItemsNotInPackage.filter((item) => item != null); - const isRecycleFeeHidden = this.getSettingValue('HideRecycleFee') === 'true'; - const isMobileFeeHidden = this.getSettingValue('HideMobileFee') === 'true'; + const isRecycleFeeHidden = this.getSettingValue(experimentSettings.ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN) === 'true'; + const isMobileFeeHidden = this.getSettingValue(experimentSettings.ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN) === 'true'; if (this.recycleFeeCartItem && !isRecycleFeeHidden) { items.push(this.recycleFeeCartItem); } From 005d0700ffa0f8e23667d3a136202776eb9a4ceb Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 10 Jul 2024 13:28:12 -0400 Subject: [PATCH 06/11] formatting and fix test --- src/layouts/order-confirmation/order-confirmation.spec.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/layouts/order-confirmation/order-confirmation.spec.js b/src/layouts/order-confirmation/order-confirmation.spec.js index abd7c86b..80cead3a 100644 --- a/src/layouts/order-confirmation/order-confirmation.spec.js +++ b/src/layouts/order-confirmation/order-confirmation.spec.js @@ -9,8 +9,8 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { mount } from '@vue/test-utils'; import { createTestingPinia } from '@pinia/testing'; import { nextTick } from 'vue'; -import coverageStatuses from "@/constants/coverage-statuses"; -import coverageType from "@/constants/coverage-type"; +import coverageStatuses from '@/constants/coverage-statuses'; +import coverageType from '@/constants/coverage-type'; jest.mock('@/helpers/layout-helper.js', () => jest.fn()); @@ -173,6 +173,7 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu useMainStore(testingPinia); methodToRun(); + mountOptions.global.mixins[0].methods.getSettingValue = jest.fn(() => 'false'); mountOptions.global.plugins = [testingPinia]; mountOptions.mixins = [mockMixin]; mountOptions.data = () => ( From a5f75168eebb32fe0af4072785b986ba79af76d1 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 10 Jul 2024 14:04:02 -0400 Subject: [PATCH 07/11] Must've undid this at somepoint. Corrected override strings --- src/constants/experiments.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants/experiments.js b/src/constants/experiments.js index ede13562..b5af7dbc 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -6,9 +6,9 @@ const experimentSettings = Object.freeze({ GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index', ISS_DISPLAY_PAY_IN_ADVANCE: 'DisplayPIAInsurance', ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_HIDDEN: 'HideMobileFee', - ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'HideMobileFee', + ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'OverrideMobileFee', ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee', - ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'HideRecycleFee' + ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee' }); const experimentTriggers = Object.freeze({ From 7849694667139dcb0db8f5533c490d6c63307bf1 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 11 Jul 2024 12:21:33 -0400 Subject: [PATCH 08/11] Updates for calculating highest fully completed package tier Misc linting updates as well - service-package component all linting --- .../service-package-question.vue | 60 +++++-------------- .../service-packages/service-packages.vue | 16 ++--- 2 files changed, 23 insertions(+), 53 deletions(-) diff --git a/src/layouts/service-packages/service-package-question/service-package-question.vue b/src/layouts/service-packages/service-package-question/service-package-question.vue index 06a97fdf..bad1f443 100644 --- a/src/layouts/service-packages/service-package-question/service-package-question.vue +++ b/src/layouts/service-packages/service-package-question/service-package-question.vue @@ -19,6 +19,7 @@ import partTypeStrings from '@/constants/part-type-strings'; import { useMainStore } from '@/store'; import allGlassPartsAndItemsHavePrices from '@/layouts/service-packages/service-package-helper/service-package-helper'; import { getPriceOfLineItem } from '@/helpers/price-calculator'; +import { getHighestFullySatisfiedTier } from '@/helpers/service-package-helper.js'; const glassLocations = damageLocationsSelected; @@ -40,7 +41,10 @@ export default { groupName: String, validationRules: String, isRequired: Boolean, - availableLineItems: [] + availableLineItems: { + type: Array, + default: () => [] + } }, emits: ['vapsItemsSelected'], data() { @@ -212,51 +216,15 @@ export default { return vapsPrice; }, selectDefaultPackage() { - const vapsFromStore = store.order.lineItems.vaps; - let lowestTierForPackage = packageNames.TIER_ONE; - if (vapsFromStore?.length > 0) { - vapsFromStore.every((vapsItem) => { - const lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem); - if (lowestTierForThisItem === packageNames.TIER_THREE) { - lowestTierForPackage = packageNames.TIER_THREE; - return false; - } if (lowestTierForThisItem === packageNames.TIER_TWO) { - lowestTierForPackage = packageNames.TIER_TWO; - return true; - } - return true; - }); - } - this.selectedPackageName = lowestTierForPackage; - }, - - getLowestTierForThisItem(vapsItem) { - let lowestTierForThisItem = null; - switch (vapsItem.partType) { - case partTypeStrings.FRONT_WIPER: - if (this.frontWipersApplicableForTierThree) { - lowestTierForThisItem = packageNames.TIER_THREE; - } - if (this.frontWipersApplicableForTierTwo) { - lowestTierForThisItem = packageNames.TIER_TWO; - } - break; - case partTypeStrings.REAR_WIPER: - if (this.rearWiperApplicableForTierThree) { - lowestTierForThisItem = packageNames.TIER_THREE; - } - if (this.rearWiperApplicableForTierTwo) { - lowestTierForThisItem = packageNames.TIER_TWO; - } - break; - case partTypeStrings.RAIN_DEFENSE: - if (this.rainDefenseApplicableForTierThree) { - lowestTierForThisItem = packageNames.TIER_THREE; - } - break; - default: - } - return lowestTierForThisItem; + const { glassToReplace, isRepair } = store.order.damage; + const { vaps } = store.order.lineItems; + const defaultTier = getHighestFullySatisfiedTier( + glassToReplace ?? [], + this.availableLineItems, + isRepair, + vaps ?? [] + ); + this.selectedPackageName = defaultTier; }, getVapsLineItemsForSelectedPackage(packageName) { const vapsLineItemsForSelectedPackage = []; diff --git a/src/layouts/service-packages/service-packages.vue b/src/layouts/service-packages/service-packages.vue index f0a9b527..0849ef35 100644 --- a/src/layouts/service-packages/service-packages.vue +++ b/src/layouts/service-packages/service-packages.vue @@ -3,7 +3,7 @@ ref="theForm" v-slot="{ meta }" @submit="onSubmit" - @invalid-submit="onInvalidSubmit"> + @invalidSubmit="onInvalidSubmit">
@@ -50,8 +50,8 @@ ref="RearWiperModal" cmsWidgetName="RearWiperModal" /> + ref="RecalModal" + cmsWidgetName="RecalModal" />
@@ -72,7 +72,6 @@ import allGlassPartsAndItemsHavePrices from '@/layouts/service-packages/service- import globalRules from '@/constants/global-rules'; import servicePackageQuestion from '@/layouts/service-packages/service-package-question/service-package-question.vue'; import issPageValues from '@/router/router-constants/issPage-values'; -import bailoutCode from '@/constants/bailoutCode'; import bailoutMessage from '@/constants/bailoutMessage'; const store = useMainStore(); @@ -143,9 +142,7 @@ export default { if (!hasBailedOut) { next((vm) => { vm.setCmsContent(resultMap.cmsContent); - vm.pricedGlassParts = clonedGlassParts; - vm.supportingItems = resultMap.supportingItems; - vm.availableLineItems = pricingResults; + vm.setData(clonedGlassParts, resultMap.supportingItems, pricingResults); }); } }, @@ -185,6 +182,11 @@ export default { && store.order.lineItems.glassParts.length > 0)) ); }, + setData(clonedGlassParts, supportingItems, pricingResults) { + this.pricedGlassParts = clonedGlassParts; + this.supportingItems = supportingItems; + this.availableLineItems = pricingResults; + }, vapsItemsSelectedAction(vapsItemsSelected) { this.selectedVaps = vapsItemsSelected; }, From 54310b95c4dca3529f3ab1dd4a1556a3f411eaa1 Mon Sep 17 00:00:00 2001 From: Michaela Brydon Date: Thu, 11 Jul 2024 13:17:08 -0400 Subject: [PATCH 09/11] Adding router test --- src/router/index.js | 1 - src/router/router.spec.js | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/router/index.js b/src/router/index.js index 7a0c2097..53dfb91f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -195,7 +195,6 @@ router.navigateWithoutSaving = ( optionalParams = {}, optionalPageData = {} ) => { - // TODO does not save session navigate(scenario, currentRoute, optionalQuery, optionalParams, optionalPageData); }; diff --git a/src/router/router.spec.js b/src/router/router.spec.js index adce98dc..c221dbf0 100644 --- a/src/router/router.spec.js +++ b/src/router/router.spec.js @@ -21,4 +21,19 @@ describe('Router', () => { router.navigate(scenario, currentRoute); expect(router.push.mock.calls[0][0].query.issPage).toBe(issPageValues.POLICY_HOLDER_DETAILS); }); + + it('Should set state as expected', () => { + // Arrange + const scenario = navigationScenarios.CLICKED_FORWARD; + const currentRoute = { query: { issPage: issPageValues.WELCOME_PAGE } }; + const parameters = {saveSync: true}; + + router.push = jest.fn(); + + // Act + router.navigate(scenario, currentRoute, {}, parameters); + + // Assert + expect(router.push.mock.calls[0][0].state).toBe(parameters); + }); }); From f501601c02903f2c939e3e151920dbfb31e72f7d Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 11 Jul 2024 13:36:09 -0400 Subject: [PATCH 10/11] Change setupModalLinks to setupModalLink for specific ones When variable gets blown away so does the listener. Add back in inside watch similar to other modalLinks --- src/layouts/coverage-statement/coverage-statement.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index a38ffa88..96890713 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -109,6 +109,7 @@ import textBlock from '@/digital-components/text-block/text-block.vue'; // Import Supporting Files import { fetchCmsContentForPage, + setupModalLink, setupModalLinks, processIfStatements } from '@/helpers/cms-content-helper.js'; @@ -335,8 +336,13 @@ export default { }, nextStepsBody(newValue, oldValue) { if (newValue !== oldValue) { - setupModalLinks(this, 'RecalModal'); - setupModalLinks(this, 'DeductibleModal'); + setupModalLink(this, 'RecalModal'); + setupModalLink(this, 'DeductibleModal'); + } + }, + verifiedItacAlertBody(newValue, oldValue) { + if (newValue !== oldValue) { + setupModalLink(this, 'DeductibleModal'); } } }, From a9c9956441f0acd462e2e442cfa4933cd16228f8 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Fri, 12 Jul 2024 11:11:15 -0500 Subject: [PATCH 11/11] Update Vehicle API endpoints for FMG changes --- src/constants/endpoints.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 6562047f..6846a87c 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -141,11 +141,11 @@ const endpoints = Object.freeze({ method: 'POST' }, LookupVinByAddress: { - url: `${VEHICLE_BASE_URL}/lookup-vin-by-address`, + url: `${VEHICLE_BASE_URL}/lookup-by-address`, method: 'POST' }, LookupVinByPlate: { - url: `${VEHICLE_BASE_URL}/lookup-vin-by-plate`, + url: `${VEHICLE_BASE_URL}/lookup-by-plate`, method: 'POST' }, InitializeSession: {