diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 3e6a617e..8f21cdd9 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -117,7 +117,7 @@ const endpoints = Object.freeze({ method: 'GET' }, TaxOrderItems: { - url: '/price/api/v1/price/taxed-order-items', + url: `${PRICE_BASE_URL}/taxed-order-items`, method: 'GET' }, LogExperimentExposureIfAssigned: { diff --git a/src/helpers/price-calculator.js b/src/helpers/price-calculator.js new file mode 100644 index 00000000..b44abc5a --- /dev/null +++ b/src/helpers/price-calculator.js @@ -0,0 +1,12 @@ +function getPriceOfLineItem(lineItem) { + return (lineItem?.kitPrice ?? 0) + + (lineItem?.laborAmount ?? 0) + + (lineItem?.sellingPrice ?? 0); +} + +export default function getPriceOfLineItems(lineItems) { + return lineItems.reduce( + (accumulator, lineItem) => accumulator + getPriceOfLineItem(lineItem), + 0 + ); +} diff --git a/src/helpers/price-calculator.spec.js b/src/helpers/price-calculator.spec.js new file mode 100644 index 00000000..4d09128b --- /dev/null +++ b/src/helpers/price-calculator.spec.js @@ -0,0 +1,56 @@ +import getPriceOfLineItems from "@/helpers/price-calculator.js"; + +describe('getPriceOfLineItems', () => { + test('Returns zero when no line items', () => { + // Arrange + const lineItems = []; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(0); + }); + test('Returns expected when one line item', () => { + // Arrange + const lineItems = [ + { + kitPrice: 1, + laborAmount: 2, + sellingPrice: 3 + } + ]; + const expected = 6; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(expected); + }); + test('Returns expected when multiple line items', () => { + // Arrange + const lineItems = [ + { + kitPrice: 1, + laborAmount: 2, + sellingPrice: 3 + }, + { + kitPrice: 1 + }, + { + kitPrice: 10, + laborAmount: 100, + sellingPrice: 1000 + } + ]; + const expected = 1117; + + // Act + const result = getPriceOfLineItems(lineItems); + + // Assert + expect(result).toBe(expected); + }); +}); diff --git a/src/iss-components/vehicle-banner/vehicle-banner.vue b/src/iss-components/vehicle-banner/vehicle-banner.vue index 387118c1..fd4010f9 100644 --- a/src/iss-components/vehicle-banner/vehicle-banner.vue +++ b/src/iss-components/vehicle-banner/vehicle-banner.vue @@ -23,12 +23,9 @@ export default { return this.genericVehicleImage; } - let imageUrl = ''; - if (this.mainStore.hasSubmittedOrder()) { - imageUrl = this.mainStore.submittedOrder.vehicle.imageUrl; - } else { - imageUrl = this.mainStore.order.vehicle.imageUrl; - } + const imageUrl = (this.mainStore.hasSubmittedOrder()) + ? this.mainStore.submittedOrder.vehicle.imageUrl + : this.mainStore.order.vehicle.imageUrl; if (!imageUrl || imageUrl === 'NULL') { return this.getUnmatchedVehicleIcon(); diff --git a/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap b/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap new file mode 100644 index 00000000..aca040ba --- /dev/null +++ b/src/layouts/coverage-statement/__snapshots__/coverage-statement.spec.js.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`coverageStatement.vue-working returns the initial data 1`] = ` +Object { + "baseServiceLineItems": Array [], + "currencyFormatter": NumberFormat {}, + "deductibleText": "Your deductible is", + "isNoComp": false, + "isRepair": true, + "loadingText": Array [ + "Connecting to your insurance company", + "Nearly there", + "Finishing up", + ], + "policyLookupSuccessful": true, + "rules": Object { + "selectionRequired": "option-required", + }, + "selectedProvider": "", + "supportingItems": null, + "widget": Object { + "explanatoryText": "ExplanatoryTextWidget", + "nextStep": "NextStepsWidget", + "serviceProviderQuestion": "ServiceProviderQuestion", + "subheader": "SiteSubHeaderWidget", + "verifiedItacAlert": "VerifiedITACAlert", + }, +} +`; diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js index a597b7f9..65cfd347 100644 --- a/src/layouts/coverage-statement/coverage-statement.spec.js +++ b/src/layouts/coverage-statement/coverage-statement.spec.js @@ -3,17 +3,18 @@ import coverageStatement from '@/layouts/coverage-statement/coverage-statement.v // Supporting Files import { nextTick } from 'vue'; -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { createTestingPinia } from '@pinia/testing'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js'; import { getRandomString, getRandomInt } from '@/helpers/data-generation.js'; import settleAllPromises from '@/helpers/layout-helper.js'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; -import routerParams from '@/router/router-constants/router-params'; import { useMainStore } from '@/store/index.js'; +import getPriceOfLineItems from '@/helpers/price-calculator.js'; jest.mock('@/helpers/layout-helper.js', () => jest.fn()); +jest.mock('@/helpers/price-calculator.js', () => jest.fn()); jest.mock('@/helpers/cms-content-helper', () => ({ fetchCmsContentForPage: jest.fn(), @@ -21,10 +22,15 @@ jest.mock('@/helpers/cms-content-helper', () => ({ processIfStatements: jest.fn() })); +const SAFELITE_PROVIDER = 'Safelite'; + const mockMixin = { methods: { getCmsContent: jest.fn().mockImplementation(() => ''), - setCmsContent: jest.fn() + setCmsContent: jest.fn(), + onSubmit: jest.fn(), + onInvalidSubmit: jest.fn(), + navigateBackByVehicleQuestions: jest.fn() } }; @@ -51,6 +57,7 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu }); mountOptions.global.stubs = { + ...mountOptions.global.stubs, siteFooter: footerStub, siteHeader: true, recalModal: true, @@ -79,44 +86,28 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu settleAllPromises.mockImplementation(() => apiPromise); fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); - const wrapper = mount(coverageStatement, mountOptions); + const wrapper = shallowMount(coverageStatement, mountOptions); return { wrapper }; } -describe.skip('coverageStatement.vue', () => { - describe('method arePagePrerequisitesValid...', () => { - test('Should return true for valid page requisites if vin exists', () => { - // Arrange - const { wrapper } = getMountedComponent({ - order: { - vehicle: { - vin: getRandomString(5, 20) - } +describe('coverageStatement.vue-working', () => { + test('returns the initial data', () => { + // Arrange + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + policyLookupSuccessful: true, + noCoverage: false } - }); + } + }; + const { wrapper } = getMountedComponent(mainInitialState); - // Act - const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); - - // Assert - expect(arePagePrerequisitesValid).toBeTruthy(); - }); - test('Should return false for valid page requisites if vin is missing', () => { - // Arrange - const { wrapper } = getMountedComponent({ - order: { - vehicle: { - vin: null - } - } - }); - - // Act - const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); - - // Assert - expect(arePagePrerequisitesValid).not.toBeTruthy(); - }); + // Assert + expect(wrapper.vm.$data).toMatchSnapshot(); }); describe('Rendering', () => { test('Should render site header', () => { @@ -171,663 +162,920 @@ describe.skip('coverageStatement.vue', () => { expect(footer.exists()).toBe(true); }); }); - describe('Verified ITAC scenario', () => { - test('If policy lookup successful, not No Comp, and deductible > service price, verifiedITAC returns true', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice + 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible - }, - policyLookupSuccessful: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] - }); - - // Assert - expect(wrapper.vm.verifiedITAC).toBeTruthy(); - }); - test('If policy lookup unsuccessful, verifiedITAC returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - policyLookupSuccessful: false - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedITAC).toBeFalsy(); - }); - test('If No Comp, verifiedITAC returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedITAC).toBeFalsy(); - }); - test('If deductible < service price, verifiedITAC returns false', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice - 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + describe('Computed', () => { + describe('verifiedNoComp', () => { + test.each([true, false])('returns false when policyLookupSuccessful false', (isNoComp) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: isNoComp, + policyLookupSuccessful: false } } - } - }; + }; + const { wrapper } = getMountedComponent(mainInitialState); - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] + // Act + const result = wrapper.vm.verifiedNoComp; + + // Assert + expect(result).toBeFalsy(); }); - - // Assert - expect(wrapper.vm.verifiedITAC).toBeFalsy(); - }); - }); - describe('Verified Deductible scenario', () => { - test('If policy lookup successful, not No Comp, and service price > deductible, verifiedITAC returns true', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice - 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible - }, - policyLookupSuccessful: true - } - } - }; - - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] - }); - - // Assert - expect(wrapper.vm.verifiedDeductible).toBeTruthy(); - }); - test('If policy lookup unsuccessful, verifiedDeductible returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - policyLookupSuccessful: false - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedDeductible).toBeFalsy(); - }); - test('If No Comp, verifiedDeductible returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedDeductible).toBeFalsy(); - }); - test('If service price < deductible, verifiedDeductible returns false', () => { - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice + 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + test.each([true, false])('returns false when isNoComp false', (policyLookupSuccessful) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: false, + policyLookupSuccessful } } - } - }; + }; + const { wrapper } = getMountedComponent(mainInitialState); - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] + // Act + const result = wrapper.vm.verifiedNoComp; + + // Assert + expect(result).toBeFalsy(); }); - - // Assert - expect(wrapper.vm.verifiedDeductible).toBeFalsy(); - }); - test('If deductible is null, verifiedDeductible returns false', () => { - const sellingPrice = getRandomInt(100, 500); - const deductible = null; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + test('returns true when policyLookupSuccessful true and policyLookupSuccessful true', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: true, + policyLookupSuccessful: true } } - } - }; + }; + const { wrapper } = getMountedComponent(mainInitialState); - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] + // Act + const result = wrapper.vm.verifiedNoComp; + + // Assert + expect(result).toBeTruthy(); }); - - // Assert - expect(wrapper.vm.verifiedDeductible).toBeFalsy(); }); - }); - describe('No Comp scenario', () => { - test('If noCoverage = true, verifiedNoComp returns true', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: true, - policyLookupSuccessful: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedNoComp).toBeTruthy(); - }); - test('If noCoverage = false, verifiedNoComp returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.verifiedNoComp).toBeFalsy(); - }); - }); - describe('Unverified scenario', () => { - test('If policyLookupSuccessful false, unverified returns true', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - policyLookupSuccessful: false - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.unverified).toBeTruthy(); - }); - test('If policyLookupSuccessful is true, unverified returns false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - policyLookupSuccessful: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Assert - expect(wrapper.vm.unverified).toBeFalsy(); - }); - }); - describe('Navigation', () => { - test('If Unverified, navigate forward with CLICKED_FORWARD scenario', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - policyLookupSuccessful: false - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('If Verified Deductible, navigate forward with CLICKED_FORWARD scenario', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice - 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + describe('verifiedITAC', () => { + const priceOfLineItems = 213; + test.each([true, false])('returns false when policyLookupSuccessful false', (isNoComp) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: isNoComp, + policyLookupSuccessful: false }, - policyLookupSuccessful: true + currentDeductible: priceOfLineItems + 1 } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ] + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedITAC; + + // Assert + expect(result).toBeFalsy(); }); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('If Verified ITAC and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice + 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + test.each([true, false])('returns false when isNoComp true', (policyLookupSuccessful) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: true, + policyLookupSuccessful }, - policyLookupSuccessful: true + currentDeductible: priceOfLineItems + 1 } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ], - selectedProvider: 'Safelite' + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedITAC; + + // Assert + expect(result).toBeFalsy(); }); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('If Verified ITAC, selected other shop, and TPA enabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_ENABLED', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice + 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + test.each([ + [true, false], + [true, true], + [false, false], + [false, true] + ])('returns false when deductibleValue equals totalServicePrice', (noCoverage, policyLookupSuccessful) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage, + policyLookupSuccessful }, - policyLookupSuccessful: true + currentDeductible: priceOfLineItems } - }, - issConfig: { - enableTPAFlow: true - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ], - selectedProvider: 'Other' + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedITAC; + + // Assert + expect(result).toBeFalsy(); }); + test.each([ + [true, false], + [true, true], + [false, false], + [false, true] + ])( + 'returns false when deductibleValue less than totalServicePrice when noCoverage is %p and policyLookupSuccessful is %p', + (noCoverage, policyLookupSuccessful) => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage, + policyLookupSuccessful + }, + currentDeductible: priceOfLineItems - 1 + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); - // Act - wrapper.vm.forwardButtonAction(); + // Act + const result = wrapper.vm.verifiedITAC; - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('If Verified ITAC, selected other shop, and TPA disabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_DISABLED', () => { - // Arrange - const sellingPrice = getRandomInt(100, 500); - const deductible = sellingPrice + 1; - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: false, - deductible: { - repair: deductible + // Assert + expect(result).toBeFalsy(); + } + ); + test('returns true when deductibleValue more than totalServicePrice, noComp is false, and policyLookupSuccessful true', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + noCoverage: false, + policyLookupSuccessful: true }, - policyLookupSuccessful: true + currentDeductible: priceOfLineItems + 1 } - }, - issConfig: { - enableTPAFlow: false - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - availableLineItems: [ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 - } - ], - selectedProvider: 'Other' + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedITAC; + + // Assert + expect(result).toBeTruthy(); }); - - // Act - wrapper.vm.forwardButtonAction(); - - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); }); - test('If No Comp and selected Safelite, navigate forward with CLICKED_FORWARD scenario', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true - }, - policy: { - noCoverage: true, - policyLookupSuccessful: true - } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); - wrapper.setData({ - isVerified: false, - selectedProvider: 'Safelite' + describe('verifiedDeductible', () => { + const servicePrice = 123; + describe('claim registration required', () => { + const issConfig = { isClaimRegistrationRequired: true }; + let verifiedDeductibleStoreState; + beforeEach(() => { + verifiedDeductibleStoreState = { + issConfig, + order: { + payment: { + insuranceCoverage: { + isVerified: true + } + }, + policy: { + noCoverage: false, + policyLookupSuccessful: false + }, + currentDeductible: servicePrice - 1 + } + }; + getPriceOfLineItems.mockImplementation(() => servicePrice); + }); + test('returns false when deductible is null', () => { + // Arrange + const mainInitialState = verifiedDeductibleStoreState; + mainInitialState.order.currentDeductible = null; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when register claim not successful', () => { + // Arrange + const mainInitialState = verifiedDeductibleStoreState; + mainInitialState.order.payment.insuranceCoverage.isVerified = false; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns true when register claim successful, isNoComp false, and service price over deductible', () => { + // Arrange + const { wrapper } = getMountedComponent(verifiedDeductibleStoreState); + + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeTruthy(); + }); }); + describe('claim registration not required', () => { + const issConfig = { isClaimRegistrationRequired: false }; + let verifiedDeductibleStoreState; + beforeEach(() => { + verifiedDeductibleStoreState = { + issConfig, + order: { + payment: { + insuranceCoverage: { + isVerified: false + } + }, + policy: { + noCoverage: false, + policyLookupSuccessful: true + }, + currentDeductible: servicePrice - 1 + } + }; + }); + test('returns false when policy lookup not successful', () => { + // Arrange + const mainInitialState = verifiedDeductibleStoreState; + mainInitialState.order.policy.policyLookupSuccessful = false; + const { wrapper } = getMountedComponent(mainInitialState); - // Act - wrapper.vm.forwardButtonAction(); + // Act + const result = wrapper.vm.verifiedDeductible; - // Assert - expect(wrapper.vm.$router.navigate) - .toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - }); - describe('ADAS', () => { - test('if Replace and parts require recalibration, isADAS should return true', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: false + // Assert + expect(result).toBeFalsy(); + }); + test('returns true when policyLookupSuccessful, isNoComp false, and deductible over service price', () => { + // Arrange + const { wrapper } = getMountedComponent(verifiedDeductibleStoreState); + + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeTruthy(); + }); + }); + test('returns false when isNoComp true', () => { + // Arrange + const isNoComp = true; + const storeState = { + issConfig: { + isClaimRegistrationRequired: false }, - lineItems: { - glassParts: [ - { - requiresRecalibration: true + order: { + payment: { + insuranceCoverage: { + isVerified: true } - ] + }, + policy: { + noCoverage: isNoComp, + policyLookupSuccessful: true + }, + currentDeductible: servicePrice - 1 } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); + }; + const { wrapper } = getMountedComponent(storeState); - // Assert - expect(wrapper.vm.isADAS).toBeTruthy(); - }); - test('if Replace and parts do not require recalibration, isADAS should return false', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: false + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when service price below deductible', () => { + // Arrange + const storeState = { + issConfig: { + isClaimRegistrationRequired: false }, - lineItems: { - glassParts: [ - { - requiresRecalibration: false + order: { + payment: { + insuranceCoverage: { + isVerified: true } - ] + }, + policy: { + noCoverage: false, + policyLookupSuccessful: true + }, + currentDeductible: servicePrice + 1 } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); + }; + const { wrapper } = getMountedComponent(storeState); - // Assert - expect(wrapper.vm.isADAS).toBeFalsy(); + // Act + const result = wrapper.vm.verifiedDeductible; + + // Assert + expect(result).toBeFalsy(); + }); }); - test('if Repair, isADAS should return true', () => { - // Arrange - const mainInitialState = { - order: { - damage: { - isRepair: true + describe('isADAS', () => { + test('returns false when glassParts null', () => { + // Arrange + const mainInitialState = { + order: { + lineItems: { + glassParts: null + } } - } - }; - const { wrapper } = getMountedComponent(mainInitialState); + }; + const { wrapper } = getMountedComponent(mainInitialState); - // Assert - expect(wrapper.vm.isADAS).toBeFalsy(); + // Act + const result = wrapper.vm.isADAS; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when glassParts empty', () => { + // Arrange + const mainInitialState = { + order: { + lineItems: { + glassParts: [] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isADAS; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when no parts in glassParts require recalibration', () => { + // Arrange + const mainInitialState = { + order: { + lineItems: { + glassParts: [ + { + partNumber: 123, + requiresRecalibration: false + }, + { + partNumber: 111, + requiresRecalibration: false + } + ] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isADAS; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns true when a part in glassParts require recalibration', () => { + // Arrange + const mainInitialState = { + order: { + lineItems: { + glassParts: [ + { + partNumber: 123, + requiresRecalibration: true + }, + { + partNumber: 111, + requiresRecalibration: false + } + ] + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isADAS; + + // Assert + expect(result).toBeTruthy(); + }); + }); + describe('isQuoteDisplayed', () => { + test('returns false when policy lookup not successful', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: false + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeFalsy(); + }); + describe('not no comp', () => { + const priceOfLineItems = 341; + test('returns false when deductible equal to service price', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + currentDeductible: priceOfLineItems + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when deductible less than service price', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + currentDeductible: priceOfLineItems - 1 + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns true when policy lookup successful and deductible over service price', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + currentDeductible: priceOfLineItems + 1 + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeTruthy(); + }); + }); + describe('not itac', () => { + const priceOfLineItems = 23; + test('returns false when isNoComp false', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + currentDeductible: priceOfLineItems + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns true when isNoComp true', () => { + // Arrange + const mainInitialState = { + order: { + policy: { + policyLookupSuccessful: true, + noCoverage: true + }, + currentDeductible: priceOfLineItems + } + }; + getPriceOfLineItems.mockImplementationOnce(() => priceOfLineItems); + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.isQuoteDisplayed; + + // Assert + expect(result).toBeTruthy(); + }); + }); + }); + describe.each([[0], [12]])('shouldRegisterClaim', (policyVehicleId) => { + const servicePrice = 90; + let shouldRegisterClaimStoreStateItac; + beforeEach(() => { + shouldRegisterClaimStoreStateItac = { + order: { + payment: { + insuranceCoverage: { claimNumber: null } + }, + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + vehicle: { + policyVehicleId + }, + currentDeductible: servicePrice - 1 + }, + issConfig: { + isClaimRegistrationRequired: true + } + }; + getPriceOfLineItems.mockImplementation(() => servicePrice); + }); + test('returns false when policy lookup not successful', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.order.policy.policyLookupSuccessful = false; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when policy vehicle id is less than 0', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.order.vehicle.policyVehicleId = -3; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when policy vehicle id is null', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.order.vehicle.policyVehicleId = null; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when claim registration is not required', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.issConfig.isClaimRegistrationRequired = false; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when claim already registered', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.order.payment.insuranceCoverage.claimNumber = 13; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false when no comp', () => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.order.policy.noCoverage = true; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeFalsy(); + }); + describe('returns true when policy lookup success, vehicleId set to %p, claim reg req, claim not yet reg', () => { + test('and itac', () => { + // Arrange + const { wrapper } = getMountedComponent(shouldRegisterClaimStoreStateItac); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeTruthy(); + }); + test.each([ + [servicePrice], + [servicePrice + 1] + ])('and deductible case', (deductibleValue) => { + // Arrange + const mainInitialState = shouldRegisterClaimStoreStateItac; + mainInitialState.currentDeductible = deductibleValue; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.shouldRegisterClaim; + + // Assert + expect(result).toBeTruthy(); + }); + }); }); }); - describe('claim registration api call', () => { - it('claim registration not required => method not called', async () => { - // Arrange - const { wrapper } = getMountedComponent({ - issConfig: { - isClaimRegistrationRequired: false - } - }); - - // Assert - expect(wrapper.vm.mainStore.registerClaim).not.toHaveBeenCalled(); - }); - - it('claim registration required => register claim method called', async () => { - // Arrange - const sellingPrice = getRandomInt(50, 100); - const deductible = sellingPrice - 1; - const initialStore = { - order: { - policy: { - policyLookupSuccessful: true, - noCoverage: false, - deductible: { - repair: deductible + describe('methods', () => { + describe('arePagePrerequisitesValid', () => { + test('returns false if car id not set', () => { + // Arrange + const mainInitialState = { + order: { + vehicle: { + carId: null } - }, - damage: { - isRepair: true } - }, - issConfig: { - isClaimRegistrationRequired: true - } - }; - const mockStoreActions = () => { - useMainStore().getWipers = jest.fn().mockImplementation(() => Promise.resolve()); - useMainStore().getRainDefense = jest.fn().mockImplementation(() => Promise.resolve()); - useMainStore().getSupportingItems = jest.fn().mockImplementation(() => Promise.resolve()); - useMainStore().getPriceOrderItems = jest.fn().mockImplementation(() => Promise.resolve([ - { - sellingPrice, - kitPrice: 0, - laborAmount: 0 + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(result).toBeFalsy(); + }); + test('returns false if car id set to 0', () => { + // Arrange + const mainInitialState = { + order: { + vehicle: { + carId: 0 + } } - ])); - }; - const { wrapper } = getMountedComponent(initialStore, {}, mockStoreActions); - const next = (method) => { method(wrapper.vm); }; + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(result).toBeFalsy(); + }); + test.each([[-1], [1], [123]])('returns true if car id set to %p', (carId) => { + // Arrange + const mainInitialState = { + order: { + vehicle: { carId } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + const result = wrapper.vm.arePagePrerequisitesValid(); + + // Assert + expect(result).toBeTruthy(); + }); + }); + test.each([ + [0, '$0.00'], + [1, '$1.00'], + [12, '$12.00'], + [1.2, '$1.20'], + [1.25, '$1.25'], + [1.254, '$1.25'], + [1.255, '$1.26'], + [-1, '-$1.00'] + ])('getFormattedAmount given %p returns "%p"', (value, expected) => { + // Arrange + const { wrapper } = getMountedComponent(); // Act - coverageStatement.beforeRouteEnter.call(wrapper.vm, undefined, undefined, next); - for (let i = 0; i < 7; i++) { - // eslint-disable-next-line no-await-in-loop - await nextTick(); - } + const result = wrapper.vm.getFormattedAmount(value); // Assert - expect(wrapper.vm.mainStore.registerClaim).toHaveBeenCalled(); + expect(result).toBe(expected); + }); + describe('navigateForward', () => { + const servicePrice = 82; + beforeEach(() => { + getPriceOfLineItems.mockImplementation(() => servicePrice); + }); + test('If Unverified, navigate forward with CLICKED_FORWARD scenario', () => { + // Arrange + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + policyLookupSuccessful: false + }, + currentDeductible: null + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD, + undefined + ); + }); + test('If Verified Deductible, navigate forward with CLICKED_FORWARD scenario', () => { + // Arrange + const deductible = servicePrice - 1; + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + noCoverage: false, + policyLookupSuccessful: true + }, + currentDeductible: deductible + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD, + undefined + ); + }); + test('If Verified ITAC and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => { + // Arrange + const deductible = servicePrice + 1; + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + noCoverage: false, + policyLookupSuccessful: true + }, + currentDeductible: deductible + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + wrapper.setData({ + selectedProvider: SAFELITE_PROVIDER + }); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, + undefined + ); + }); + test('If Verified ITAC, selected other shop, navigate forward w/ CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP', () => { + // Arrange + const deductible = servicePrice + 1; + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + noCoverage: false, + policyLookupSuccessful: true + }, + currentDeductible: deductible + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + wrapper.setData({ + selectedProvider: 'Other' + }); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, + undefined + ); + }); + test('If No Comp and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => { + // Arrange + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + noCoverage: true, + policyLookupSuccessful: true + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + wrapper.setData({ + selectedProvider: SAFELITE_PROVIDER + }); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, + undefined + ); + }); + test('If No comp and selected other shop, navigate forward with CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP ', () => { + // Arrange + const mainInitialState = { + order: { + damage: { + isRepair: true + }, + policy: { + noCoverage: true, + policyLookupSuccessful: true + } + } + }; + const { wrapper } = getMountedComponent(mainInitialState); + wrapper.setData({ + selectedProvider: 'other' + }); + + // Act + wrapper.vm.navigateForward(); + + // Assert + expect(wrapper.vm.$router.navigate) + .toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP, + undefined + ); + }); }); }); -}); - -describe('coverageStatement.vue-working', () => { describe('ITAC flag', () => { test('ITAC flag updated once component is initialized', async () => { // Arrange @@ -903,4 +1151,74 @@ describe('coverageStatement.vue-working', () => { expect(wrapper.vm.mainStore.registerClaim).toHaveBeenCalledTimes(0); }); }); + describe('claim registration api call', () => { + it('claim registration not required => method not called', async () => { + // Arrange + const mockStoreActions = () => { + useMainStore().getWipers = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getRainDefense = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getSupportingItems = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getPriceOrderItems = jest.fn().mockImplementation(() => Promise.resolve()); + }; + const { wrapper } = getMountedComponent({ + issConfig: { + isClaimRegistrationRequired: false + } + }, {}, mockStoreActions); + const next = (method) => { method(wrapper.vm); }; + + // Act + coverageStatement.beforeRouteEnter.call(wrapper.vm, undefined, undefined, next); + for (let i = 0; i < 7; i++) { + // eslint-disable-next-line no-await-in-loop + await nextTick(); + } + + // Assert + expect(wrapper.vm.mainStore.registerClaim).not.toHaveBeenCalled(); + }); + + it('claim registration required => register claim method called', async () => { + // Arrange + const servicePrice = 7283; + const deductible = servicePrice - 1; + const initialStore = { + order: { + payment: { + insuranceCoverage: { claimNumber: null } + }, + policy: { + policyLookupSuccessful: true, + noCoverage: false + }, + vehicle: { + policyVehicleId: 1 + }, + currentDeductible: deductible + }, + issConfig: { + isClaimRegistrationRequired: true + } + }; + getPriceOfLineItems.mockImplementation(() => servicePrice); + const mockStoreActions = () => { + useMainStore().getWipers = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getRainDefense = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getSupportingItems = jest.fn().mockImplementation(() => Promise.resolve()); + useMainStore().getPriceOrderItems = jest.fn().mockImplementation(() => Promise.resolve()); + }; + const { wrapper } = getMountedComponent(initialStore, {}, mockStoreActions); + const next = (method) => { method(wrapper.vm); }; + + // Act + coverageStatement.beforeRouteEnter.call(wrapper.vm, undefined, undefined, next); + for (let i = 0; i < 7; i++) { + // eslint-disable-next-line no-await-in-loop + await nextTick(); + } + + // Assert + expect(wrapper.vm.mainStore.registerClaim).toHaveBeenCalled(); + }); + }); }); diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 7338f1ad..51f86d5e 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -35,26 +35,26 @@