From 49347eb4bef6f55f3dc154dab46da1436ce0cc1f Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Wed, 26 Jul 2023 10:30:28 -0400 Subject: [PATCH 1/4] Unit Tests - Initial setup --- .../time-slot-modal-question.spec.js | 487 ++++++++++++++++++ .../time-slot-modal-question.vue | 4 +- 2 files changed, 489 insertions(+), 2 deletions(-) create mode 100644 src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js new file mode 100644 index 000000000..07c81ff0b --- /dev/null +++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js @@ -0,0 +1,487 @@ +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 timeSlotModalQuestion from "@/layouts/schedule/time-slot-modal-question/time-slot-modal-question.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 fetchCmsContentForPage +// jest.mock("@/helpers/cms-content-helper", () => ({ +// fetchCmsContentForPage: () => Promise.resolve("content"), +// })); + +// jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ +// navigateToHeritageFunnel: jest.fn(), +// })); + +// jest.mock( +// "@/store", +// () => { +// return {}; +// }, +// { 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: { + payment: { + insuranceCoverage: {}, + isInsurance: false, + parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, + }, + }, +}; + +afterEach(() => { + // reset store after each test + store.getters = { + order: { + payment: { + parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, + }, + }, + payment: { + insuranceCoverage: {}, + isInsurance: false, + }, + }; +}); + +describe("time-slot-modal-list-button-question.vue", () => { + test.only("IsInsurance false should navigateWithSaving", async () => { + //Arrange + const { wrapper } = setupMocks({ + customMountOptions: { + router: { + navigateWithSaving: jest.fn(), + }, + }, + }); + + store.getters.payment = { + insuranceCoverage: {}, + isInsurance: false, + }; + // wrapper.vm.dispatchStoreAction = jest.fn(() => { + // return { + // data: [], + // }; + // }); + + // wrapper.vm.modal = { + // openModal() { return null}, + // closeModal() {return null}, + // }; + wrapper.vm.dateAndTimeSlotData.timeSlots = [{ + + }]; + wrapper.vm.$refs.timeSlots.closeModal = jest.fn(); + wrapper.vm.selectedTimeSlotId = "testRouteCodeId"; + + //await nextTick(); + + wrapper.vm.setSelectedTimeSlot(); + + //Act + //await wrapper.vm.forwardButtonAction(); + const expectedEmit = + //Assert + expect(wrapper.emitted()["update:modelValue"]).toEqual(expectedEmit); + }); +}); + +// describe("quote.vue", () => { +// test("IsInsurance false should navigateWithSaving", async () => { +// //Arrange +// const { wrapper } = setupMocks({ +// customMountOptions: { +// router: { +// navigateWithSaving: jest.fn(), +// }, +// route: { quote }, +// }, +// }); + +// store.getters.payment = { +// insuranceCoverage: {}, +// isInsurance: false, +// }; + +// wrapper.vm.dispatchStoreAction = jest.fn(() => { +// return { +// data: [], +// }; +// }); + +// wrapper.vm.pricedGlassParts = []; + +// //Act +// await wrapper.vm.forwardButtonAction(); + +// //Assert +// expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); +// }); + +// test("IsInsurance true should navigateToHeritageFunnel", async () => { +// //Arrange +// const { wrapper } = setupMocks({ +// customMountOptions: { +// router: { +// navigateWithSaving: jest.fn(), +// }, +// route: { quote }, +// }, +// }); + +// store.getters.payment = { +// insuranceCoverage: {}, +// isInsurance: true, +// }; + +// wrapper.vm.dispatchStoreAction = jest.fn(() => { +// return { +// data: [], +// }; +// }); + +// wrapper.vm.pricedGlassParts = []; + +// //Act +// await wrapper.vm.forwardButtonAction(); + +// //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", +// }, +// payment: { +// insuranceCoverage: { +// isVerified: false, +// }, +// }, +// }; + +// 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"], +// }, +// }, +// payment: { +// insuranceCoverage: { +// isVerified: false, +// }, +// }, +// }; + +// 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 }) { + const mountOptions = getMountOptions({ + ...customMountOptions, + }); + mountOptions.global.mocks["$store"] = store; + mountOptions["attachTo"] = document.body; + mountOptions.mixins = [{ + methods: { + getCmsContent: jest.fn() + } + }]; + + + const questionText = "Question Text"; + + const wrapper = shallowMount(timeSlotModalQuestion, mountOptions); + wrapper.vm.setCmsContent = jest.fn(); + return { wrapper }; +} diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue index 13f33ae05..724facf6c 100644 --- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue +++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue @@ -150,7 +150,7 @@ export default { return this.modelValue?.routeCode; }, set: function (newValue) { - // Button Question only supports Number, or String data types so we must get the full object to emit + // Button Question only supports Number, or String data types so we must convert to the full object before emitting this.selectedValue = this.getSelectedTimeSlotObject(newValue); }, }, @@ -326,7 +326,7 @@ export default { } }, modal() { - return this.$refs["timeSlots"]; + return this.$refs[this.modalName]; }, }, methods: { From 653918944e696cd1596e563c3a62b37cd927dd04 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 28 Jul 2023 11:15:29 -0400 Subject: [PATCH 2/4] Unit tests - first one completed --- .../time-slot-modal-question.spec.js | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js index 07c81ff0b..500b5646c 100644 --- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js +++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js @@ -87,13 +87,29 @@ afterEach(() => { }); describe("time-slot-modal-list-button-question.vue", () => { - test.only("IsInsurance false should navigateWithSaving", async () => { + test.only("When selected time slot is changed, a correctly formatted selectedTimeSlot should be emitted", async () => { //Arrange + const date = "2023-07-01"; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; const { wrapper } = setupMocks({ customMountOptions: { router: { navigateWithSaving: jest.fn(), }, + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [{ + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }] + } + } }, }); @@ -111,11 +127,8 @@ describe("time-slot-modal-list-button-question.vue", () => { // openModal() { return null}, // closeModal() {return null}, // }; - wrapper.vm.dateAndTimeSlotData.timeSlots = [{ - - }]; wrapper.vm.$refs.timeSlots.closeModal = jest.fn(); - wrapper.vm.selectedTimeSlotId = "testRouteCodeId"; + wrapper.vm.selectedTimeSlotId = timeSlotId; //await nextTick(); @@ -123,7 +136,13 @@ describe("time-slot-modal-list-button-question.vue", () => { //Act //await wrapper.vm.forwardButtonAction(); - const expectedEmit = + const expectedEmit = [[{ + date: date, + routeCode: timeSlotId, + startTime: startTime, + endTime: endTime, + jobMaxMinutes: jobMaxMinutes.toString(), + }]]; //Assert expect(wrapper.emitted()["update:modelValue"]).toEqual(expectedEmit); }); @@ -470,6 +489,7 @@ function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions, }); + console.log(mountOptions); mountOptions.global.mocks["$store"] = store; mountOptions["attachTo"] = document.body; mountOptions.mixins = [{ @@ -479,8 +499,6 @@ function setupMocks({ customMountOptions }) { }]; - const questionText = "Question Text"; - const wrapper = shallowMount(timeSlotModalQuestion, mountOptions); wrapper.vm.setCmsContent = jest.fn(); return { wrapper }; From 61d1fb4711a7558904c6e35add0cb24645624c49 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 1 Aug 2023 10:13:36 -0400 Subject: [PATCH 3/4] Unit tests for time slots --- src/layouts/schedule/schedule.spec.js | 228 ++++ .../time-slot-modal-question.spec.js | 1089 ++++++++++------- 2 files changed, 876 insertions(+), 441 deletions(-) create mode 100644 src/layouts/schedule/schedule.spec.js diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js new file mode 100644 index 000000000..654e0e4c9 --- /dev/null +++ b/src/layouts/schedule/schedule.spec.js @@ -0,0 +1,228 @@ +import { shallowMount } 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 schedule from "@/layouts/schedule/schedule.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 fetchCmsContentForPage +jest.mock("@/helpers/cms-content-helper", () => ({ + fetchCmsContentForPage: () => Promise.resolve("content"), + splitCopyOnCMSPlaceHolder: jest.fn(() => ["A", "B"]), +})); + +jest.mock( + "@/store", + () => { + return {}; + }, + { virtual: true } +); + +store.getters = { + order: { + schedule: { + date: "2020-01-01", + }, + lineItems: { + glassParts: [], + supportingItems: [], + }, + serviceLocation: { + appointmentType: "Inshop", + }, + }, + lineItems: { + glassParts: [], + supportingItems: [], + }, +}; + +describe("schedule.vue", () => { + test("Should navigateWithoutSaving", async () => { + //Arrange + const { wrapper } = setupMocks({ + customMountOptions: { + router: { + navigateWithoutSaving: jest.fn(), + }, + route: { schedule }, + }, + }); + + wrapper.vm.dispatchStoreAction = jest.fn(() => { + return { + data: [], + }; + }); + + //Act + await wrapper.vm.forwardButtonAction(); + + //Assert + expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled(); + }); + test("should pass arePagePrerequisitesValid with a mobile order and no providerNumber", () => { + //Arrange + const { wrapper } = setupMocks({}); + store.getters = { + order: { + schedule: { + date: "2020-01-01", + }, + serviceLocation: { + zipCode: "12345", + zipCodeCtu: "value", + appointmentType: "Mobile", + }, + damage: { + isRepair: true, + }, + referralNumber: "1234567", + }, + payment: { + isInsurance: true, + }, + lineItems: { + supportingItems: [], + }, + }; + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + + expect(arePagePrerequisitesValid).toBe(true); + }); + test("should pass arePagePrerequisitesValid with a inshop order and providerNumber", () => { + //Arrange + const { wrapper } = setupMocks({}); + store.getters = { + order: { + schedule: { + date: "2020-01-01", + }, + serviceLocation: { + zipCode: "12345", + zipCodeCtu: "value", + appointmentType: "Inshop", + provider: { + providerNumber: "5", + }, + }, + damage: { + isRepair: true, + }, + referralNumber: "1234567", + }, + payment: { + isInsurance: true, + }, + lineItems: { + supportingItems: [], + }, + }; + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + + expect(arePagePrerequisitesValid).toBe(true); + }); + test("should fail arePagePrerequisitesValid with a replace with no glass parts", () => { + //Arrange + const { wrapper } = setupMocks({}); + store.getters = { + order: { + schedule: { + date: "2020-01-01", + }, + serviceLocation: { + zipCode: "12345", + zipCodeCtu: "value", + appointmentType: "Inshop", + provider: { + providerNumber: "5", + }, + }, + damage: { + isRepair: false, + }, + referralNumber: "1234567", + }, + payment: { + isInsurance: true, + }, + lineItems: { + supportingItems: [], + glassParts: [], + }, + }; + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + + expect(arePagePrerequisitesValid).toBe(false); + }); + test("should fail arePagePrerequisitesValid without isInsurance", () => { + //Arrange + const { wrapper } = setupMocks({}); + store.getters = { + order: { + schedule: { + date: "2020-01-01", + }, + serviceLocation: { + zipCode: "12345", + zipCodeCtu: "value", + appointmentType: "Inshop", + provider: { + providerNumber: "5", + }, + }, + damage: { + isRepair: true, + }, + referralNumber: "1234567", + }, + payment: { + isInsurance: null, + }, + lineItems: { + supportingItems: [], + glassParts: [], + }, + }; + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + + expect(arePagePrerequisitesValid).toBe(false); + }); +}); + +const mockCmsContent = {}; + +function setupMocks({ customMountOptions }) { + const mountOptions = getMountOptions({ + ...customMountOptions, + }); + + mountOptions.global.mocks["$store"] = store; + mountOptions["attachTo"] = document.body; + mountOptions.mixins = [ + { + methods: { + getCmsContent: jest.fn().mockImplementation((widgetName, fieldName) => { + if (mockCmsContent[widgetName] && mockCmsContent[widgetName][fieldName]) + return mockCmsContent[widgetName][fieldName]; + }), + }, + }, + ]; + + const wrapper = shallowMount(schedule, mountOptions); + wrapper.vm.setCmsContent = jest.fn(); + return { wrapper }; +} diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js index 500b5646c..43d997892 100644 --- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js +++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js @@ -1,503 +1,710 @@ 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 timeSlotModalQuestion from "@/layouts/schedule/time-slot-modal-question/time-slot-modal-question.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 fetchCmsContentForPage -// jest.mock("@/helpers/cms-content-helper", () => ({ -// fetchCmsContentForPage: () => Promise.resolve("content"), -// })); - -// jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ -// navigateToHeritageFunnel: jest.fn(), -// })); - -// jest.mock( -// "@/store", -// () => { -// return {}; -// }, -// { 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: { - payment: { - insuranceCoverage: {}, - isInsurance: false, - parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, - }, - }, -}; - -afterEach(() => { - // reset store after each test - store.getters = { - order: { - payment: { - parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, - }, - }, - payment: { - insuranceCoverage: {}, - isInsurance: false, - }, - }; -}); +import { + RouteCodeFlags, + PREMIUM_TIME_SLOT_ID_FLAG, + PREMIUM_FEE_PART_TYPE, +} from "@/constants/schedule-constants"; describe("time-slot-modal-list-button-question.vue", () => { - test.only("When selected time slot is changed, a correctly formatted selectedTimeSlot should be emitted", async () => { + test("When selected time slot is changed, a correctly formatted selectedTimeSlot should be emitted", async () => { //Arrange const date = "2023-07-01"; const timeSlotId = "testRouteCodeId"; const startTime = "8:00 AM"; const endTime = "8:30 AM"; const jobMaxMinutes = 100; + const expectedEmit = [ + [ + { + date: date, + routeCode: timeSlotId, + startTime: startTime, + endTime: endTime, + jobMaxMinutes: jobMaxMinutes.toString(), + }, + ], + ]; + const { wrapper } = setupMocks({ customMountOptions: { - router: { - navigateWithSaving: jest.fn(), - }, propsData: { estimatedServiceMinutesMaximum: jobMaxMinutes, dateAndTimeSlotData: { date: date, - timeSlots: [{ - id: timeSlotId, - startTime: startTime, - endTime: endTime, - }] - } - } + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + }, }, }); - store.getters.payment = { - insuranceCoverage: {}, - isInsurance: false, - }; - // wrapper.vm.dispatchStoreAction = jest.fn(() => { - // return { - // data: [], - // }; - // }); - - // wrapper.vm.modal = { - // openModal() { return null}, - // closeModal() {return null}, - // }; wrapper.vm.$refs.timeSlots.closeModal = jest.fn(); wrapper.vm.selectedTimeSlotId = timeSlotId; - //await nextTick(); - + //Act wrapper.vm.setSelectedTimeSlot(); - //Act - //await wrapper.vm.forwardButtonAction(); - const expectedEmit = [[{ - date: date, - routeCode: timeSlotId, - startTime: startTime, - endTime: endTime, - jobMaxMinutes: jobMaxMinutes.toString(), - }]]; //Assert expect(wrapper.emitted()["update:modelValue"]).toEqual(expectedEmit); }); }); +describe("time-slot-modal-list-button-question.vue Supplemental information", () => { + test("The correct supplemental information should be obtained from CMS - Mobile - Not Premium ", async () => { + //Arrange + const mobileCmsWidgetName = "MobileNotPremium"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "test" }, + appointmentType: "Mobile", + mobileCmsWidgetName: mobileCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toEqual( + mockCmsContent[mobileCmsWidgetName]["BodyText"] + ); + }); + test("The correct supplemental information should be obtained from CMS - Mobile - Premium", async () => { + //Arrange + const mobileCmsWidgetName = "MobilePremium"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "test" + PREMIUM_TIME_SLOT_ID_FLAG }, + appointmentType: "Mobile", + mobileCmsWidgetName: mobileCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toEqual( + mockCmsContent[mobileCmsWidgetName]["BodyText"] + ); + }); + test("No supplemental information should be obtained from CMS - Inshop", async () => { + //Arrange + const inshopWidgetName = "Inshop"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "test" }, + appointmentType: "Inshop", + cmsWidgetName: inshopWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toBeNull(); + }); + test("No supplemental information should be obtained from CMS - Drop off, nothing selected", async () => { + //Arrange + const dropOffWidgetName = "Dropoff"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: null, + appointmentType: "Dropoff", + cmsWidgetName: dropOffWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toBeNull(); + }); + test("Correct supplemental information should be retrieved, Dropoff regular", async () => { + //Arrange + const dropOffWidgetName = "Dropoff"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + dropoffCmsWidgetName: dropOffWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toEqual( + mockCmsContent[dropOffWidgetName]["BodyText"] + ); + }); + test("Correct supplemental information should be retrieved, Dropoff Overnight", async () => { + //Arrange + const overnightDropOffCmsWidgetName = "Overnight"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF }, + appointmentType: "Dropoff", + overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.supplementalInformationBlock).toEqual( + mockCmsContent[overnightDropOffCmsWidgetName]["BodyText"] + ); + }); + test("Correct supplemental information should be retrieved, Dropoff Sameday", async () => { + //Arrange + const sameDayDropOffCmsWidgetName = "Sameday"; + const date = new Date().toISOString().split("T")[0]; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// describe("quote.vue", () => { -// test("IsInsurance false should navigateWithSaving", async () => { -// //Arrange -// const { wrapper } = setupMocks({ -// customMountOptions: { -// router: { -// navigateWithSaving: jest.fn(), -// }, -// route: { quote }, -// }, -// }); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName, + }, + }, + }); -// store.getters.payment = { -// insuranceCoverage: {}, -// isInsurance: false, -// }; + //Assert + expect(wrapper.vm.supplementalInformationBlock).toEqual( + mockCmsContent[sameDayDropOffCmsWidgetName]["BodyText"] + ); + }); +}); -// wrapper.vm.dispatchStoreAction = jest.fn(() => { -// return { -// data: [], -// }; -// }); +describe("time-slot-modal-list-button-question.vue Disclaimer", () => { + test("The correct disclaimer information should be obtained from CMS - Dropoff - Sameday ", async () => { + //Arrange + const sameDayDropOffCmsWidgetName = "Sameday"; + const date = new Date().toISOString().split("T")[0]; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// wrapper.vm.pricedGlassParts = []; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName, + }, + }, + }); -// //Act -// await wrapper.vm.forwardButtonAction(); + //Assert + expect(wrapper.vm.disclaimerTextBlockCopy).toEqual( + mockCmsContent[sameDayDropOffCmsWidgetName]["FooterText"] + ); + }); + test("Correct disclaimer information should be retrieved, Dropoff regular", async () => { + //Arrange + const dropOffWidgetName = "Dropoff"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + dropoffCmsWidgetName: dropOffWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.disclaimerTextBlockCopy).toEqual( + mockCmsContent[dropOffWidgetName]["FooterText"] + ); + }); + test("Correct disclaimer information should be retrieved, Dropoff overnight", async () => { + //Arrange + const overnightDropOffCmsWidgetName = "Overnight"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF }, + appointmentType: "Dropoff", + overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.disclaimerTextBlockCopy).toEqual( + mockCmsContent[overnightDropOffCmsWidgetName]["FooterText"] + ); + }); + test("No disclaimer information should be retrieved, non-dropoff", async () => { + //Arrange + const inshopWidgetName = "Inshop"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "test" }, + appointmentType: "Inshop", + cmsWidgetName: inshopWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.disclaimerTextBlockCopy).toBeNull(); + }); +}); -// //Assert -// expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); -// }); +describe("time-slot-modal-list-button-question.vue Duration", () => { + test("The correct duration information should be displayed - Dropoff - Sameday ", async () => { + //Arrange + const sameDayDropOffCmsWidgetName = "Sameday"; + const date = new Date().toISOString().split("T")[0]; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// test("IsInsurance true should navigateToHeritageFunnel", async () => { -// //Arrange -// const { wrapper } = setupMocks({ -// customMountOptions: { -// router: { -// navigateWithSaving: jest.fn(), -// }, -// route: { quote }, -// }, -// }); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName, + }, + }, + }); -// store.getters.payment = { -// insuranceCoverage: {}, -// isInsurance: true, -// }; + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[sameDayDropOffCmsWidgetName]["SubheaderText"] + ); + }); + test("Correct duration information should be retrieved, Dropoff overnight", async () => { + //Arrange + const overnightDropOffCmsWidgetName = "Overnight"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF }, + appointmentType: "Dropoff", + overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[overnightDropOffCmsWidgetName]["SubheaderText"] + ); + }); + test("Correct duration information should be retrieved, Dropoff", async () => { + //Arrange + const dropoffCmsWidgetName = "Dropoff"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF }, + appointmentType: "Dropoff", + dropoffCmsWidgetName: dropoffCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[dropoffCmsWidgetName]["SubheaderText"] + ); + }); + test("Correct duration information should be retrieved, Inshop - convert to hours", async () => { + //Arrange + const cmsWidgetName = "Inshop"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: 180, + estimatedServiceMinutesMinimum: 120, + modelValue: { routeCode: "Test" }, + appointmentType: "Inshop", + cmsWidgetName: cmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[cmsWidgetName]["SubheaderText"] + " 2 - 3 hours" + ); + }); + test("Correct duration information should be retrieved, Inshop - convert to minutes", async () => { + //Arrange + const cmsWidgetName = "Inshop"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: 90, + estimatedServiceMinutesMinimum: 60, + modelValue: { routeCode: "Test" }, + appointmentType: "Inshop", + cmsWidgetName: cmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[cmsWidgetName]["SubheaderText"] + " 60 - 90 minutes" + ); + }); + test("Correct duration information should be retrieved, Inshop - min = maximum time", async () => { + //Arrange + const cmsWidgetName = "Inshop"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: 240, + estimatedServiceMinutesMinimum: 240, + modelValue: { routeCode: "Test" }, + appointmentType: "Inshop", + cmsWidgetName: cmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toEqual( + mockCmsContent[cmsWidgetName]["SubheaderText"] + " 4 hours" + ); + }); + test("No duration information should be displayed, Mobile", async () => { + //Arrange + const mobileCmsWidgetName = "Mobile"; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: 240, + estimatedServiceMinutesMinimum: 240, + modelValue: { routeCode: "Test" }, + appointmentType: "Mobile", + mobileCmsWidgetName: mobileCmsWidgetName, + }, + }, + }); + //Assert + expect(wrapper.vm.durationTextBlockCopy).toBeNull(); + }); +}); -// wrapper.vm.dispatchStoreAction = jest.fn(() => { -// return { -// data: [], -// }; -// }); +describe("time-slot-modal-list-button-question.vue Available Timeslots", () => { + test("Available Timeslots should be formatted correctly - Dropoff - Sameday ", async () => { + //Arrange + const sameDayDropOffCmsWidgetName = "Sameday"; + const date = new Date().toISOString().split("T")[0]; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// wrapper.vm.pricedGlassParts = []; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + appointmentType: "Dropoff", + sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName, + }, + }, + }); -// //Act -// await wrapper.vm.forwardButtonAction(); + //Assert + const expectedTimeSlotObject = { + buttonLabel: mockCmsContent[sameDayDropOffCmsWidgetName]["HeaderText"], + value: timeSlotId, + }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); + test("Available Timeslots should be formatted correctly - Dropoff - Overnight ", async () => { + //Arrange + const overnightDropOffCmsWidgetName = "Overnight"; + const date = new Date().toISOString().split("T")[0]; + const timeSlotId = "testRouteCodeId" + RouteCodeFlags.OVERNIGHT_DROP_OFF; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// //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", -// }, -// payment: { -// insuranceCoverage: { -// isVerified: false, -// }, -// }, -// }; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + appointmentType: "Dropoff", + overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName, + }, + }, + }); -// let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + //Assert + const expectedTimeSlotObject = { + buttonLabel: mockCmsContent[overnightDropOffCmsWidgetName]["HeaderText"], + value: timeSlotId, + }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); + test("Available Timeslots should be formatted correctly - Dropoff", async () => { + //Arrange + const dropoffCmsWidgetName = "Dropoff"; + const date = "2020-01-01"; + const timeSlotId = "testRouteCodeId" + RouteCodeFlags.ALL_DAY_DROP_OFF; + const startTime = "8:00 AM"; + const endTime = "8:30 AM"; + const jobMaxMinutes = 100; -// 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"], -// }, -// }, -// payment: { -// insuranceCoverage: { -// isVerified: false, -// }, -// }, -// }; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + appointmentType: "Dropoff", + dropoffCmsWidgetName: dropoffCmsWidgetName, + }, + }, + }); -// let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + //Assert + const expectedTimeSlotObject = { + buttonLabel: mockCmsContent[dropoffCmsWidgetName]["HeaderText"], + value: timeSlotId, + }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); + test("Available Timeslots should be formatted correctly - Mobile not premium", async () => { + //Arrange + const mobileCmsWidgetName = "MobileNotPremium"; + const date = "2020-01-01"; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00"; + const endTime = "8:30"; + const jobMaxMinutes = 100; -// 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", -// }, -// }; + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + appointmentType: "Mobile", + mobileCmsWidgetName: mobileCmsWidgetName, + }, + }, + }); -// let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + //Assert + const expectedTimeSlotObject = { + buttonLabel: startTime + " AM - " + endTime + " AM", + value: timeSlotId, + }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); + test("Available Timeslots should be formatted correctly - Mobile with premium", async () => { + //Arrange + const mobilePremiumCmsWidgetName = "MobilePremium"; + const date = "2020-01-01"; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00"; + const endTime = "8:30"; + const jobMaxMinutes = 100; -// expect(arePagePrerequisitesValid).toBe(false); -// }); -// test("should have non-null values for necessary data members after 'beforeRouteEnter'", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + premiumAppointmentFee: { + partType: PREMIUM_FEE_PART_TYPE, + }, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + offerPremium: true, + }, + ], + }, + appointmentType: "Mobile", + mobilePremiumCmsWidgetName: mobilePremiumCmsWidgetName, + }, + }, + }); -// store.getters = { -// order: { -// lineItems: { -// glassParts: ["item", "item2"], -// }, -// }, -// }; + //Assert + const expectedTimeSlotObject = { + additionalButtonData: { + isPremiumAppointment: true, + }, + buttonLabel: mockCmsContent[mobilePremiumCmsWidgetName]["HeaderText"], + buttonLabelSubCopy: "+$15.99", + value: timeSlotId + PREMIUM_TIME_SLOT_ID_FLAG, + }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); + test("Available Timeslots should be formatted correctly - Inshop", async () => { + //Arrange + const cmsWidgetName = "Inshop"; + const date = "2020-01-01"; + const timeSlotId = "testRouteCodeId"; + const startTime = "8:00"; + const endTime = "8:30"; + const jobMaxMinutes = 100; -// //mock this to avoid needing to populate this.$route in an unrelated test -// wrapper.vm.getDefaultIsInsuranceSelectedValue = jest.fn(); + const { wrapper } = setupMocks({ + customMountOptions: { + propsData: { + estimatedServiceMinutesMaximum: jobMaxMinutes, + dateAndTimeSlotData: { + date: date, + timeSlots: [ + { + id: timeSlotId, + startTime: startTime, + endTime: endTime, + }, + ], + }, + appointmentType: "Inshop", + cmsWidgetName: cmsWidgetName, + }, + }, + }); -// //Act -// await quote.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "quote" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Assert + const expectedTimeSlotObject = { buttonLabel: startTime + " AM", value: timeSlotId }; + expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject); + }); +}); -// //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); -// }); -// }); +const mockCmsContent = { + MobileNotPremium: { + BodyText: "Mobile, not premium BodyText", + FooterText: "Mobile, not premium FooterText", + SubheaderText: "Mobile, not premium SubheaderText", + HeaderText: "Mobile, not premium HeaderText", + }, + MobilePremium: { + "BodyText:": "Mobile, with premium BodyText", + FooterText: "Mobile, with premium FooterText", + SubheaderText: "Mobile, with premium SubheaderText", + HeaderText: "Mobile, with premium HeaderText", + }, + Inshop: { + BodyText: "Inshop BodyText", + FooterText: "Inshop FooterText", + SubheaderText: "Inshop SubheaderText", + HeaderText: "Inshop HeaderText", + }, + Dropoff: { + BodyText: "Dropoff BodyText", + FooterText: "Dropoff FooterText", + SubheaderText: "Dropoff SubheaderText", + HeaderText: "Dropoff HeaderText", + }, + Overnight: { + BodyText: "Dropoff Overnight", + FooterText: "Dropoff, Overnight FooterText", + SubheaderText: "Dropoff, Overnight SubheaderText", + HeaderText: "Dropoff, Overnight HeaderText", + }, + Sameday: { + BodyText: "Dropoff Sameday", + FooterText: "Dropoff, Sameday FooterText", + SubheaderText: "Dropoff, Sameday SubheaderText", + HeaderText: "Dropoff, Sameday HeaderText", + }, +}; function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions, }); - console.log(mountOptions); mountOptions.global.mocks["$store"] = store; mountOptions["attachTo"] = document.body; - mountOptions.mixins = [{ - methods: { - getCmsContent: jest.fn() - } - }]; - + mountOptions.mixins = [ + { + methods: { + getCmsContent: jest.fn().mockImplementation((widgetName, fieldName) => { + if (mockCmsContent[widgetName] && mockCmsContent[widgetName][fieldName]) + return mockCmsContent[widgetName][fieldName]; + }), + getTotalLineItemPrice: jest.fn().mockImplementation(() => 15.99), + }, + }, + ]; const wrapper = shallowMount(timeSlotModalQuestion, mountOptions); wrapper.vm.setCmsContent = jest.fn(); From 84f1f0dbb7902db09e6c844dfb5251cf34083370 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 1 Aug 2023 10:18:20 -0400 Subject: [PATCH 4/4] Up unit test % to 80 --- jest.config.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jest.config.js b/jest.config.js index aaf2d9ff8..0a6fbc048 100644 --- a/jest.config.js +++ b/jest.config.js @@ -26,8 +26,7 @@ module.exports = { testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], coverageThreshold: { global: { - statements: 75, - // Got the go ahead from Mark to temporarily lower this. Taking out initialize component made the year,make,model and style coverage drop a bit. Once unit tests for license plate lookup, vin lookup and address lookup are in the coverage should go back up to 90 + statements: 80, }, }, // Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit