From 52cc88dbcae2493ad7cf1276f0a50b683e2c99cb Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 16 Aug 2023 17:40:57 -0400 Subject: [PATCH 01/41] Move customer-details-modal-question --- .../customer-details-modal-question.spec.js | 2 +- .../customer-details-modal-question.vue | 0 src/layouts/review/review.vue | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/layouts/review/{review-sections/customer-review => }/customer-details-modal-question/customer-details-modal-question.spec.js (96%) rename src/layouts/review/{review-sections/customer-review => }/customer-details-modal-question/customer-details-modal-question.vue (100%) diff --git a/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js b/src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js similarity index 96% rename from src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js rename to src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js index a8e0a6f7b..abd264cef 100644 --- a/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js +++ b/src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js @@ -1,7 +1,7 @@ import { shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; -import customerDetailsModalQuestion from "@/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question"; +import customerDetailsModalQuestion from "@/layouts/review/customer-details-modal-question/customer-details-modal-question"; const testConstants = { previousCustomerValues: { diff --git a/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue b/src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue similarity index 100% rename from src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue rename to src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index fe14e8f7e..0c9fa1533 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -115,7 +115,7 @@ import serviceLocationReview from "@/layouts/review/review-sections/service-loca import scheduleReview from "@/layouts/review/review-sections/schedule-review/schedule-review"; import customerReview from "@/layouts/review/review-sections/customer-review/customer-review"; -import customerDetailsModalQuestion from "@/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue"; +import customerDetailsModalQuestion from "@/layouts/review/customer-details-modal-question/customer-details-modal-question.vue"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; From d5e47707982c0307fc00a1f5e642e38cb5cfaa4a Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 17 Aug 2023 10:07:40 -0400 Subject: [PATCH 02/41] Change modal to back-nav --- .../customer-details-modal-question.spec.js | 150 ------------------ .../customer-details-modal-question.vue | 148 ----------------- src/layouts/review/review.vue | 12 +- .../router-constants/navigation-scenarios.js | 1 + src/router/router-constants/routing-table.js | 4 + 5 files changed, 9 insertions(+), 306 deletions(-) delete mode 100644 src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js delete mode 100644 src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue diff --git a/src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js b/src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js deleted file mode 100644 index abd264cef..000000000 --- a/src/layouts/review/customer-details-modal-question/customer-details-modal-question.spec.js +++ /dev/null @@ -1,150 +0,0 @@ -import { shallowMount } from "@vue/test-utils"; -import { getMountOptions } from "@/helpers/unit-test-helper.js"; - -import customerDetailsModalQuestion from "@/layouts/review/customer-details-modal-question/customer-details-modal-question"; - -const testConstants = { - previousCustomerValues: { - firstName: "First", - lastName: "Last", - emailAddress: "builddigitaltest@safelite.com", - phoneNumber: "111-111-1111", - isSmsOptIn: false, - }, - newValues: { - firstName: "New First", - lastName: "New Last", - emailAddress: "builddigitaltest2@safelite.com", - phoneNumber: "222-222-2222", - isSmsOptIn: true, - }, -}; - -let cmsContent; - -describe("Customer Details Modal", () => { - beforeEach(() => { - cmsContent = {}; - }); - - describe("Submit", () => { - test("Should push to store if a field has changed", async () => { - // Arrange - let props = generateDefaultProps(); - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - wrapper.vm.onModalOpened(); - - wrapper.vm.firstName = testConstants.newValues.firstName; - - await wrapper.vm.setContactDetails(); - await wrapper.vm.$nextTick(); - - // Assert - expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled(); - expect(wrapper.vm.closeModal).toHaveBeenCalled(); - }); - - test("Should not push to store if no fields have changed", async () => { - // Arrange - let props = generateDefaultProps(); - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - wrapper.vm.onModalOpened(); - - await wrapper.vm.setContactDetails(); - await wrapper.vm.$nextTick(); - - // Assert - expect(wrapper.vm.dispatchStoreAction).not.toHaveBeenCalled(); - expect(wrapper.vm.closeModal).toHaveBeenCalled(); - }); - }); - - describe("Default values", () => { - test("Should populate on open", () => { - // Arrange - let props = generateDefaultProps(); - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - wrapper.vm.onModalOpened(); - - // Assert - expect(wrapper.vm.firstName).toBe(testConstants.previousCustomerValues.firstName); - expect(wrapper.vm.lastName).toBe(testConstants.previousCustomerValues.lastName); - expect(wrapper.vm.emailAddress).toBe(testConstants.previousCustomerValues.emailAddress); - expect(wrapper.vm.phoneNumber).toBe(testConstants.previousCustomerValues.phoneNumber); - expect(wrapper.vm.isSmsOptIn).toBe(testConstants.previousCustomerValues.isSmsOptIn); - }); - - test("Should replace old values on open", async () => { - // Arrange - let props = generateDefaultProps(); - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - wrapper.vm.firstName = testConstants.newValues.firstName; - wrapper.vm.lastName = testConstants.newValues.lastName; - wrapper.vm.emailAddress = testConstants.newValues.emailAddress; - wrapper.vm.phoneNumber = testConstants.newValues.phoneNumber; - wrapper.vm.isSmsOptIn = testConstants.newValues.isSmsOptIn; - - wrapper.vm.onModalOpened(); - - // Assert - expect(wrapper.vm.firstName).toBe(testConstants.previousCustomerValues.firstName); - expect(wrapper.vm.lastName).toBe(testConstants.previousCustomerValues.lastName); - expect(wrapper.vm.emailAddress).toBe(testConstants.previousCustomerValues.emailAddress); - expect(wrapper.vm.phoneNumber).toBe(testConstants.previousCustomerValues.phoneNumber); - expect(wrapper.vm.isSmsOptIn).toBe(testConstants.previousCustomerValues.isSmsOptIn); - }); - }); -}); - -function generateDefaultProps() { - return { - previousCustomerValues: { - firstName: testConstants.previousCustomerValues.firstName, - lastName: testConstants.previousCustomerValues.lastName, - emailAddress: testConstants.previousCustomerValues.emailAddress, - phoneNumber: testConstants.previousCustomerValues.phoneNumber, - isSmsOptIn: testConstants.previousCustomerValues.isSmsOptIn, - }, - }; -} - -function setupMocks(customMountOptions) { - const mountOptions = getMountOptions(customMountOptions); - - const mockMixin = { - methods: { - getCmsContent: jest.fn((widgetName, cmsFieldName) => { - return cmsContent?.[widgetName]?.[cmsFieldName] ?? ""; - }), - }, - }; - - mountOptions.global.mixins = [mockMixin]; - - const wrapper = shallowMount(customerDetailsModalQuestion, mountOptions); - wrapper.vm.setCmsContent = jest.fn(); - wrapper.vm.openModal = jest.fn(); - wrapper.vm.closeModal = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn(); - return { wrapper }; -} diff --git a/src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue b/src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue deleted file mode 100644 index 0b08abee7..000000000 --- a/src/layouts/review/customer-details-modal-question/customer-details-modal-question.vue +++ /dev/null @@ -1,148 +0,0 @@ - - - diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index 0c9fa1533..be0af585e 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -89,10 +89,6 @@
- - diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index ce2f32134..10339a6a0 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -52,6 +52,7 @@ const navigationScenarios = { CLICKED_SERVICE_PACKAGE_EDIT: "CLICKED_SERVICE_PACKAGE_EDIT", CLICKED_SERVICE_LOCATION_EDIT: "CLICKED_SERVICE_LOCATION_EDIT", CLICKED_SCHEDULE_EDIT: "CLICKED_SCHEDULE_EDIT", + CLICKED_CUSTOMER_EDIT: "CLICKED_CUSTOMER_EDIT", }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index f1f83b445..953eaffc3 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -488,6 +488,10 @@ const routingTable = function (store) { scenario: navigationScenarios.CLICKED_SCHEDULE_EDIT, destinationFmgPageValue: fmgPageValues.SCHEDULE, }, + { + scenario: navigationScenarios.CLICKED_CUSTOMER_EDIT, + destinationFmgPageValue: fmgPageValues.CUSTOMER_DETAILS, + }, ], }, ]; From 7ed74f5915f59a7417958941cb0e9e310f3d1a63 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 17 Aug 2023 11:10:48 -0400 Subject: [PATCH 03/41] Remove custom hack from cms as no longer needed --- .../review-sections/customer-review/customer-review.vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/layouts/review/review-sections/customer-review/customer-review.vue b/src/layouts/review/review-sections/customer-review/customer-review.vue index d8777d9e4..678dcf0b6 100644 --- a/src/layouts/review/review-sections/customer-review/customer-review.vue +++ b/src/layouts/review/review-sections/customer-review/customer-review.vue @@ -36,10 +36,7 @@ export default { return this.customer?.phoneNumber; }, smsOptIn() { - const rawCmsText = this.getCmsContent(this.cmsWidgetName, "SubheaderText"); - const joinerText = this.customer?.isSmsOptIn ? "in to" : "out of"; - - return rawCmsText.replace("{custom:smsOptInJoiner}", joinerText); + return this.getCmsContent(this.cmsWidgetName, "SubheaderText"); }, }, components: { From 398964ea597a7abe11dbd05958d4b20233f51094 Mon Sep 17 00:00:00 2001 From: sheena Date: Tue, 22 Aug 2023 20:07:44 +0530 Subject: [PATCH 04/41] CSR-1599 Updated the color --- .../shop-question/shop-list-button/shop-list-button.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue b/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue index 31c415a2d..9a0fb063e 100644 --- a/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue +++ b/src/layouts/service-location/shop-question/shop-list-button/shop-list-button.vue @@ -88,7 +88,7 @@ export default { if (this.availabilityRating == null) { return "gray"; } else { - return this.availabilityRating == "high" ? "green" : "red"; + return this.availabilityRating == "high" ? "green" : "Orange"; } }, badgeText() { From 8cae60577a98080f9ba8df67fe916a6e96506c21 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 22 Aug 2023 16:33:13 -0400 Subject: [PATCH 05/41] Update Tests --- .../customer-review/customer-review.spec.js | 61 ++++--------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/src/layouts/review/review-sections/customer-review/customer-review.spec.js b/src/layouts/review/review-sections/customer-review/customer-review.spec.js index 1bcbbe83b..45627df2e 100644 --- a/src/layouts/review/review-sections/customer-review/customer-review.spec.js +++ b/src/layouts/review/review-sections/customer-review/customer-review.spec.js @@ -9,11 +9,7 @@ const testConstants = { text: "Header", }, sms: { - template: "Test {custom:smsOptInJoiner}", - expected: { - ifTrue: "Test in to", - ifFalse: "Test out of", - }, + text: "Sms", }, }, customer: { @@ -27,7 +23,7 @@ const testConstants = { fullName: "First Last", phoneNumber: "111-111-1111", emailAddress: "builddigitaltest@safelite.com", - smsOptIn: "Test out of", + smsOptIn: "Sms", }, }; @@ -38,7 +34,7 @@ describe("Customer Review Block", () => { cmsContent = { CustomerWidget: { HeaderText: testConstants.cms.header.text, - SubheaderText: testConstants.cms.sms.template, + SubheaderText: testConstants.cms.sms.text, }, }; }); @@ -58,52 +54,19 @@ describe("Customer Review Block", () => { expect(wrapper.vm.header).toEqual(testConstants.cms.header.text); }); - describe("SMS Opt In Text", () => { - test("Should render correctly when opt in is true:", async () => { - // Arrange - let props = generateDefaultProps(); - props.customer.isSmsOptIn = true; + test("Should display sms text from cms", async () => { + // Arrange + let props = generateDefaultProps(); - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - await wrapper.vm.$nextTick(); - - // Assert - expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifTrue); + const { wrapper } = setupMocks({ + propsData: props, }); - test("Should render correctly when opt in is false:", async () => { - // Arrange - let props = generateDefaultProps(); - props.customer.isSmsOptIn = false; - const { wrapper } = setupMocks({ - propsData: props, - }); + // Act + await wrapper.vm.$nextTick(); - // Act - await wrapper.vm.$nextTick(); - - // Assert - expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifFalse); - }); - test("Should render correctly when opt in is null:", async () => { - // Arrange - let props = generateDefaultProps(); - props.customer.isSmsOptIn = null; - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - await wrapper.vm.$nextTick(); - - // Assert - expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifFalse); - }); + // Assert + expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.text); }); test("Should render correct display content", async () => { From 54010aa81f4095f7f77f15a962dd955aec400800 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 23 Aug 2023 10:12:41 -0400 Subject: [PATCH 06/41] Add prereq check --- src/layouts/review/review.vue | 63 ++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index be0af585e..61538c8f3 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -111,8 +111,11 @@ import serviceLocationReview from "@/layouts/review/review-sections/service-loca import scheduleReview from "@/layouts/review/review-sections/schedule-review/schedule-review"; import customerReview from "@/layouts/review/review-sections/customer-review/customer-review"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; + import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import store from "@/store"; export default { name: "review", @@ -147,7 +150,65 @@ export default { }, methods: { arePagePrerequisitesValid() { - return true; + // Vehicle + const vehicle = store.getters.order.vehicle; + const vehicleReqs = vehicle.year && vehicle.make && vehicle.model && vehicle.style; + + // Damage + const damage = store.getters.order.damage; + const damageReqs = + (damage.isRepair && damage.numberOfChips) || damage.glassToReplace?.length; + + // Service Package + const lineItems = store.getters.order.lineItems; + // damageReqs handles checking for damage, even though it is also required for this section. + const packageReqs = (damage.isRepair || lineItems.glassParts) && lineItems.supportingItems && lineItems.vaps; + + // Service Location + const serviceLocation = store.getters.order.serviceLocation; + const mobileReqs = + serviceLocation.address && + serviceLocation.city && + serviceLocation.state && + serviceLocation.zipCode; + + const providerLocation = serviceLocation.provider.address; + const dropOffInshopReqs = + providerLocation.streetAddress && + providerLocation.city && + providerLocation.state && + providerLocation.zipCode; + + const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; + + const serviceLocationReqs = + (isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs); + + // Schedule + const schedule = store.getters.order.schedule; + const scheduleReqs = + schedule.date && + schedule.startTime && + schedule.endTime && + schedule.jobMaxMinutes && + schedule.jobMinMinutes; + + // Customer + const customer = store.getters.order.customer; + const customerReqs = + customer.firstName && + customer.lastName && + customer.phoneNumber && + customer.emailAddress; + + return ( + vehicleReqs && + damageReqs && + packageReqs && + serviceLocationReqs && + scheduleReqs && + customerReqs + ); }, backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); From 076c48552e9c71bf0bc2f3aca1d713b92684d3ae Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 23 Aug 2023 14:14:52 -0400 Subject: [PATCH 07/41] Type Coerce --- src/layouts/review/review.vue | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index 61538c8f3..6b2d26cff 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -152,32 +152,40 @@ export default { arePagePrerequisitesValid() { // Vehicle const vehicle = store.getters.order.vehicle; - const vehicleReqs = vehicle.year && vehicle.make && vehicle.model && vehicle.style; + const vehicleReqs = !!(vehicle.year && vehicle.make && vehicle.model && vehicle.style); // Damage const damage = store.getters.order.damage; - const damageReqs = - (damage.isRepair && damage.numberOfChips) || damage.glassToReplace?.length; + const damageReqs = !!( + (damage.isRepair && damage.numberOfChips) || + damage.glassToReplace?.length + ); // Service Package const lineItems = store.getters.order.lineItems; // damageReqs handles checking for damage, even though it is also required for this section. - const packageReqs = (damage.isRepair || lineItems.glassParts) && lineItems.supportingItems && lineItems.vaps; + const packageReqs = !!( + (damage.isRepair || lineItems.glassParts) && + lineItems.supportingItems && + lineItems.vaps + ); // Service Location const serviceLocation = store.getters.order.serviceLocation; - const mobileReqs = + const mobileReqs = !!( serviceLocation.address && serviceLocation.city && serviceLocation.state && - serviceLocation.zipCode; + serviceLocation.zipCode + ); const providerLocation = serviceLocation.provider.address; - const dropOffInshopReqs = + const dropOffInshopReqs = !!( providerLocation.streetAddress && providerLocation.city && providerLocation.state && - providerLocation.zipCode; + providerLocation.zipCode + ); const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; @@ -186,20 +194,22 @@ export default { // Schedule const schedule = store.getters.order.schedule; - const scheduleReqs = + const scheduleReqs = !!( schedule.date && schedule.startTime && schedule.endTime && schedule.jobMaxMinutes && - schedule.jobMinMinutes; + schedule.jobMinMinutes + ); // Customer const customer = store.getters.order.customer; - const customerReqs = + const customerReqs = !!( customer.firstName && customer.lastName && customer.phoneNumber && - customer.emailAddress; + customer.emailAddress + ); return ( vehicleReqs && From 4d953cae649c68c3838393f8e35ca634a2032a79 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 23 Aug 2023 14:35:01 -0400 Subject: [PATCH 08/41] Clarify damage requirements --- src/layouts/review/review.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index 6b2d26cff..2fb033ea3 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -158,7 +158,7 @@ export default { const damage = store.getters.order.damage; const damageReqs = !!( (damage.isRepair && damage.numberOfChips) || - damage.glassToReplace?.length + (!damage.isRepair && damage.glassToReplace?.length) ); // Service Package From 06c095fcb1103369cbc6be3fc701bc06ca853ae7 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 23 Aug 2023 14:54:28 -0400 Subject: [PATCH 09/41] Add tests --- src/layouts/review/review.spec.js | 361 +++++++++++++++++++++++++++++- 1 file changed, 360 insertions(+), 1 deletion(-) diff --git a/src/layouts/review/review.spec.js b/src/layouts/review/review.spec.js index 674dc71f7..bd1bfc5b6 100644 --- a/src/layouts/review/review.spec.js +++ b/src/layouts/review/review.spec.js @@ -1,3 +1,362 @@ +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import store from "@/store"; + +import review from "@/layouts/review/review"; + +const testConstants = {}; + +jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), +})); + describe("Review Page", () => { - test.todo("Add more tests as specific functionality is added."); + beforeEach(() => { + store.getters = { + order: { + vehicle: { + year: "2020", + make: "Acura", + model: "MDX", + style: "4 door sedan", + }, + damage: { + isRepair: false, + numberOfChips: 2, + glassToReplace: ["dummy location value"], + }, + lineItems: { + glassParts: ["dummy part value"], + supportingItems: ["dummy supporting item"], + vaps: ["dummy vap"], + }, + serviceLocation: { + address: "address 1", + address2: "address 2", + city: "city", + state: "state", + zipCode: "zip code", + appointmentType: "Mobile", + provider: { + providerNumber: 1, + address: { + streetAddress: "provider address 1", + city: "provider city", + state: "provider state", + zipCode: "provider zip code", + }, + }, + }, + schedule: { + date: "date", + startTime: "start", + endTime: "end", + jobMinMinutes: "30", + jobMaxMinutes: "45", + }, + customer: { + firstName: "first name", + lastName: "last name", + emailAddress: "builddigitaltest@safelite.com", + phoneNumber: "555-555-5555", + isSmsOptIn: true, + }, + }, + }; + }); + describe("arePagePrerequisitesValid", () => { + test("Returns true for baseline valid state", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Returns false for empty state", () => { + // Arrange + store.getters.order = { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + vin: null, + imageUrl: null, + imageVifNumber: null, + imageColor: null, + registration: { + licensePlate: null, + }, + }, + serviceLocation: { + address: null, + address2: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + appointmentType: null, + isVehicleProtected: null, + provider: { + providerNumber: null, + address: { + streetAddress: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + }, + }, + techNotes: null, + }, + customer: { + firstName: null, + lastName: null, + emailAddress: null, + phoneNumber: null, + isSmsOptIn: null, + }, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + partQuestionAnswers: null, + moldingQuestionAnswers: null, + capabilityQuestionAnswers: null, + }, + lineItems: { + glassParts: null, + supportingItems: null, + vaps: null, + serverData: null, + }, + payment: { + isInsurance: null, + insuranceCoverage: { + isVerified: null, + coverageStatus: null, + }, + parentAccountNumber: 0, + }, + schedule: { + date: null, + startTime: null, + endTime: null, + routeCode: null, + jobMaxMinutes: null, + jobMinMinutes: null, + }, + referralNumber: null, + referralSequenceNumber: null, + referralDate: null, + referralCorrelationId: null, + eon: null, + }; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + describe("Damage requirements", () => { + test("Accepts null glassToReplace when is repair", () => { + // Arrange + store.getters.order.damage.isRepair = true; + store.getters.order.damage.glassToReplace = null; + store.getters.order.damage.numberOfChips = 1; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Rejects 0 chips when repair", () => { + // Arrange + store.getters.order.damage.isRepair = true; + store.getters.order.damage.numberOfChips = 0; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + test("Rejects null chips when repair", () => { + // Arrange + store.getters.order.damage.isRepair = true; + store.getters.order.damage.numberOfChips = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + test("Accepts null chips when not repair", () => { + // Arrange + store.getters.order.damage.isRepair = false; + store.getters.order.damage.numberOfChips = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Rejects empty glassToReplace when not repair", () => { + // Arrange + store.getters.order.damage.isRepair = false; + store.getters.order.damage.glassToReplace = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + test("Rejects null glassToReplace when not repair", () => { + // Arrange + store.getters.order.damage.isRepair = false; + store.getters.order.damage.glassToReplace = []; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + }); + describe("Package requirements", () => { + test("Accepts null glassParts when is repair", () => { + // Arrange + store.getters.order.damage.isRepair = true; + store.getters.order.lineItems.glassParts = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Rejects null glassParts when not repair", () => { + // Arrange + store.getters.order.damage.isRepair = false; + store.getters.order.lineItems.glassParts = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + }); + describe("Service Location requirements", () => { + test("Accepts null provider address when mobile appointment", () => { + // Arrange + store.getters.order.serviceLocation.appointmentType = "Mobile"; + store.getters.order.serviceLocation.provider.address = {}; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Reject null provider address when non-mobile appointment", () => { + // Arrange + store.getters.order.serviceLocation.appointmentType = "Inshop"; + store.getters.order.serviceLocation.provider.address = {}; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + test("Accepts null service location address when non-mobile appointment", () => { + // Arrange + store.getters.order.serviceLocation.appointmentType = "Inshop"; + store.getters.order.serviceLocation.address = null; + store.getters.order.serviceLocation.address2 = null; + store.getters.order.serviceLocation.zipCode = null; + store.getters.order.serviceLocation.city = null; + store.getters.order.serviceLocation.state = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(true); + }); + test("Rejects null service location address when mobile appointment", () => { + // Arrange + store.getters.order.serviceLocation.appointmentType = "Mobile"; + store.getters.order.serviceLocation.address = null; + store.getters.order.serviceLocation.address2 = null; + store.getters.order.serviceLocation.zipCode = null; + store.getters.order.serviceLocation.city = null; + store.getters.order.serviceLocation.state = null; + + const { wrapper } = setupMocks({}); + + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(isValid).toBe(false); + }); + }); + }); }); + +function setupMocks(customMountOptions) { + customMountOptions.store = store; + + const mountOptions = getMountOptions(customMountOptions); + + const mockMixin = { + methods: { + getCmsContent: jest.fn((widgetName, cmsFieldName) => { + return `${widgetName} ${cmsFieldName}`; + }), + }, + }; + + mountOptions.global.mixins = [mockMixin]; + + const wrapper = shallowMount(review, mountOptions); + wrapper.vm.setCmsContent = jest.fn(); + return { wrapper }; +} From 5d79f79c8834aa291dc094d699721367ad7b23d0 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 23 Aug 2023 15:17:34 -0400 Subject: [PATCH 10/41] Formatting --- src/layouts/review/review.spec.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/layouts/review/review.spec.js b/src/layouts/review/review.spec.js index bd1bfc5b6..a4f82451d 100644 --- a/src/layouts/review/review.spec.js +++ b/src/layouts/review/review.spec.js @@ -235,17 +235,17 @@ describe("Review Page", () => { expect(isValid).toBe(false); }); test("Rejects null glassToReplace when not repair", () => { - // Arrange - store.getters.order.damage.isRepair = false; - store.getters.order.damage.glassToReplace = []; + // Arrange + store.getters.order.damage.isRepair = false; + store.getters.order.damage.glassToReplace = []; - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({}); - // Act - const isValid = wrapper.vm.arePagePrerequisitesValid(); + // Act + const isValid = wrapper.vm.arePagePrerequisitesValid(); - // Assert - expect(isValid).toBe(false); + // Assert + expect(isValid).toBe(false); }); }); describe("Package requirements", () => { From 3dd2fac254e80d8900c7298723f8b905aea2dc4b Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Thu, 24 Aug 2023 08:26:33 -0400 Subject: [PATCH 11/41] Added sonarqube support files --- .scannerwork/.sonar_lock | 0 .scannerwork/report-task.txt | 6 ++++++ sonar-project.properties | 10 ++++++++++ 3 files changed, 16 insertions(+) create mode 100644 .scannerwork/.sonar_lock create mode 100644 .scannerwork/report-task.txt create mode 100644 sonar-project.properties diff --git a/.scannerwork/.sonar_lock b/.scannerwork/.sonar_lock new file mode 100644 index 000000000..e69de29bb diff --git a/.scannerwork/report-task.txt b/.scannerwork/report-task.txt new file mode 100644 index 000000000..dbcf1e585 --- /dev/null +++ b/.scannerwork/report-task.txt @@ -0,0 +1,6 @@ +projectKey=DigitalConsumer.FixMyGlass +serverUrl=http://localhost:9000 +serverVersion=10.1.0.73491 +dashboardUrl=http://localhost:9000/dashboard?id=DigitalConsumer.FixMyGlass +ceTaskId=AYnlDa50m2ysCZ4aQNIX +ceTaskUrl=http://localhost:9000/api/ce/task?id=AYnlDa50m2ysCZ4aQNIX diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 000000000..c849286c4 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,10 @@ +# must be unique in a given SonarQube instance +sonar.projectKey=DigitalConsumer.FixMyGlass + +# --- optional properties --- + +# defaults to project key +sonar.projectName=DigitalConsumer.FixMyGlass + +# defaults to 'not provided' +sonar.projectVersion=1.0 \ No newline at end of file From 78c53d6777847b94baf6c2b75b99f7a8413ddd1d Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Thu, 24 Aug 2023 08:26:33 -0400 Subject: [PATCH 12/41] Revert "Added sonarqube support files" This reverts commit 3dd2fac254e80d8900c7298723f8b905aea2dc4b. --- .scannerwork/.sonar_lock | 0 .scannerwork/report-task.txt | 6 ------ sonar-project.properties | 10 ---------- 3 files changed, 16 deletions(-) delete mode 100644 .scannerwork/.sonar_lock delete mode 100644 .scannerwork/report-task.txt delete mode 100644 sonar-project.properties diff --git a/.scannerwork/.sonar_lock b/.scannerwork/.sonar_lock deleted file mode 100644 index e69de29bb..000000000 diff --git a/.scannerwork/report-task.txt b/.scannerwork/report-task.txt deleted file mode 100644 index dbcf1e585..000000000 --- a/.scannerwork/report-task.txt +++ /dev/null @@ -1,6 +0,0 @@ -projectKey=DigitalConsumer.FixMyGlass -serverUrl=http://localhost:9000 -serverVersion=10.1.0.73491 -dashboardUrl=http://localhost:9000/dashboard?id=DigitalConsumer.FixMyGlass -ceTaskId=AYnlDa50m2ysCZ4aQNIX -ceTaskUrl=http://localhost:9000/api/ce/task?id=AYnlDa50m2ysCZ4aQNIX diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index c849286c4..000000000 --- a/sonar-project.properties +++ /dev/null @@ -1,10 +0,0 @@ -# must be unique in a given SonarQube instance -sonar.projectKey=DigitalConsumer.FixMyGlass - -# --- optional properties --- - -# defaults to project key -sonar.projectName=DigitalConsumer.FixMyGlass - -# defaults to 'not provided' -sonar.projectVersion=1.0 \ No newline at end of file From 8b45d81cf75ce7d4716360a37c39702c350de5fe Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 24 Aug 2023 15:23:24 -0400 Subject: [PATCH 13/41] Add existing loading modal to text-links, off by default. --- src/ux-components/text-link/text-link.vue | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ux-components/text-link/text-link.vue b/src/ux-components/text-link/text-link.vue index 464143b65..b84d8ef7e 100644 --- a/src/ux-components/text-link/text-link.vue +++ b/src/ux-components/text-link/text-link.vue @@ -1,4 +1,5 @@ From f94e58cacb447cc4d6f626b40f03f10eaf2562df Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 24 Aug 2023 16:06:33 -0400 Subject: [PATCH 14/41] Enable loading spinner for some back-nav links --- src/fmg-components/funnel-footer/funnel-footer.vue | 1 + src/layouts/review/review-block/review-block.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index e093e43f9..1685bf573 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -20,6 +20,7 @@ From 4af89dc4379121388a3e7d9bffe2556800c993b7 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 24 Aug 2023 16:08:36 -0400 Subject: [PATCH 15/41] Change parameter name --- src/fmg-components/funnel-footer/funnel-footer.vue | 2 +- src/layouts/review/review-block/review-block.vue | 2 +- src/ux-components/text-link/text-link.vue | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fmg-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue index 1685bf573..448f15319 100644 --- a/src/fmg-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -20,7 +20,7 @@ diff --git a/src/ux-components/text-link/text-link.vue b/src/ux-components/text-link/text-link.vue index b84d8ef7e..d56c3253b 100644 --- a/src/ux-components/text-link/text-link.vue +++ b/src/ux-components/text-link/text-link.vue @@ -30,7 +30,7 @@ export default { href: { type: String, }, - displayLoadingModal: { + useLoadingModal: { type: Boolean, default: false, }, @@ -44,7 +44,7 @@ export default { true ); - if (this.displayLoadingModal) { + if (this.useLoadingModal) { this.$refs.loadingModal.showModal(); } From c9c96235d40e6db92a1f4e1c022cafb5651aea8b Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 24 Aug 2023 16:09:01 -0400 Subject: [PATCH 16/41] Tweak --- src/ux-components/text-link/text-link.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ux-components/text-link/text-link.vue b/src/ux-components/text-link/text-link.vue index d56c3253b..11e8db52c 100644 --- a/src/ux-components/text-link/text-link.vue +++ b/src/ux-components/text-link/text-link.vue @@ -1,5 +1,5 @@