diff --git a/src/helpers/order-helper.js b/src/helpers/order-helper.js index cbc5c890..449f79b6 100644 --- a/src/helpers/order-helper.js +++ b/src/helpers/order-helper.js @@ -24,7 +24,8 @@ export async function saveSession({ shouldAwaitSaveSessionQueue = false, submitA store.setSaveSessionPromise(saveSessionPromise); - if (!store.applicationUser.savedSessionId || shouldAwaitSaveSessionQueue) { + // This should await anytime the referral number is not set, or the shouldAwaitSaveSessionQueue is set to true. + if (!store.order.referralNumber || shouldAwaitSaveSessionQueue) { await saveSessionPromise; } } diff --git a/src/layouts/entry-page/entry-page.vue b/src/layouts/entry-page/entry-page.vue index bdbe78ae..e4f73f17 100644 --- a/src/layouts/entry-page/entry-page.vue +++ b/src/layouts/entry-page/entry-page.vue @@ -13,9 +13,9 @@ import { validateISSClientTag, validateISSClientSignature } from '@/helpers/clie import { getISSCookie, updateOrCreateISSCookie } from '@/helpers/cookie-helper.js'; import { useMainStore } from '@/store'; import showIssLoadingModal from '@/helpers/loading-modal-helper'; -import applicationConfig from '@/constants/application-config'; import { toPossessive } from '@/helpers/text-helper'; import analyticsMixin from '@/mixins/analytics-mixin'; +import routerParams from '@/router/router-constants/router-params'; export default { name: 'entry-page', @@ -80,23 +80,19 @@ export default { } this.mainStore.applicationUser.coverageAttempts = 0; - if ( - applicationConfig.CURRENT_ENVIRONMENT === 'Localhost' - || applicationConfig.CURRENT_ENVIRONMENT === 'Dev' - || applicationConfig.CURRENT_ENVIRONMENT === 'SysTest' - ) { - this.navigateForward(); - } else { - // Forced full location redirect here. We do not want the entry page as part of the router/flow/path history. - window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`; - } + + // Forced full location redirect here. We do not want the entry page as part of the router/flow/path history. + window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`; }, methods: { navigateForward() { + // If we use navigateForward we need to skip saving session (creating referral). this.$router.navigate( this.navigationScenarios.MOVE_FORWARD_ENTRY_PAGE, - this.$route + this.$route, + {}, + { [routerParams.SKIP_SAVE_SESSION]: true } ); }, parseQueryParms() { diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 92ddeab2..38b35558 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -371,7 +371,6 @@ export default { } } - await saveSession({ shouldAwaitSaveSessionQueue: true, bailoutOnError: true }) this.navigateForward(); }, async configureZip() { @@ -388,6 +387,7 @@ export default { navigateForward() { if ((this.mainStore.applicationUser.duplicateOrders?.length > 0 ?? false) && !this.answeredContinueModal) { + // Duplicate orders found; navigating to duplicate check page and skipping save session. this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, this.$route, diff --git a/src/router/index.js b/src/router/index.js index 1fbe148f..0c33cae4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -46,6 +46,7 @@ const routes = [ if (getISSCookie() !== null && !isSavedSessionStillActive()) { // await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); await GoToStartOn404(next); + return null; } // Process ISS cookie. @@ -66,9 +67,10 @@ const routes = [ if (!arePagePrerequisitesValid(component)) { await GoToStartOn404(next); + return null; } - return next({name: issPageToUse, query: to.query, params: to.params}); + return next({name: issPageToUse, query: to.query, params: to.params, state: to.state}); } var routeData = []; @@ -123,13 +125,15 @@ const routes = [ const tempMsgCopy = 'Pre Requisites failed, need to handle. Default is Welcome Page.'; const tempMsgHeadline = `${issPageToUse}: pre-req failed...`; await GoToStartOn404(next, tempMsgCopy, tempMsgHeadline); + return null; } // Assign current query string parameters, as well as our issPage one. next({ name: routeData[0].name, query: Object.assign(to.query, {issPage: routeData[0].name}), - params: to.params + params: to.params, + state: to.state }); return null; } @@ -196,7 +200,10 @@ router.afterEach(async (to, from) => { await analyticsMixin.methods.validateSession(); - const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; + const skipSaveSession = !!( + to.state?.[routerParams.SKIP_SAVE_SESSION] + ?? router.options.history.state?.[routerParams.SKIP_SAVE_SESSION] + ); if (from.name !== undefined && !skipSaveSession && !store.hasSubmittedOrder()) { await saveSession({ bailoutOnError: from.name === issPageValues.ENTRY_PAGE}); } diff --git a/src/router/router.afterEach.spec.js b/src/router/router.afterEach.spec.js new file mode 100644 index 00000000..2a2185dc --- /dev/null +++ b/src/router/router.afterEach.spec.js @@ -0,0 +1,115 @@ +import issPageValues from '@/router/router-constants/issPage-values'; +import routerParams from '@/router/router-constants/router-params'; + +let router; +let saveSession; +let mockAfterEachHandler; +let mockStore; + +jest.mock('vue-router', () => ({ + createWebHistory: jest.fn(() => ({ state: {} })), + createRouter: jest.fn((options) => ({ + options, + beforeEach: jest.fn(), + afterEach: jest.fn((handler) => { + mockAfterEachHandler = handler; + }), + addRoute: jest.fn(), + getRoutes: jest.fn(() => []), + hasRoute: jest.fn(() => true), + push: jest.fn(), + go: jest.fn(), + currentRoute: { value: { query: { issPage: 'welcomePage' } } } + })) +})); + +jest.mock('@/helpers/order-helper.js', () => ({ + saveSession: jest.fn(() => Promise.resolve()) +})); + +jest.mock('@/mixins/analytics-mixin', () => ({ + __esModule: true, + default: { + methods: { + validateSession: jest.fn(() => Promise.resolve()), + logDigitalConsumer: jest.fn(), + pushIssSessionData: jest.fn(), + pushPageViewToGA: jest.fn(), + pushExperimentsToDataLayer: jest.fn(), + pushOrderToDataLayer: jest.fn() + } + } +})); + +jest.mock('@/store', () => ({ + useMainStore: jest.fn(() => mockStore) +})); + +describe('Router afterEach skipSaveSession', () => { + beforeAll(() => { + router = require('@/router/').default; + ({ saveSession } = require('@/helpers/order-helper.js')); + }); + + beforeEach(() => { + mockStore = { + applicationUser: { triggeredSiteEntry: true }, + runExperimentsForTrigger: jest.fn(() => Promise.resolve()), + updateLastPageVisited: jest.fn(), + clearSaveSessionPromise: jest.fn(), + hasSubmittedOrder: jest.fn(() => false) + }; + + router.options.history.state = {}; + jest.clearAllMocks(); + }); + + it('should skip saveSession when skipSaveSession is true on to.state', async () => { + await mockAfterEachHandler( + { + name: issPageValues.WELCOME_PAGE, + query: { issPage: issPageValues.WELCOME_PAGE }, + state: { [routerParams.SKIP_SAVE_SESSION]: true } + }, + { + name: issPageValues.ENTRY_PAGE, + redirectedFrom: undefined + } + ); + + expect(saveSession).not.toHaveBeenCalled(); + }); + + it('should skip saveSession when skipSaveSession is true on history state', async () => { + router.options.history.state = { [routerParams.SKIP_SAVE_SESSION]: true }; + + await mockAfterEachHandler( + { + name: issPageValues.WELCOME_PAGE, + query: { issPage: issPageValues.WELCOME_PAGE } + }, + { + name: issPageValues.ENTRY_PAGE, + redirectedFrom: undefined + } + ); + + expect(saveSession).not.toHaveBeenCalled(); + }); + + it('should call saveSession when skipSaveSession is not present', async () => { + await mockAfterEachHandler( + { + name: issPageValues.WELCOME_PAGE, + query: { issPage: issPageValues.WELCOME_PAGE } + }, + { + name: issPageValues.ENTRY_PAGE, + redirectedFrom: undefined + } + ); + + expect(saveSession).toHaveBeenCalledTimes(1); + expect(saveSession).toHaveBeenCalledWith({ bailoutOnError: true }); + }); +}); \ No newline at end of file