From 8fbb9919892f133575cb9b0698ba6d720d52b416 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 11:58:01 -0400 Subject: [PATCH 01/10] conditionally show endorsement questions --- .../policy-endorsements.vue | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.vue b/src/layouts/policy-endorsements/policy-endorsements.vue index 22154818..e5644be9 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.vue +++ b/src/layouts/policy-endorsements/policy-endorsements.vue @@ -16,6 +16,7 @@ cmsWidgetName="SiteSubHeaderWidget" class="mt-5" /> Date: Wed, 11 Oct 2023 15:55:46 -0400 Subject: [PATCH 02/10] save endorsement questions, update navigation (cherry picked from commit f78e32a94e7e0a034032c1420b64e7ee878540a9) --- src/layouts/policy-vehicles/policy-vehicles.vue | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 8e08bd97..021772c6 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -117,13 +117,14 @@ export default { ? vehicle?.coverages[0].deductible : 0; }, - selectedVehicleHasEndorsements() { + endorsementsForSelectedVehicle() { const vehicle = this.policyVehicles.find((policyVehicle) => policyVehicle?.vin === this.selectedVehicleVin); - if (!vehicle) { - return false; + if (vehicle?.endorsements?.length > 0) { + + return vehicle.endorsements; } - return vehicle.endorsements?.length > 0; + return []; }, repairWaivedForSelectedVehicle() { const vehicle = this.policyVehicles.find((policyVehicle) => @@ -182,7 +183,8 @@ export default { vin: this.selectedVehicleVin, noCoverage: this.noCoverageForSelectedVehicle, deductible: this.deductibleForSelectedVehicle, - repairWaived: this.repairWaivedForSelectedVehicle + repairWaived: this.repairWaivedForSelectedVehicle, + endorsements: this.endorsementsForSelectedVehicle }); useMainStore().updateVehicle(this.vehicleFromLookup); @@ -205,7 +207,7 @@ export default { {}, {} ); - } else if (this.selectedVehicleHasEndorsements) { + } else if (this.endorsementsForSelectedVehicle?.length > 0) { this.$router.navigate( this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, this.$route From 72f5f1e9e6bb51452913ea0330c5b37aa14b0645 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 12:06:25 -0400 Subject: [PATCH 03/10] updates --- src/layouts/policy-vehicles/policy-vehicles.vue | 1 - src/store/index.js | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 021772c6..18ecfbf1 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -121,7 +121,6 @@ export default { const vehicle = this.policyVehicles.find((policyVehicle) => policyVehicle?.vin === this.selectedVehicleVin); if (vehicle?.endorsements?.length > 0) { - return vehicle.endorsements; } return []; diff --git a/src/store/index.js b/src/store/index.js index b9d40f81..54dc38e5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -76,6 +76,7 @@ const getDefaultState = () => ({ }, isITAC: null, vehicles: [], + endorsements: [], endorsementQuestionAnswers: null }, customer: { @@ -1168,6 +1169,7 @@ export const useMainStore = defineStore({ : coverageStatuses.PENDING; this.order.policy.deductible.replace = vehicle.deductible; this.order.policy.deductible.repair = vehicle?.repairWaived ?? false ? 0 : vehicle.deductible; + this.order.policy.endorsements = vehicle?.endorsements; // TODO logic should be more complicated later on this.order.originalDeductible = parseFloat(vehicle.deductible); From 0b6607177dc4f4caea0282d1d8d9c392f37cb0d3 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 12:55:30 -0400 Subject: [PATCH 04/10] styling fix --- src/layouts/policy-endorsements/policy-endorsements.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.vue b/src/layouts/policy-endorsements/policy-endorsements.vue index e5644be9..d1f4ab47 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.vue +++ b/src/layouts/policy-endorsements/policy-endorsements.vue @@ -45,7 +45,6 @@ Date: Thu, 12 Oct 2023 13:27:28 -0400 Subject: [PATCH 05/10] unit test updates - test computed properties --- .../policy-endorsements.spec.js | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.spec.js b/src/layouts/policy-endorsements/policy-endorsements.spec.js index 86b8fa73..41202415 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.spec.js +++ b/src/layouts/policy-endorsements/policy-endorsements.spec.js @@ -8,6 +8,23 @@ import navigationScenarios from '@/router/router-constants/navigation-scenarios' import { createTestingPinia } from '@pinia/testing'; import { useMainStore } from '@/store'; +function getMountedComponent(mainInitialState = {}, initialData = {}) { + const mountOptions = getMountOptions({ + router: { + navigate: jest.fn() + } + }); + + mountOptions.global.plugins = [createTestingPinia({ + initialState: { + main: mainInitialState + } + })]; + + const wrapper = shallowMount(policyEndorsements, mountOptions); + return { wrapper }; +} + describe('policyEndorsements.vue', () => { describe('Rendering', () => { test('Should render site header', () => { @@ -30,24 +47,36 @@ describe('policyEndorsements.vue', () => { // Assert expect(siteSubHeader.exists()).toBe(true); }); - test('Should render schoolProperty buttonQuestion component', () => { + test('Should render schoolProperty buttonQuestion component if policy vehicle has Educator endorsement', () => { // Arrange - const wrapper = shallowMount(policyEndorsements, getMountOptions()); - - // Act + const mainInitialState = { + order: { + policy: { + endorsements: ['Educator'] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' }); // Assert + expect(wrapper.vm.educatorEndorsement).toBeTruthy(); expect(buttonQuestion.exists()).toBe(true); }); - test('Should render parkingLot buttonQuestion component', () => { + test('Should render parkingLot buttonQuestion component if policy vehicle has Parking Guard endorsement', () => { // Arrange - const wrapper = shallowMount(policyEndorsements, getMountOptions()); - - // Act + const mainInitialState = { + order: { + policy: { + endorsements: ['Parking Guard'] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' }); // Assert + expect(wrapper.vm.parkingGuardEndorsement).toBeTruthy(); expect(buttonQuestion.exists()).toBe(true); }); test('Should render site footer', () => { From a9c42b099e40ea5c3340c8bff7e8aae7a5b292b2 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 14:25:48 -0400 Subject: [PATCH 06/10] linting fix --- src/layouts/policy-endorsements/policy-endorsements.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.spec.js b/src/layouts/policy-endorsements/policy-endorsements.spec.js index 41202415..05031717 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.spec.js +++ b/src/layouts/policy-endorsements/policy-endorsements.spec.js @@ -8,7 +8,7 @@ import navigationScenarios from '@/router/router-constants/navigation-scenarios' import { createTestingPinia } from '@pinia/testing'; import { useMainStore } from '@/store'; -function getMountedComponent(mainInitialState = {}, initialData = {}) { +function getMountedComponent(mainInitialState = {}) { const mountOptions = getMountOptions({ router: { navigate: jest.fn() From 54c760830f77da8ddfdc778fcc1e674250f51668 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 15:40:36 -0400 Subject: [PATCH 07/10] unit test for nav scenario --- .../policy-vehicles/policy-vehicles.spec.js | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.spec.js b/src/layouts/policy-vehicles/policy-vehicles.spec.js index 14518679..0ea0770f 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.spec.js +++ b/src/layouts/policy-vehicles/policy-vehicles.spec.js @@ -117,7 +117,8 @@ describe('policy-vehicles.vue', () => { vin, noCoverage: true, deductible: 0, - repairWaived: false + repairWaived: false, + endorsements: [] }; // Act @@ -135,6 +136,57 @@ describe('policy-vehicles.vue', () => { } ); + test( + // eslint-disable-next-line max-len + 'Selected VIN matches vehicle listed in system and policy vehicle has endorsements => update vehicle and navigate forward with CLICKED_FORWARD_WITH_ENDORSEMENTS scenario.', + async () => { + // Arrange + const { wrapper } = setupMocks({}); + + const vin = getRandomString(17, 17); + const endorsements = [getRandomString(10, 20)]; + await wrapper.setData({ + selectedVehicleVin: vin, + policyVehicles: [ + { + vin, + endorsements + } + ], + bailout: false + }); + + const year = getRandomInt(1998, 2023); + const lookupVehicleResponse = { + data: { + year + } + }; + const store = useMainStore(); + store.lookupVehicleByVin.mockReturnValue(Promise.resolve(lookupVehicleResponse)); + + const expectedInput = { + year, + vin, + noCoverage: true, + deductible: 0, + repairWaived: false, + endorsements + }; + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.bailout).toBeFalsy(); + expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput); + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, + undefined + ); + } + ); + test( 'Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', async () => { From 20a9af13bac66b75dc6a4dfc84488938c41806dd Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Thu, 12 Oct 2023 20:40:32 -0400 Subject: [PATCH 08/10] PR changes --- .../policy-endorsements.spec.js | 33 +++++++++++++++++++ .../policy-endorsements.vue | 4 +-- .../policy-vehicles/policy-vehicles.spec.js | 4 +-- src/store/store.spec.js | 14 +++++--- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.spec.js b/src/layouts/policy-endorsements/policy-endorsements.spec.js index 05031717..c01818f5 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.spec.js +++ b/src/layouts/policy-endorsements/policy-endorsements.spec.js @@ -7,6 +7,7 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios'; import { createTestingPinia } from '@pinia/testing'; import { useMainStore } from '@/store'; +import { getRandomString } from '@/helpers/data-generation'; function getMountedComponent(mainInitialState = {}) { const mountOptions = getMountOptions({ @@ -63,6 +64,22 @@ describe('policyEndorsements.vue', () => { expect(wrapper.vm.educatorEndorsement).toBeTruthy(); expect(buttonQuestion.exists()).toBe(true); }); + test('Should not render schoolProperty buttonQuestion component if policy vehicle does not have Educator endorsement', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + endorsements: [getRandomString(20, 30)] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' }); + + // Assert + expect(wrapper.vm.educatorEndorsement).toBeFalsy(); + expect(buttonQuestion.exists()).toBe(false); + }); test('Should render parkingLot buttonQuestion component if policy vehicle has Parking Guard endorsement', () => { // Arrange const mainInitialState = { @@ -79,6 +96,22 @@ describe('policyEndorsements.vue', () => { expect(wrapper.vm.parkingGuardEndorsement).toBeTruthy(); expect(buttonQuestion.exists()).toBe(true); }); + test('Should not render parkingLot buttonQuestion component if policy vehicle does not have Parking Guard endorsement', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + endorsements: [getRandomString(20, 30)] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' }); + + // Assert + expect(wrapper.vm.parkingGuardEndorsement).toBeFalsy(); + expect(buttonQuestion.exists()).toBe(false); + }); test('Should render site footer', () => { // Arrange const wrapper = shallowMount(policyEndorsements, getMountOptions()); diff --git a/src/layouts/policy-endorsements/policy-endorsements.vue b/src/layouts/policy-endorsements/policy-endorsements.vue index d1f4ab47..809854f4 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.vue +++ b/src/layouts/policy-endorsements/policy-endorsements.vue @@ -120,10 +120,10 @@ export default { return this.getCmsContent('ParkingLotQuestion', 'Answers'); }, educatorEndorsement() { - return useMainStore().order.policy.endorsements.includes('Educator'); + return useMainStore().order.policy.endorsements?.includes('Educator'); }, parkingGuardEndorsement() { - return useMainStore().order.policy.endorsements.includes('Parking Guard'); + return useMainStore().order.policy.endorsements?.includes('Parking Guard'); } }, methods: diff --git a/src/layouts/policy-vehicles/policy-vehicles.spec.js b/src/layouts/policy-vehicles/policy-vehicles.spec.js index 0ea0770f..39b50c15 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.spec.js +++ b/src/layouts/policy-vehicles/policy-vehicles.spec.js @@ -152,8 +152,7 @@ describe('policy-vehicles.vue', () => { vin, endorsements } - ], - bailout: false + ] }); const year = getRandomInt(1998, 2023); @@ -178,7 +177,6 @@ describe('policy-vehicles.vue', () => { await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.bailout).toBeFalsy(); expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput); expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index fd728d27..9fc8f865 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -153,10 +153,12 @@ describe('Store', () => { // Arrange const noCoverage = getRandomBoolean(); const deductible = getRandomInt(1, 500); + const endorsements = [getRandomString(10, 20)]; const vehicle = { noCoverage, deductible, - repairWaived: true + repairWaived: true, + endorsements }; const expectedPolicy = { @@ -164,7 +166,8 @@ describe('Store', () => { deductible: { replace: deductible, repair: 0 - } + }, + endorsements }; // Act @@ -178,10 +181,12 @@ describe('Store', () => { // Arrange const noCoverage = getRandomBoolean(); const deductible = getRandomInt(1, 500); + const endorsements = [getRandomString(10, 20)]; const vehicle = { noCoverage, deductible, - repairWaived: false + repairWaived: false, + endorsements }; const expectedPolicy = { @@ -189,7 +194,8 @@ describe('Store', () => { deductible: { replace: deductible, repair: deductible - } + }, + endorsements }; // Act From 31f7f072e70b60f8262c05eb283ff7ec25141ac1 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Fri, 13 Oct 2023 14:12:43 -0400 Subject: [PATCH 09/10] unit tests for endorsements computed --- .../policy-vehicles/policy-vehicles.spec.js | 114 ++++++++++++++++++ .../policy-vehicles/policy-vehicles.vue | 10 +- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/src/layouts/policy-vehicles/policy-vehicles.spec.js b/src/layouts/policy-vehicles/policy-vehicles.spec.js index 39b50c15..6bb10a35 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.spec.js +++ b/src/layouts/policy-vehicles/policy-vehicles.spec.js @@ -458,6 +458,120 @@ describe('policy-vehicles.vue', () => { }); }); + describe('endorsementsForSelectedVehicle computed property', () => { + it('policyVehicles is null => empty endorsements array returned', () => { + // Arrange + const testValues = { + policyVehicles: null + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + const expected = []; + + // Assert + expect(result).toStrictEqual(expected); + }); + + it('policyVehicles is empty => empty endorsements array returned', () => { + // Arrange + const testValues = { + policyVehicles: [] + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + const expected = []; + + // Assert + expect(result).toStrictEqual(expected); + }); + + it('selectedVehicleVin does not match any vin in policyVehicles => empty endorsements array returned', () => { + // Arrange + const selectedVin = getRandomString(17, 17); + const otherVin = getRandomString(17, 17); + const testValues = { + selectedVehicleVin: selectedVin, + policyVehicles: [ + { + vin: otherVin + } + ] + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + const expected = []; + + // Assert + expect(result).toStrictEqual(expected); + }); + + it('vehicle VIN match with endorsements null => empty endorsements array returned', () => { + // Arrange + const vin = getRandomString(17, 17); + const testValues = { + selectedVehicleVin: vin, + policyVehicles: [ + { + vin, + endorsements: null + } + ] + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + const expected = []; + + // Assert + expect(result).toStrictEqual(expected); + }); + + it('vehicle VIN match with empty endorsements => empty endorsements array returned', () => { + // Arrange + const vin = getRandomString(17, 17); + const testValues = { + selectedVehicleVin: vin, + policyVehicles: [ + { + vin, + endorsements: [] + } + ] + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + const expected = []; + + // Assert + expect(result).toStrictEqual(expected); + }); + + it('vehicle VIN match with endorsements => endorsements array returned', () => { + // Arrange + const vin = getRandomString(17, 17); + const endorsements = [getRandomString(10, 20)]; + const testValues = { + selectedVehicleVin: vin, + policyVehicles: [ + { + vin, + endorsements + } + ] + }; + + // Act + const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues); + + // Assert + expect(result).toStrictEqual(endorsements); + }); + }); + test('first vehicle is auto-selected if only one vehicle on policy', async () => { // Arrange const vin = getRandomString(17, 17); diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 18ecfbf1..8ea67941 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -102,12 +102,12 @@ export default { return mappedData; }, noCoverageForSelectedVehicle() { - const vehicle = this.policyVehicles.find((policyVehicle) => + const vehicle = this.policyVehicles?.find((policyVehicle) => policyVehicle.vin === this.selectedVehicleVin); return (vehicle?.coverages?.length ?? 0) === 0; }, deductibleForSelectedVehicle() { - const vehicle = this.policyVehicles.find((policyVehicle) => + const vehicle = this.policyVehicles?.find((policyVehicle) => policyVehicle?.vin === this.selectedVehicleVin); if (!vehicle) { return undefined; @@ -118,7 +118,7 @@ export default { : 0; }, endorsementsForSelectedVehicle() { - const vehicle = this.policyVehicles.find((policyVehicle) => + const vehicle = this.policyVehicles?.find((policyVehicle) => policyVehicle?.vin === this.selectedVehicleVin); if (vehicle?.endorsements?.length > 0) { return vehicle.endorsements; @@ -126,7 +126,7 @@ export default { return []; }, repairWaivedForSelectedVehicle() { - const vehicle = this.policyVehicles.find((policyVehicle) => + const vehicle = this.policyVehicles?.find((policyVehicle) => policyVehicle.vin === this.selectedVehicleVin); return vehicle?.endorsements?.includes(endorsementOptions.REPAIR_WAIVED) ?? false; }, @@ -161,7 +161,7 @@ export default { }, beforeMount() { if (this.policyVehicles?.length === 1) { - this.selectedVehicleVin = this.policyVehicles[0].vin; + this.selectedVehicleVin = this.policyVehicles[0]?.vin; } }, methods: From bcbad4725ad94e9f48fba5d0939fd3c6d73f6b62 Mon Sep 17 00:00:00 2001 From: Katie Kroell Date: Fri, 13 Oct 2023 15:06:29 -0400 Subject: [PATCH 10/10] return false from computeds --- src/layouts/policy-endorsements/policy-endorsements.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/policy-endorsements/policy-endorsements.vue b/src/layouts/policy-endorsements/policy-endorsements.vue index 809854f4..1d4e1972 100644 --- a/src/layouts/policy-endorsements/policy-endorsements.vue +++ b/src/layouts/policy-endorsements/policy-endorsements.vue @@ -120,10 +120,10 @@ export default { return this.getCmsContent('ParkingLotQuestion', 'Answers'); }, educatorEndorsement() { - return useMainStore().order.policy.endorsements?.includes('Educator'); + return useMainStore().order.policy.endorsements?.includes('Educator') ?? false; }, parkingGuardEndorsement() { - return useMainStore().order.policy.endorsements?.includes('Parking Guard'); + return useMainStore().order.policy.endorsements?.includes('Parking Guard') ?? false; } }, methods: