Merge pull request #303 from Safelite/feature/CSR-98

Feature/csr 98
This commit is contained in:
katieoh-safelite 2022-03-25 11:40:31 -04:00 committed by GitHub
commit 856060faa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 280 additions and 460 deletions

View file

@ -14,7 +14,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="container-fluid fixed-bottom g-4 bg-light py-4" id="infoBox"> <div class="container-fluid fixed-bottom g-5 bg-light py-4" id="infoBox">
<div class="row d-flex flex-row-reverse align-items-center"> <div class="row d-flex flex-row-reverse align-items-center">
<div class="col button-col d-flex" id="stacked"> <div class="col button-col d-flex" id="stacked">
<buttonMain <buttonMain

View file

@ -5,4 +5,5 @@ const applicationConfig = {
SAVED_SESSION_TIMEOUT: 45 SAVED_SESSION_TIMEOUT: 45
}; };
export { applicationConfig }; export { applicationConfig };

View file

@ -5,14 +5,8 @@ import httpStatusCodes from "http-status-codes";
export default { export default {
callHttpClient({ method, endpoint, payload }) { callHttpClient({ method, endpoint, payload }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// TODO CSR-98 TEMP FOR TESTING const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL;
var apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL;
if (endpoint.includes("order")) {
apiGatewayUrl = "https://localhost:44346";
}
// const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL;
const payloadAndAnalyticsData = Object.assign({}, payload, { const payloadAndAnalyticsData = Object.assign({}, payload, {
AppName: "FixMyGlass", AppName: "FixMyGlass",
}); });

View file

@ -1,3 +1,4 @@
import * as self from "./heritage-integration-helper";
import { storeActions } from "@/constants/store-actions.js"; import { storeActions } from "@/constants/store-actions.js";
import { cookieNames } from "@/constants/cookie-names"; import { cookieNames } from "@/constants/cookie-names";
import { queryStrings } from "@/constants/query-strings"; import { queryStrings } from "@/constants/query-strings";
@ -36,7 +37,7 @@ export async function saveOrder() {
*/ */
export async function loadOrderIfPresent() { export async function loadOrderIfPresent() {
console.log("attempting to load referral...."); console.log("attempting to load referral....");
const conceptCookie = getConceptCookie(); const conceptCookie = self.getConceptCookie();
// Do nothing if there is no cookie or no correlation id. // Do nothing if there is no cookie or no correlation id.
if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) {
@ -177,18 +178,18 @@ export function isSavedSessionStillActive() {
/* /*
Used to navigate to the heritage funnel with the correct query string and url. Used to navigate to the heritage funnel with the correct query string and url.
*/ */
export async function navigateToHeritageFunnel() { export async function navigateToHeritageFunnel() {
// Create the order (or save existing order) when navigating to Heritage Funnel. // Create the order (or save existing order) when navigating to Heritage Funnel.
await saveOrder(); // console.log(exports)
await self.saveOrder();
router.navigateToExternalUrl( router.navigateToExternalUrl(
externalUrls.HERITAGE_FUNNEL, externalUrls.HERITAGE_FUNNEL,
{ {
corid: store.getters.order.referralCorrelationId, corid: store.getters.order.referralCorrelationId,
src: "concept-funnel", src: "concept-funnel"
cns: "all",
experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true"
} }
); );
} }
@ -264,8 +265,6 @@ function setConceptCookieProperties(properties) {
Removes concept cookie from browser. Removes concept cookie from browser.
*/ */
function deleteConceptCookie() { function deleteConceptCookie() {
// If this cookie is ever created from the concept funnel, will need to add another
// line with the path=/fmg/
document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`;
} }

View file

@ -4,73 +4,86 @@ import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js";
import { storeActions } from "@/constants/store-actions"; import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations"; import { storeMutations } from "@/constants/store-mutations";
import store from "@/store"; import store from "@/store";
import router from "@/router";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
import baseMixin from "@/mixins/base-mixin";
import { externalUrls } from "@/router/router-constants/externalUrl-values";
describe("loadOrderIfPresent", () => {
afterEach(() => {
removeAllTestCookies();
});
test("ShouldResetState == true => concept cookie is deleted", () => {
// Arrange
const testShouldResetState = true;
const testCookieValue = {
ShouldResetState: testShouldResetState
}
document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=${location.hostname}`;
// Act
helper.loadOrderIfPresent();
// Assert
expect(document.cookie).toBe("");
});
test("ShouldResetState == true => reset store", () => {
// Arrange
const getConceptCookieMethod = jest.spyOn(helper, "getConceptCookie")
getConceptCookieMethod.mockImplementation(() => { return { ShouldResetState: true, DidHeritageFunnelUpdateLast: false } });
const mockData = {
actionList: [{
actionName: storeActions.RESET_STATE
}],
}
setupMocksForJsFiles(mockData);
// Act
helper.loadOrderIfPresent();
// Assert
expect(getConceptCookieMethod).toHaveBeenCalled();
expect(baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE);
getConceptCookieMethod.mockRestore();
});
test("Concept cookie is null => store is unchanged", () => {
// Arrange
const getConceptCookieMethod = jest.spyOn(helper, "getConceptCookie")
getConceptCookieMethod.mockImplementation(() => null);
store.dispatch = jest.spyOn(store, "dispatch");
const mockData = {
actionList: [{
actionName: storeActions.RESET_STATE
}],
}
setupMocksForJsFiles(mockData);
// Act
helper.loadOrderIfPresent();
// Assert
expect(helper.getConceptCookie).toHaveBeenCalled();
expect(store.dispatch).not.toHaveBeenCalledWith(storeActions.RESET_STATE);
getConceptCookieMethod.mockRestore();
});
});
describe("saveOrder", () => { describe("saveOrder", () => {
afterEach(() => {
// afterEach(() => { removeAllTestCookies();
// removeAllTestCookies(); });
// });
function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate ) {
return {
referralNumber: mockReferralNumber,
referralCorrelationId: mockCorrelationId,
referralDate: mockReferralDate
}
}
describe("loadOrderIfPresent", () => {
// test("ShouldResetState == true => heritage cookie is deleted", () => {
// // Arrange
// // TODO CSR-98 Can we not mock this??
// const testShouldResetState = true;
// const testCookieValue = {
// ShouldResetState: testShouldResetState
// }
// console.log(cookieNames.CONCEPT_SESSION_INFO);
// console.log(testCookieValue)
// console.log(JSON.stringify(testCookieValue));
// console.log(location.hostname)
// let myString = `${cookieNames.CONCEPT_SESSION_INFO}=${JSON.stringify(testCookieValue)};domain=${location.hostname};path=/;`;
// console.log(myString)
// document.cookie = 'OrderInfo={"Hahahah":true};domain=localhost;path=/;';
// console.log(document.cookie)
// document.cookie = "Ahhh=AHHH;"
// document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; domain=${location.hostname};`;
// console.log(document.cookie)
// // Act
// helper.loadOrderIfPresent();
// // Assert
// console.log(document.cookie)
// // expect(document.cookie).toBe();
// });
// test("ShouldResetState == true => reset store", () => {
// // Arrange
// helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false);
// // Act
// helper.loadOrderIfPresent();
// // Assert
// expect(helper.getHeritageCookieValue).toHaveBeenCalled();
// });
// test("Heritage cookie is null => store is unchanged", () => {
// // Arrange
// helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true);
// // Act
// helper.loadOrderIfPresent();
// // Assert
// expect(helper.getHeritageCookieValue).toHaveBeenCalled();
// });
});
test("saveOrder => should set state order values", async () => { test("saveOrder => should set state order values", async () => {
// Arrange // Arrange
@ -79,71 +92,142 @@ describe("saveOrder", () => {
const mockReferralDate = "2022"; const mockReferralDate = "2022";
const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate);
const mockData = { const mockData = {
actionList: [{ actionList: [
actionName: storeActions.SAVE_ORDER, {
data: mockOrderInfo, actionName: storeActions.SAVE_ORDER,
}], data: mockOrderInfo,
},
{
actionName: storeActions.SET_REFERRAL_INFORMATION
}
]
} }
setupMocksForJsFiles(mockData); const mocks = setupMocksForJsFiles(mockData);
// Act // Act
await helper.saveOrder(); await helper.saveOrder();
// Assert // Assert
expect(store.commit).toHaveBeenCalledTimes(3); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SAVE_ORDER);
expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_NUMBER, mockReferralNumber); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SET_REFERRAL_INFORMATION, {
expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, mockCorrelationId); referralNumber: mockReferralNumber,
expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_DATE, mockReferralDate); referralDate: mockReferralDate,
referralCorrelationId: mockCorrelationId
}, false);
}); });
// test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value", async () => { test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => {
// // Arrange // Arrange
// const mockReferralNumber = 2; const testReferralNumber = 1566818;
// const mockCorrelationId = "55"; const testReferralDate = "2022-03-15T10:56:24.597";
// const mockReferralDate = "2022"; const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060";
// const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); const mockOrderInfo = getMockOrderInfo(testReferralNumber, testReferralCorrelationId, testReferralDate);
// const mockData = {
// actionList: [{
// actionName: storeActions.SAVE_ORDER,
// data: mockOrderInfo,
// }],
// }
// setupMocksForJsFiles(mockData);
// // Act
// await helper.saveOrder();
// // Assert const mockData = {
actionList: [{
// }); actionName: storeActions.SAVE_ORDER,
data: mockOrderInfo,
}],
router: router
}
setupMocksForJsFiles(mockData);
const testCookieValue = {
ReferralNumber: testReferralNumber,
ReferralDate: testReferralDate,
ReferralCorrelationId: testReferralCorrelationId,
ShouldResetState: false,
DidHeritageFunnelUpdateLast: true
}
setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) });
// Act
await helper.saveOrder();
// Assert
expect(helper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false);
});
}); });
describe("navigateToHeritageFunnel", () => { describe("navigateToHeritageFunnel", () => {
test("should go to external link", () => { test("should save order", async () => {
// Arrange // Arrange
const mockReferralNumber = 2;
const mockCorrelationId = "55";
const mockReferralDate = "2022";
const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate);
const mockData = {
actionList: [{
actionName: storeActions.SAVE_ORDER,
data: mockOrderInfo,
}]
}
setupMocksForJsFiles(mockData);
const saveOrderFunction = jest.spyOn(helper, "saveOrder");
router.navigateToExternalUrl = jest.fn();
// Act // Act
helper.navigateToHeritageFunnel(); await helper.navigateToHeritageFunnel();
// Assert // Assert
expect(router.navigate).toHaveBeenCalled(); expect(saveOrderFunction).toHaveBeenCalled();
expect(window.location.assign).toHaveBeenCalled();
}) // Should alway save before we navigate to heritage
const saveOrderFunctionCallOrder = saveOrderFunction.mock.invocationCallOrder[0];
const routerNavigateFunctionCallOrder = router.navigateToExternalUrl.mock.invocationCallOrder[0];
expect(saveOrderFunctionCallOrder).toBeLessThan(routerNavigateFunctionCallOrder);
saveOrderFunction.mockRestore();
});
test("should go to heritage funnel", async () => {
// Arrange
const mockReferralNumber = 2;
const mockCorrelationId = "55";
const mockReferralDate = "2022";
const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate);
const mockData = {
actionList: [{
actionName: storeActions.SAVE_ORDER,
data: mockOrderInfo,
}]
}
setupMocksForJsFiles(mockData);
store.getters.order.referralCorrelationId = mockCorrelationId
router.navigateToExternalUrl = jest.fn();
// Act
await helper.navigateToHeritageFunnel();
// Assert
expect(router.navigateToExternalUrl).toHaveBeenCalled();
expect(router.navigateToExternalUrl).toHaveBeenCalledWith(externalUrls.HERITAGE_FUNNEL,
expect.objectContaining({
corid: mockCorrelationId
})
);
});
}); });
// TODO CSR-98 Remove skip describe("cookies", () => {
describe.skip("cookies", () => {
afterEach(() => { afterEach(() => {
removeAllTestCookies(); removeAllTestCookies();
}) })
describe("getHeritageCookieValue method", () => { describe("getConceptCookie method", () => {
test("gets correct value when cookie is present", () => { test("gets correct value when cookie is present", () => {
// Arrange // Arrange
const testReferralNumber = 1566818; const testReferralNumber = 1566818;
@ -159,10 +243,10 @@ describe.skip("cookies", () => {
ShouldResetState: testShouldResetState, ShouldResetState: testShouldResetState,
DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast
} }
setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) });
// Act // Act
var result = helper.getHeritageCookieValue(); var result = helper.getConceptCookie();
// Assert // Assert
expect(result).toEqual(testCookieValue); expect(result).toEqual(testCookieValue);
@ -172,44 +256,68 @@ describe.skip("cookies", () => {
expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId); expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId);
expect(result.ShouldResetState).toEqual(testShouldResetState); expect(result.ShouldResetState).toEqual(testShouldResetState);
expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast); expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast);
}) });
test("returns empty object when value is empty object", () => { test("returns empty object when value is empty object", () => {
// Arrange // Arrange
const testCookieValue = {}; const testCookieValue = {};
setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) });
// Act // Act
var result = helper.getHeritageCookieValue(); var result = helper.getConceptCookie();
// Assert // Assert
expect(result).toEqual(testCookieValue); expect(result).toEqual(testCookieValue);
expect(typeof result).toEqual("object"); expect(typeof result).toEqual("object");
expect(Object.keys(result)).toHaveLength(0); expect(Object.keys(result)).toHaveLength(0);
}) });
test("returns null when value is empty string", () => { test("returns null when value is empty string", () => {
// Arrange // Arrange
const testCookieValue = ""; const testCookieValue = "";
setupCookies({ heritageCookieValue: testCookieValue }); setupCookies({ conceptCookieValue: testCookieValue });
// Act // Act
var result = helper.getHeritageCookieValue(); var result = helper.getConceptCookie();
// Assert // Assert
expect(result).toEqual(null); expect(result).toEqual(null);
}) });
test("returns null when heritage cookie doesn't exist", () => { test("returns null when concept cookie doesn't exist", () => {
// Arrange // Arrange
setupCookies({ includeHeritageCookie: false }); setupCookies({ includeHeritageCookie: false });
// Act // Act
var result = helper.getHeritageCookieValue(); var result = helper.getConceptCookie();
// Assert // Assert
expect(result).toEqual(null); expect(result).toEqual(null);
}) });
test("gets correct cookie value", () => {
// Arrange
const testCookieValue = { test: "testValue" };
setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) });
// Act
const actualCookieValue = helper.getConceptCookie();
// Assert
expect(actualCookieValue).toEqual(testCookieValue);
});
test("getCookieValue: Gets null cookie value", () => {
// Arrange
setupCookies({ includeHeritageCookie: false });
// Act
const actualCookieValue = helper.getConceptCookie();
// Assert
expect(actualCookieValue).toBeNull();
});
}) })
}) })
@ -224,59 +332,26 @@ const cookies = {
"addshoppers.com": "2%7C1%3A0%7C10%3A1646681050%7C15%3Aaddshoppers.com%7C44%3AODM1OTczNWI0MmFjNGNmMmExNDY3OWRlNTQ1NmM5MGY%3D%7Cef2a50fafe40fc5abf641a14ee5541c70bef2950666f59d3a809fd9352c7b963" "addshoppers.com": "2%7C1%3A0%7C10%3A1646681050%7C15%3Aaddshoppers.com%7C44%3AODM1OTczNWI0MmFjNGNmMmExNDY3OWRlNTQ1NmM5MGY%3D%7Cef2a50fafe40fc5abf641a14ee5541c70bef2950666f59d3a809fd9352c7b963"
}; };
function setupCookies({ heritageCookieValue = "", includeHeritageCookie = true }) { function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) {
console.log(heritageCookieValue)
Object.keys(cookies).forEach(key => { Object.keys(cookies).forEach(key => {
const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? heritageCookieValue : cookies[key]; const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key];
if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO)
document.cookie = `${key}=${cookieValue}`; document.cookie = `${key}=${cookieValue}; path=/;`;
}); });
} }
function removeAllTestCookies() { function removeAllTestCookies() {
Object.keys(cookies).forEach(key => { Object.keys(cookies).forEach(key => {
document.cookie = `${key}=;Max-Age=0;`; document.cookie = `${key}=;Max-Age=0;`;
document.cookie = `${key}=;Max-Age=0;path=/`;
}); });
} }
// test("getCookieValue: Gets correct cookie value", () => {
// // Arrange
// const mixIn = getMixInInstance({});
// const testCookieName = "testCookie";
// const testCookieValue = "testCookieValue";
// document.cookie = `yearMakeModel=2020 ACURA MDX;`; function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) {
// document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`; return {
// document.cookie = `${testCookieName}=${testCookieValue};`; referralNumber: mockReferralNumber,
// document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`; referralCorrelationId: mockCorrelationId,
// document.cookie = `orderconfirmation=7411543;`; referralDate: mockReferralDate
}
// console.log(document.cookie) }
// // Act
// const actualCookieValue = mixIn.methods.getCookieValue(testCookieName);
// // Assert
// expect(actualCookieValue).toEqual(testCookieValue);
// expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; ${testCookieName}=${testCookieValue}; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543`);
// clearCookies();
// });
// test("getCookieValue: Gets undefined cookie value", () => {
// // Arrange
// const mixIn = getMixInInstance({});
// const testCookieName = "testCookie";
// document.cookie = `yearMakeModel=2020 ACURA MDX;`;
// document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`;
// document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`;
// document.cookie = `orderconfirmation=7411543;`;
// // Act
// const actualCookieValue = mixIn.methods.getCookieValue(testCookieName);
// // Assert
// expect(actualCookieValue).toEqual(undefined);
// expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543;`);
// });

View file

@ -4,29 +4,14 @@ import { navigationScenarios } from "@/router/router-constants/navigation-scenar
import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import baseMixin from "@/mixins/base-mixin"; import baseMixin from "@/mixins/base-mixin";
import store from "@/store";
export function getMountOptions(mockData) { export function getMountOptions(mockData) {
// Define our mocks to attached to the 'global' object for Vue/Jest. // Define our mocks to attached to the 'global' object for Vue/Jest.
const mocks = {}; const mocks = {};
//this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction
if (mockData.actionList !== undefined) { setupBaseMixinDispatchNonBlockingStoreAction(mockData);
// baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
// baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => {
// let actionFilterResult = mockData.actionList.filter(
// (x) => x.actionName == actionName
// );
// if (actionFilterResult.length > 0 && actionFilterResult.length === 1) {
// return Promise.resolve({
// data: actionFilterResult[0].data,
// });
// }
// });
setupDispatchNonBlockingStoreAction(mockData);
}
mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction = jest.fn();
mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => {
let actionFilterResult = mockData.actionList.filter( let actionFilterResult = mockData.actionList.filter(
@ -59,23 +44,25 @@ export function getMountOptions(mockData) {
return { global }; return { global };
} }
function setupDispatchNonBlockingStoreAction(mockData) { function setupBaseMixinDispatchNonBlockingStoreAction(mockData) {
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); if (mockData.actionList !== undefined) {
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
let actionFilterResult = mockData.actionList.filter( baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => {
(x) => x.actionName == actionName let actionFilterResult = mockData.actionList.filter(
); (x) => x.actionName == actionName
);
if (actionFilterResult.length > 0 && actionFilterResult.length === 1) {
return Promise.resolve({ if (actionFilterResult.length > 0 && actionFilterResult.length === 1) {
data: actionFilterResult[0].data, return Promise.resolve({
}); data: actionFilterResult[0].data,
} });
}); }
});
}
} }
export function setupMocksForJsFiles(mockData) { export function setupMocksForJsFiles(mockData = {}) {
setupDispatchNonBlockingStoreAction(mockData); setupBaseMixinDispatchNonBlockingStoreAction(mockData);
store.commit = jest.fn();
router.navigate = jest.fn(); return { baseMixin };
} }

