Merge branch 'develop' into feature/CSR-1088
This commit is contained in:
commit
b74ea28d6a
7 changed files with 444 additions and 18 deletions
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -19150,9 +19150,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
|
||||
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
|
|
@ -39784,9 +39784,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
|
||||
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
|
||||
"dev": true
|
||||
},
|
||||
"query-string": {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const storeActions = {
|
|||
LOAD_SESSION: "loadSession",
|
||||
UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE: "updateStoreWithSaveSessionResponse",
|
||||
VALIDATE_ZIP: "validateZip",
|
||||
PRICE_ORDER_ITEMS: "priceOrderItems",
|
||||
PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "priceOrderItemsAndSaveServerData",
|
||||
LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure",
|
||||
LOG_PAGE_VIEW: "logPageView",
|
||||
LOG_CUSTOM_EVENT: "logCustomEvent",
|
||||
|
|
|
|||
|
|
@ -1,23 +1,20 @@
|
|||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import quote from "@/layouts/quote/quote.vue";
|
||||
import store from "@/store";
|
||||
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { nextTick } from "vue";
|
||||
|
||||
jest.mock("@/store", () => ({
|
||||
commit: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
}));
|
||||
|
||||
// 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(),
|
||||
fetchCmsContentForPage: () => Promise.resolve("content"),
|
||||
}));
|
||||
|
||||
jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({
|
||||
|
|
@ -32,6 +29,38 @@ jest.mock(
|
|||
{ virtual: true }
|
||||
);
|
||||
|
||||
// START beforeRouteEnter mock arranging //
|
||||
jest.mock("@/mixins/base-mixin", () => ({
|
||||
methods: {
|
||||
dispatchStoreAction(action, items, encode) {
|
||||
if (action === mockPriceOrderStoreAction) return items;
|
||||
else return mockStoreActionResults[action];
|
||||
},
|
||||
getTierOnePackagePrice() {
|
||||
return mockTierOnePrice;
|
||||
},
|
||||
filterOutFees() {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
}));
|
||||
let mockTierOnePrice = 501;
|
||||
|
||||
const mockPriceOrderStoreAction = storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA;
|
||||
const mockStoreActionResults = {};
|
||||
|
||||
mockStoreActionResults[storeActions.GET_WIPERS] = Promise.resolve([
|
||||
{ partNumber: "SBB24", partType: "FRONT WIPER" },
|
||||
]);
|
||||
mockStoreActionResults[storeActions.GET_RAIN_DEFENSE] = Promise.resolve({
|
||||
partNumber: "RAIN DEFENSE",
|
||||
partType: "RAIN DEFENSE",
|
||||
});
|
||||
mockStoreActionResults[storeActions.GET_SUPPORTING_ITEMS] = Promise.resolve([
|
||||
{ partNumber: "WSREPAIR", partType: "WSREPAIR" },
|
||||
]);
|
||||
// END beforeRouteEnter mock arranging
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
accountNumber: applicationConfig.CASH_ACCOUNT_NUMBER,
|
||||
|
|
@ -117,6 +146,269 @@ describe("quote.vue", () => {
|
|||
//Assert
|
||||
expect(navigateToHeritage.navigateToHeritageFunnel).toHaveBeenCalled();
|
||||
});
|
||||
test("should pass arePagePrerequisitesValid with a repair order", () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
store.getters = {
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "12345",
|
||||
zipCodeCtu: "value",
|
||||
},
|
||||
damage: {
|
||||
isRepair: true,
|
||||
},
|
||||
referralNumber: "1234567",
|
||||
},
|
||||
};
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(true);
|
||||
});
|
||||
test("should pass arePagePrerequisitesValid with a replace order", () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
store.getters = {
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "12345",
|
||||
zipCodeCtu: "value",
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
},
|
||||
referralNumber: "1234567",
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(true);
|
||||
});
|
||||
test("should fail arePagePrerequisitesValid without glass parts or flagged as repair", () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
store.getters = {
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "12345",
|
||||
zipCodeCtu: "value",
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
},
|
||||
referralNumber: "1234567",
|
||||
},
|
||||
};
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(false);
|
||||
});
|
||||
test("should have non-null values for necessary data members after 'beforeRouteEnter'", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
//mock this to avoid needing to populate this.$route in an unrelated test
|
||||
wrapper.vm.getDefaultIsInsuranceSelectedValue = jest.fn();
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.pricedGlassParts !== null).toBe(true);
|
||||
expect(wrapper.vm.supportingItems !== null).toBe(true);
|
||||
expect(wrapper.vm.availableLineItems !== null).toBe(true);
|
||||
// This should have its own test
|
||||
//expect(vm.isInsuranceSelected !== null).toBe(true);
|
||||
});
|
||||
test("should default to insurance if query param 'isInsurance' is true", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper.vm.$route = { query: { isInsurance: "true" } };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||
});
|
||||
test("should default to cash if query param 'isInsurance' is false", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper.vm.$route = { query: { isInsurance: "false" } };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(false);
|
||||
});
|
||||
test("should default to insurance if insurance selection is saved to store", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Ensure that query param isn't overriding selection
|
||||
wrapper.vm.$route = { query: null };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||
});
|
||||
test("should default to cash if cash selection is saved to store", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Ensure that query param isn't overriding selection
|
||||
wrapper.vm.$route = { query: null };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(false);
|
||||
});
|
||||
test("should default to cash if total economy package price is under $500", async () => {
|
||||
// Also needs no query parameter or previous selection in store to be present
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||
},
|
||||
},
|
||||
};
|
||||
mockTierOnePrice = 200;
|
||||
// Ensure that query param isn't overriding selection
|
||||
wrapper.vm.$route = { query: null };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(false);
|
||||
});
|
||||
test("should default to insurance if total economy package price is over $500", async () => {
|
||||
// Also needs no query parameter or previous selection in store to be present
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
order: {
|
||||
lineItems: {
|
||||
glassParts: ["item", "item2"],
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||
},
|
||||
},
|
||||
};
|
||||
mockTierOnePrice = 505;
|
||||
// Ensure that query param isn't overriding selection
|
||||
wrapper.vm.$route = { query: null };
|
||||
|
||||
//Act
|
||||
await quote.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "quote" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({ customMountOptions }) {
|
||||
|
|
@ -128,5 +420,6 @@ function setupMocks({ customMountOptions }) {
|
|||
mountOptions["attachTo"] = document.body;
|
||||
|
||||
const wrapper = shallowMount(quote, mountOptions);
|
||||
wrapper.vm.setCmsContent = jest.fn();
|
||||
return { wrapper };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export default {
|
|||
];
|
||||
|
||||
const pricingResults = await baseMixin.methods.dispatchStoreAction(
|
||||
storeActions.PRICE_ORDER_ITEMS,
|
||||
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||
availableLineItems,
|
||||
false
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,131 @@
|
|||
describe("service-location.vue", () => {
|
||||
test.todo("test this");
|
||||
// Components
|
||||
import serviceLocation from "@/layouts/service-location/service-location.vue";
|
||||
|
||||
// Supporting files
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper";
|
||||
import baseMixin from "@/mixins/base-mixin";
|
||||
import { nextTick } from "vue";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||
import store from "@/store";
|
||||
|
||||
// Define Mocks
|
||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||
settleAllPromises: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||
fetchCmsContentForPage: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("@/store", () => ({
|
||||
commit: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
getters: {
|
||||
lineItems: {
|
||||
supportingItems: [
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "SUPPLIES-REPAIR",
|
||||
partType: "REPAIR FEE",
|
||||
sellingPrice: 7.99,
|
||||
},
|
||||
],
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "43235",
|
||||
},
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
store.getters = {
|
||||
lineItems: {
|
||||
supportingItems: [
|
||||
{
|
||||
description: null,
|
||||
kitPrice: 0,
|
||||
laborAmount: 0,
|
||||
partNumber: "SUPPLIES-REPAIR",
|
||||
partType: "REPAIR FEE",
|
||||
sellingPrice: 7.99,
|
||||
},
|
||||
],
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "43235",
|
||||
},
|
||||
},
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe("service-location.vue", () => {
|
||||
describe("arePagePrerequisitesValid", () => {
|
||||
test("No prerequisites set: Should return false.", () => {
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters = {
|
||||
lineItems: {
|
||||
supportingItems: null,
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: null,
|
||||
},
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null,
|
||||
},
|
||||
};
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(false);
|
||||
});
|
||||
|
||||
test("All prerequisites set: Should return true.", () => {
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(true);
|
||||
});
|
||||
|
||||
test("Some prerequisites set: Should return false.", () => {
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
store.getters.order.serviceLocation.zipCode = null;
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
expect(arePagePrerequisitesValid).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({ mountOptionsMockData = {} }) {
|
||||
const apiResponses = {};
|
||||
|
||||
const apiPromise = Promise.resolve(apiResponses);
|
||||
|
||||
settleAllPromises.mockImplementation(() => apiPromise);
|
||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||
|
||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||
const wrapper = shallowMount(serviceLocation, mountOptions);
|
||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||
|
||||
return { wrapper, apiPromise };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import { Form } from "vee-validate";
|
|||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
import store from "@/store";
|
||||
|
||||
export default {
|
||||
name: "service-location",
|
||||
|
|
@ -85,7 +86,11 @@ export default {
|
|||
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
return true;
|
||||
return (
|
||||
store.getters.lineItems.supportingItems !== null &&
|
||||
store.getters.order.serviceLocation.zipCode !== null &&
|
||||
store.getters.payment.isInsurance !== null
|
||||
);
|
||||
},
|
||||
getRegistrationAddressFromStore() {
|
||||
return this.$store.getters.vehicle.registration.address;
|
||||
|
|
|
|||
|
|
@ -1423,7 +1423,7 @@ export const actions = {
|
|||
context.commit(storeMutations.UPDATE_VAPS, vaps);
|
||||
},
|
||||
// Price order actions
|
||||
async priceOrderItems(context, { availableLineItems, serviceZipCode, ctu }) {
|
||||
async priceOrderItemsAndSaveServerData(context, { availableLineItems, serviceZipCode, ctu }) {
|
||||
const zipCodeToUse = serviceZipCode
|
||||
? serviceZipCode
|
||||
: context.getters.order.serviceLocation.zipCode;
|
||||
|
|
|
|||
Loading…
Reference in a new issue