View file

@ -193,7 +193,7 @@ describe("vehicle-parts.vue", () => {
test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => { test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => {
//Arrange //Arrange
store.getters.pageData.mockReturnValueOnce(basePartResponse); store.getters.pageData.mockReturnValue(basePartResponse);
store.getters.lineItems = { glassParts: {} } store.getters.lineItems = { glassParts: {} }
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({

View file

@ -154,8 +154,9 @@ export default {
methods: { methods: {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
// Check if isRepair is populated and if the pageData we need is here (Parts data) // Check if isRepair is populated and if the pageData we need is here (Parts data)
console.log(store.getters.pageData(fmgPageValues.VEHICLE_PARTS))
if ( if (
(store.getters.damage.isRepair) && (store.getters.damage.isRepair != null) &&
Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS))
.length !== 0 .length !== 0
) { ) {

View file

@ -1,167 +1 @@
// Components test.todo("some test to be written in the future");
import vinLookup from "@/layouts/vin-lookup/vin-lookup.vue";
import vehicleDamage from "@/layouts/vehicle-damage/vehicle-damage.vue";
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options";
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
// Supporting Files
import { settleAllPromises } from "@/helpers/layout-helper.js";
import baseMixin from "@/mixins/base-mixin";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { mount, flushPromises } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
import { validate } from "vee-validate";
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(),
}));
// Mock Store
jest.mock("@/store", () => ({
commit: jest.fn(),
dispatch: jest.fn(),
getters: {
vehicle: {
carId: "C00000000",
image: "test.jpg",
},
eventBusItem: jest.fn(),
damage: {
glassToReplace: []
},
},
}));
describe("vin-lookup.vue", () => {
test("Call resetDependentState", async() => {
const {wrapper} = setupMocks({});
wrapper.vm.resetDependentState();
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
});
});
// TEMP
function setupMocks({
pageHeaderWidgetHeaderText = {},
mountOptionsMockData = {
router: {
navigate: jest.fn(),
},
store: {
getters: {
vehicle: {},
},
},
},
}) {
//Mock api responses
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
GenericVehicleImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
},
FunnelHeaderWidget: {
LogoImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
},
},
damageOptions: {
driverSideOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
passengerSideOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
windshieldOptions: {
availableReplacementOptions: ["Single", "Driver", "Passenger"],
},
backGlassOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
},
};
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
//Mock damage initialize methods
funnelHeader.methods = {
initializeComponent: jest.fn(),
};
vehicleBanner.methods = {
initializeComponent: jest.fn(),
};
funnelSubHeader.methods = {
initializeComponent: jest.fn(),
};
damageLocationQuestion.methods = {
initializeComponent: jest.fn(),
};
sideDoorOptions.methods = {
initializeComponent: jest.fn(),
};
windshieldOptions.methods = {
initializeComponent: jest.fn(),
};
replaceOptionsQuestion.methods = {
initializeComponent: jest.fn(),
updateSelectedValues: jest.fn(),
};
funnelFooter.methods = {
initializeComponent: jest.fn(),
}
const mountOptions = getMountOptions(mountOptionsMockData);
mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
const wrapper = mount(vinLookup, mountOptions);
const funnelHeaderWrapper = wrapper.findComponent({ name: "funnelHeader" });
funnelHeaderWrapper.vm.initializeComponent =
funnelHeader.methods.initializeComponent;
const vehicleBannerWrapper = wrapper.findComponent({ name: "vehicleBanner" });
vehicleBannerWrapper.vm.initializeComponent =
vehicleBanner.methods.initializeComponent;
const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader" });
funnelSubHeaderWrapper.vm.initializeComponent =
funnelSubHeader.methods.initializeComponent;
const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter" });
funnelFooterWrapper.vm.initializeComponent =
funnelFooter.methods.initializeComponent;
return { wrapper, apiPromise };
}

View file

@ -1,23 +1,17 @@
<template> <template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall"> <div class="container-fluid shadow rounded-3 px-5 position-relative make-tall">
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" />
<funnelSubHeader ref="funnelSubHeader" /> <funnelSubHeader ref="funnelSubHeader" />
<h1>VIN Lookup Placeholder Page</h1> <vinInformation
<Form class="mb-5"
@submit="onSubmit" />
@invalid-submit="onInvalidSubmit"
ref="theForm"
v-slot="{ meta }"
class="d-flex flex-column h-100"
>
<funnel-footer <funnel-footer
ref="funnelFooter" ref="funnelFooter"
:isDisabled="!meta.valid" :isDisabled="!meta.valid"
@back-clicked="backButtonAction" @back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
/> />
</Form>
</div> </div>
</template> </template>
@ -27,83 +21,17 @@ import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
// Supporting files import vinInformation from "@/layouts/vin-lookup/vin-information/vin-information";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import { storeMutations } from "@/constants/store-mutations";
import baseMixin from "@/mixins/base-mixin";
import { Form, defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
// DEFINE VALIDATION RULES
defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED));
export default { export default {
name: "vin-lookup", name: "vin-lookup",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
const damageOptionsPromise =
baseMixin.methods.dispatchNonBlockingStoreAction(
storeActions.GET_DAMAGE_OPTIONS,
{ carId: store.getters.vehicle.carId }
);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
{
resultKey: "damageOptions",
promise: damageOptionsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.$refs.funnelHeader.initializeComponent(
resultMap.cmsContent.FunnelHeaderWidget
);
vm.$refs.vehicleBanner.initializeComponent(
resultMap.cmsContent.VehicleBannerWidget
);
vm.$refs.funnelSubHeader.initializeComponent(
resultMap.cmsContent.FunnelSubHeaderWidget
);
vm.$refs.funnelFooter.initializeComponent(
resultMap.cmsContent.FunnelFooterWidget
);
});
},
methods: {
arePagePrerequisitesValid() {
return true;
},
resetDependentState() {
store.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
},
backButtonAction() {
// route to move backwards
this.$router.navigate(
this.navigationScenarios.CLICKED_BACK,
this.$route
);
},
},
components: { components: {
funnelHeader, funnelHeader,
vehicleBanner, vehicleBanner,
funnelSubHeader, funnelSubHeader,
vinInformation,
funnelFooter, funnelFooter,
Form,
}, },
}; };
</script> </script>

View file

@ -1,5 +1,5 @@
const externalUrls = { const externalUrls = {
HERITAGE_FUNNEL: process.env.VUE_APP_HERITAGE_FUNNEL, HERITAGE_FUNNEL: process.env.VUE_APP_HERITAGE_FUNNEL,
}; };
export { externalUrls }; export { externalUrls };

View file

@ -1,5 +1,6 @@
import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
import { applicationConfig } from "@/constants/application-config";
const routingTable = [ const routingTable = [
{ {