import { shallowMount } from '@vue/test-utils'; import { createTestingPinia } from '@pinia/testing'; import cartDropdown from '@/iss-components/cart-dropdown/cart-dropdown.vue'; // Supporting Files import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { useMainStore, getDefaultState } from '@/store'; import coverageStatuses from '@/constants/coverage-statuses'; import { formatAmountInDollars } from '@/helpers/text-helper.js'; import partTypeStrings from '@/constants/part-type-strings'; import partNumberStrings from '@/constants/part-number-strings'; import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/service-package-helper.js'; import getPriceOfLineItems from '@/helpers/price-calculator.js'; const VERIFYING_COVERAGE = 'Verifying coverage'; jest.mock('@/helpers/text-helper', () => ({ formatAmountInDollars: jest.fn() })); jest.mock('@/helpers/price-calculator.js', () => jest.fn()); jest.mock('@/helpers/service-package-helper', () => ({ getHighestFullySatisfiedTier: jest.fn(), getPackageContents: jest.fn() })); function getMountedComponent(mainInitialState = {}, initialData = {}, propsData = {}) { const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const testingPinia = createTestingPinia({ initialState: { main: mainInitialState } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; mountOptions.data = () => (initialData); mountOptions.propsData = propsData; const wrapper = shallowMount(cartDropdown, mountOptions); return { wrapper }; } beforeEach(() => { const store = useMainStore(); const defaultState = getDefaultState(); Object.keys(defaultState).forEach((key) => { store[key] = defaultState[key]; }); }); describe('cart-dropdown component', () => { test('initial data rendered as expected', () => { // Arrange const { wrapper } = getMountedComponent({ order: { availableVaps: [] } }); // Assert expect(wrapper.vm.$data).toMatchSnapshot(); }); describe('displays', () => { test('cart dropdown head', () => { // Arrange const reference = '#cart-dropdown-head'; const { wrapper } = getMountedComponent(cartDropdown); // Act const head = wrapper.find(reference); // Assert expect(head.exists()).toBeTruthy(); }); test('cart dropdown head is visible', () => { // Arrange const reference = '#cart-dropdown-head'; const { wrapper } = getMountedComponent(cartDropdown, {}, { showDropdownHeader: true }); // Act const head = wrapper.find(reference); // Assert expect(head.exists()).toBeTruthy(); expect(head.classes()).toContain('cart-toggle'); }); test('cart dropdown head is not visible', () => { // Arrange const reference = '#cart-dropdown-head'; const { wrapper } = getMountedComponent(cartDropdown, {}, { showDropdownHeader: false }); // Act const head = wrapper.find(reference); // Assert expect(head.exists()).toBeTruthy(); expect(head.classes()).not.toContain('cart-toggle'); }); test('cart table', () => { // Arrange const reference = '#cart-table'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const cartTable = wrapper.find(reference); // Assert expect(cartTable.exists()).toBeTruthy(); }); test('cart deductible when showDeductibleLineItem is true', () => { // Arrange const reference = '#cart-deductible'; const isExpanded = true; const initialData = { isExpanded }; const storeData = { order: { payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: false } } }; const { wrapper } = getMountedComponent(storeData, {}, initialData); // Act const cartDeductible = wrapper.find(reference); // Assert expect(cartDeductible.exists()).toBeTruthy(); }); test('cart base price when showDeductibleLineItem is false', () => { // Arrange const reference = '#cart-base-price'; const isExpanded = true; const initialData = { isExpanded }; const storeData = { order: { currentDeductible: 0, lineItems: { }, payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: true, policyLookupSuccessful: true } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData, {}, initialData); // Act const cartBasePrice = wrapper.find(reference); // Assert expect(cartBasePrice.exists()).toBeTruthy(); }); test('service package', () => { // Arrange const reference = '#cart-service-package'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const servicePackage = wrapper.find(reference); // Assert expect(servicePackage.exists()).toBeTruthy(); }); test('non service package cart items', () => { // Arrange const reference = '#non-packaged-cart-items'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const nonPackagedCartItems = wrapper.find(reference); // Assert expect(nonPackagedCartItems.exists()).toBeTruthy(); }); test('recycle cart item label when isRecycle true for some cart item', () => { // Arrange const reference = '#recycle-fee-label'; const isExpanded = true; const initialPropsData = { isExpanded }; const storeData = { order: { lineItems: { supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE } ] } } }; const { wrapper } = getMountedComponent(storeData, {}, initialPropsData); // Act const recycleFeeLabel = wrapper.find(reference); // Assert expect(wrapper.vm.recycleFeeCartItem).not.toBeNull(); expect(recycleFeeLabel.exists()).toBeTruthy(); }); test('cart footer', () => { // Arrange const reference = '#cart-footer'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const cartFooter = wrapper.find(reference); // Assert expect(cartFooter.exists()).toBeTruthy(); }); test('subtotal', () => { // Arrange const reference = '#cart-subtotal'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const subtotal = wrapper.find(reference); // Assert expect(subtotal.exists()).toBeTruthy(); }); test('tax', () => { // Arrange const reference = '#cart-sales-tax'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const salesTax = wrapper.find(reference); // Assert expect(salesTax.exists()).toBeTruthy(); }); test('amount paid when Pay in Advance', () => { // Arrange const reference = '#cart-amount-paid'; const isExpanded = true; const showAsPaid = true; const initialPropsData = { isExpanded, showAsPaid }; const storeData = { order: { payment: { isPayInAdvance: true } } }; const { wrapper } = getMountedComponent(storeData, {}, initialPropsData); // Act const amountPaid = wrapper.find(reference); // Assert expect(amountPaid.exists()).toBeTruthy(); }); test('bottom amount due', () => { // Arrange const reference = '#bottom-amount-due'; const isExpanded = true; const initialData = { isExpanded }; const { wrapper } = getMountedComponent({}, {}, initialData); // Act const bottomAmountDue = wrapper.find(reference); // Assert expect(bottomAmountDue.exists()).toBeTruthy(); }); }); describe('does not display', () => { test('cart deductible when showDeductibleLineItem is false', () => { // Arrange const reference = '#cart-deductible'; const isExpanded = true; const initialData = { isExpanded }; const storeData = { order: { currentDeductible: 0, lineItems: { }, payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: true, policyLookupSuccessful: true } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData, {}, initialData); // Act const cartDeductible = wrapper.find(reference); // Assert expect(cartDeductible.exists()).toBeFalsy(); }); test('cart base price when showDeductibleLineItem is true', () => { // Arrange const reference = '#cart-base-price'; const isExpanded = true; const initialData = { isExpanded }; const storeData = { order: { payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: false } } }; const { wrapper } = getMountedComponent(storeData, {}, initialData); // Act const cartBasePrice = wrapper.find(reference); // Assert expect(cartBasePrice.exists()).toBeFalsy(); }); test('recycle cart item label when isRecycle false for all cart items', () => { // Arrange const reference = '#recycle-fee-label'; const isExpanded = true; const initialPropsData = { isExpanded }; const storeData = { order: { lineItems: { supportingItems: [] } } }; const { wrapper } = getMountedComponent(storeData, {}, initialPropsData); // Act const recycleFeeLabel = wrapper.find(reference); // Assert expect(wrapper.vm.recycleFeeCartItem).toBeNull(); expect(recycleFeeLabel.exists()).toBeFalsy(); }); }); describe('computed', () => { describe('amountDue', () => { test('returns 0 when showAsPaid is true', () => { // Arrange const propsData = { showAsPaid: true }; const { wrapper } = getMountedComponent({}, {}, propsData); // Act const result = wrapper.vm.amountDue; // Assert expect(result).toBe(0); }); test('returns sum of subTotal and salesTax when showAsPaid is false', () => { // TODO when subTotal and salesTax are finished }); }); describe('subTotal', () => { const supportingItemPartNumber = 'supporter'; const glassPartNumber = 'glass part'; const otherPartNumber = 'other'; const vapPartNumber = 'vap'; const mobileFeePartNumber = 'mobile'; const supportingItems = [{ partNumber: supportingItemPartNumber }]; const glassParts = [{ partNumber: glassPartNumber }]; const otherParts = [{ partNumber: otherPartNumber }]; const vaps = [{ partNumber: vapPartNumber }]; const mobileFee = { partNumber: mobileFeePartNumber }; const includesPartNumber = (lineItems, partNumber) => lineItems.some((item) => item?.partNumber === partNumber); const deductiblePrice = 100; const supportingAndGlassAndOtherPrice = 30; const feesAndVapsPrice = 50; const allLineItemsPrice = 70; getPriceOfLineItems.mockImplementation((lineItems) => { const allPartNumbers = [ supportingItemPartNumber, glassPartNumber, otherPartNumber, mobileFeePartNumber, vapPartNumber ]; if (allPartNumbers.every((partNumber) => includesPartNumber(lineItems, partNumber))) { return allLineItemsPrice; } const supportingAndGlassAndOtherPartNumbers = [ supportingItemPartNumber, glassPartNumber, otherPartNumber ]; if (supportingAndGlassAndOtherPartNumbers.every((partNumber) => includesPartNumber(lineItems, partNumber))) { return supportingAndGlassAndOtherPrice; } if (includesPartNumber(lineItems, mobileFeePartNumber) && includesPartNumber(lineItems, vapPartNumber)) { return feesAndVapsPrice; } return 1; }); const lineItems = { supportingItems, glassParts, otherParts, vaps, mobileFee }; test('when not no comp and not itac, includes deductible price plus fee and vap price', () => { // Arrange const storeData = { order: { lineItems, policy: { noCoverage: false, isITAC: false }, currentDeductible: deductiblePrice } }; const { wrapper } = getMountedComponent(storeData); const expected = deductiblePrice + feesAndVapsPrice; // Act const result = wrapper.vm.subTotal; // Assert expect(result).toBe(expected); }); test('when no comp, returns all line items price', () => { // Arrange const storeData = { order: { lineItems, policy: { noCoverage: true, isITAC: false }, currentDeductible: deductiblePrice } }; const { wrapper } = getMountedComponent(storeData); const expected = allLineItemsPrice; // Act const result = wrapper.vm.subTotal; // Assert expect(result).toBe(expected); }); test('when ITAC, returns all line items price', () => { // Arrange const storeData = { order: { lineItems, policy: { noCoverage: false, isITAC: true }, currentDeductible: deductiblePrice } }; const { wrapper } = getMountedComponent(storeData); const expected = allLineItemsPrice; // Act const result = wrapper.vm.subTotal; // Assert expect(result).toBe(expected); }); }); describe('salesTax', () => { test('salesTax is treated as 0 when line items are null', () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true }, currentDeductible: 250, lineItems: { glassParts: null, otherParts: null, supportingItems: null, vaps: null }, payment: { insuranceCoverage: { isVerified: true } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(0); }); test("salesTax is treated as 0 when null or undefined is set as the line item's sales tax.", () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true }, currentDeductible: 250, lineItems: { glassParts: [ { partType: 'mock', salesTax: null }, { partType: 'mock', salesTax: undefined } ], supportingItems: [ { partType: 'mock', salesTax: null }, { partType: 'mock', salesTax: undefined } ], vaps: [ { partType: 'mock', salesTax: null }, { partType: 'mock', salesTax: undefined } ] }, payment: { insuranceCoverage: { isVerified: true } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(0); }); test('Returns 0 as sales tax when coverage is unverified and order does not contain vaps.', () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true }, currentDeductible: 250, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10 }], supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE, partType: 'mock', salesTax: 10, sellingPrice: 39.99 } ], vaps: [] }, payment: { insuranceCoverage: { isVerified: false } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(0); }); test('Returns sum of vaps sales tax when coverage is unverified and order has vaps.', () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true }, currentDeductible: 250, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10 }], vaps: [ { partType: 'mock', salesTax: 1 }, { partType: 'mock', salesTax: 2 } ] }, payment: { insuranceCoverage: { isVerified: false } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(3); }); test('Returns Recycle Fee tax when coverage is Verified-Deductible, replace service, and no vaps.', () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true, noCoverage: false, isITAC: false }, currentDeductible: 250, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10, sellingPrice: 150 }], supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE, partType: 'mock', salesTax: 10, sellingPrice: 39.99 } ], vaps: null }, payment: { insuranceCoverage: { isVerified: true } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(10); }); test('Returns sum of vaps + recycle fee sales tax when Verified-Deductible, replace service, and has vaps.', () => { // Arrange const storeData = { order: { policy: { policyLookupSuccessful: true }, currentDeductible: 250, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10, sellingPrice: 100 }], otherParts: [{ partType: 'mock', salesTax: 10, kitPrice: 100 }], supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE, partType: 'mock', salesTax: 10, sellingPrice: 39.99 }, { partType: 'mock', salesTax: 10, kitPrice: 100 } ], vaps: [ { partType: 'mock', salesTax: 2 }, { partType: 'mock', salesTax: 3 } ] }, payment: { insuranceCoverage: { isVerified: true } } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(15); }); test('Returns sum of sales tax when Verified-ITAC.', () => { // Arrange const storeData = { order: { currentDeductible: 0, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10, sellingPrice: 100 }], otherParts: [{ partType: 'mock', salesTax: 10, kitPrice: 100 }], supportingItems: [{ partType: 'mock', salesTax: 10, kitPrice: 100 }], vaps: [{ partType: 'mock', salesTax: 5 }] }, payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: true, policyLookupSuccessful: true } }, issConfig: { isClaimRegistrationRequired: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(35); }); test('Returns sum of sales tax when Verified-NoComp.', () => { // Arrange const storeData = { order: { currentDeductible: 0, lineItems: { glassParts: [{ partType: 'mock', salesTax: 10, sellingPrice: 100 }], otherParts: [{ partType: 'mock', salesTax: 10, kitPrice: 100 }], supportingItems: [{ partType: 'mock', salesTax: 10, kitPrice: 100 }], vaps: [{ partType: 'mock', salesTax: 5 }] }, payment: { insuranceCoverage: { isVerified: true } }, policy: { noCoverage: true, policyLookupSuccessful: true } }, issConfig: { isClaimRegistrationRequired: true, enableNoCompQuote: true } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.salesTax; // Assert expect(result).toBe(35); }); }); describe('availableLineItems', () => { test('returns expected when all null', () => { // Arrange const propsData = { availableVaps: null }; const { wrapper } = getMountedComponent({}, {}, propsData); // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual([]); }); test('returns expected when glassParts not null', async () => { // Arrange const glassParts = [{ partNumber: 'glass' }]; const storeData = { order: { lineItems: { glassParts } } }; const propsData = { availableVaps: null }; const { wrapper } = getMountedComponent(storeData, {}, propsData); const expected = glassParts; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when supportingItems not null', async () => { // Arrange const supportingItems = [{ partNumber: 'support' }]; const storeData = { order: { lineItems: { supportingItems } } }; const propsData = { availableVaps: null }; const { wrapper } = getMountedComponent(storeData, {}, propsData); const expected = supportingItems; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when otherParts not null', () => { // Arrange const otherParts = [{ partNumber: 'other' }]; const storeData = { order: { lineItems: { otherParts } } }; const propsData = { availableVaps: null }; const { wrapper } = getMountedComponent(storeData, {}, propsData); const expected = otherParts; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when mobileFee not null', () => { // Arrange const mobileFee = { partNumber: 'mobile' }; const storeData = { order: { lineItems: { mobileFee } } }; const propsData = { availableVaps: null }; const { wrapper } = getMountedComponent(storeData, {}, propsData); const expected = [mobileFee]; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when availableVaps null', async () => { // Arrange const availableVaps = [{ partNumber: 'vaps1' }]; const initialData = { availableVaps }; const { wrapper } = getMountedComponent({}, initialData, {}); const expected = availableVaps; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when glassParts, supportingItems, otherParts, mobileFee, and availableVaps have content', async () => { // Arrange const part1 = { partType: 'apple' }; const part2 = { partType: 'banana' }; const part3 = { partType: 'orange' }; const part4 = { partType: 'grape' }; const part5 = { partType: 'raspberry' }; const mobileFee = { partType: 'mobile' }; const storeData = { order: { lineItems: { glassParts: [part1], supportingItems: [part2, part3], otherParts: [], mobileFee } } }; const initialData = { availableVaps: [part4, part5] }; const { wrapper } = getMountedComponent(storeData, initialData, {}); const sortByPartType = (a, b) => { const typeA = a.partType.toUpperCase(); const typeB = b.partType.toUpperCase(); if (typeA < typeB) { return -1; } if (typeA > typeB) { return 1; } return 0; }; const expected = [part1, part2, part3, part4, part5, mobileFee]; // Act const result = wrapper.vm.availableLineItems; // Assert expect(result.sort(sortByPartType)).toStrictEqual(expected.sort(sortByPartType)); }); }); describe('servicePackageCartItems', () => { test.each([ [undefined], [null], [[]] ])('returns empty list when package contents %p', (packageContents) => { // Arrange getPackageContents.mockImplementationOnce(() => packageContents); const { wrapper } = getMountedComponent(); const expected = []; // Act const result = wrapper.vm.servicePackageCartItems; // Assert expect(result).toStrictEqual(expected); }); test('returns front wiper when front wiper included in types', () => { // Arrange const frontWiperPartType = partTypeStrings.FRONT_WIPER; const packageContents = [frontWiperPartType]; getPackageContents.mockImplementation(() => packageContents); const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedName = 'some name'; const vapsItemDescriptions = [ { Name: frontWiperPartType, Text: expectedName } ]; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? vapsItemDescriptions : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [{ partType: frontWiperPartType }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageCartItems; // Assert expect(result.length).toBe(1); expect(result[0].name).toBe(expectedName); }); test('returns rear wiper when rear wiper included in types', () => { // Arrange const rearWiperPartType = partTypeStrings.REAR_WIPER; const packageContents = [rearWiperPartType]; getPackageContents.mockImplementationOnce(() => packageContents); const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedName = 'some other name'; const vapsItemDescriptions = [ { Name: rearWiperPartType, Text: expectedName } ]; const mockMixin = { methods: { getCmsContent: jest.fn(() => vapsItemDescriptions) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [{ partType: rearWiperPartType }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageCartItems; // Assert expect(result.length).toBe(1); expect(result[0].name).toBe(expectedName); }); test('returns rain defense when rain defense included in types', () => { // Arrange const rainDefensePartType = partTypeStrings.RAIN_DEFENSE; const packageContents = [rainDefensePartType]; getPackageContents.mockImplementationOnce(() => packageContents); const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedName = 'different name'; const vapsItemDescriptions = [ { Name: rainDefensePartType, Text: expectedName } ]; const mockMixin = { methods: { getCmsContent: jest.fn(() => vapsItemDescriptions) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [{ partType: rainDefensePartType }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageCartItems; // Assert expect(result.length).toBe(1); expect(result[0].name).toBe(expectedName); }); test('returns expected when all included in types', () => { // Arrange const frontWiperPartType = partTypeStrings.FRONT_WIPER; const rearWiperPartType = partTypeStrings.REAR_WIPER; const rainDefensePartType = partTypeStrings.RAIN_DEFENSE; const packageContents = [frontWiperPartType, rearWiperPartType, rainDefensePartType]; getPackageContents.mockImplementationOnce(() => packageContents); const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedFrontWiperName = 'front wiper'; const expectedRearWiperName = 'rear wiper'; const expectedRainDefenseName = 'rain defense'; const vapsItemDescriptions = [ { Name: frontWiperPartType, Text: expectedFrontWiperName }, { Name: rearWiperPartType, Text: expectedRearWiperName }, { Name: rainDefensePartType, Text: expectedRainDefenseName } ]; const mockMixin = { methods: { getCmsContent: jest.fn(() => vapsItemDescriptions) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [ { partType: frontWiperPartType }, { partType: rearWiperPartType }, { partType: rainDefensePartType } ] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageCartItems; // Assert expect(result.length).toBe(3); expect(result).toContainEqual(expect.objectContaining({ name: expectedFrontWiperName })); expect(result).toContainEqual(expect.objectContaining({ name: expectedRearWiperName })); expect(result).toContainEqual(expect.objectContaining({ name: expectedRainDefenseName })); }); }); describe('nonServicePackageCartItems', () => { test('when recycleFee, includes recycle fee', () => { // Arrange const storeData = { order: { lineItems: { supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.REPLACE_FEE })); }); test('when mobileFee, includes mobile fee', () => { // Arrange const storeData = { order: { lineItems: { mobileFee: { partType: partTypeStrings.MOBILE_FEE } } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.MOBILE_FEE })); }); test('front wiper not included when front wiper in service package', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER]); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.FRONT_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).not.toContainEqual(expect.objectContaining({ partType: partTypeStrings.FRONT_WIPER })); }); test('rear wiper not included when rear wiper in service package', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => [partTypeStrings.REAR_WIPER]); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.REAR_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).not.toContainEqual(expect.objectContaining({ partType: partTypeStrings.REAR_WIPER })); }); test('rain defense not included when rain defense in service package', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => [partTypeStrings.RAIN_DEFENSE]); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.RAIN_DEFENSE } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).not.toContainEqual(expect.objectContaining({ partType: partTypeStrings.RAIN_DEFENSE })); }); test('front wiper included when not in service package and in vaps', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => []); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.FRONT_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.FRONT_WIPER })); }); test('rear wiper included when not in service package and in vaps', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => []); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.REAR_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.REAR_WIPER })); }); test('rain defense included when not in service package and in vaps', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => []); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.RAIN_DEFENSE } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.RAIN_DEFENSE })); }); test('item in vaps outside front wiper, rear wiper, and rain defense never included', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => []); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.RECALIBRATION } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result).not.toContainEqual(expect.objectContaining({ partType: partTypeStrings.RECALIBRATION })); }); test('returns expected when multiple variables apply', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER]); const storeData = { order: { lineItems: { supportingItems: [ { partNumber: partNumberStrings.RECYCLE_FEE } ], mobileFee: { partType: partTypeStrings.MOBILE_FEE }, vaps: [ { partType: partTypeStrings.RECALIBRATION }, { partType: partTypeStrings.FRONT_WIPER }, { partType: partTypeStrings.REAR_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.nonServicePackageCartItems; // Assert expect(result.length).toBe(3); expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.REPLACE_FEE })); expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.MOBILE_FEE })); expect(result).toContainEqual(expect.objectContaining({ partType: partTypeStrings.REAR_WIPER })); }); }); describe('servicePackageLabelWidget', () => { test.each([ [null], [undefined] ])('returns "" when servicePackageNames %p', (servicePackageNames) => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const mockMixin = { methods: { getCmsContent: jest.fn(() => servicePackageNames) } }; mountOptions.mixins = [mockMixin]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageLabelWidget; // Assert expect(result).toBe(''); }); test('returns "" when servicePackageTier not found in servicePackageNames', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); getHighestFullySatisfiedTier.mockImplementationOnce(() => 'some other tier'); const servicePackageNames = [{ Name: 'some tier' }]; const mockMixin = { methods: { getCmsContent: jest.fn(() => servicePackageNames) } }; mountOptions.mixins = [mockMixin]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageLabelWidget; // Assert expect(result).toBe(''); }); test('returns "" when servicePackageTier has no SubWidgetName', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const tier = 'tier1'; getHighestFullySatisfiedTier.mockImplementationOnce(() => tier); const servicePackageNames = [{ Name: tier }]; const mockMixin = { methods: { getCmsContent: jest.fn(() => servicePackageNames) } }; mountOptions.mixins = [mockMixin]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageLabelWidget; // Assert expect(result).toBe(''); }); test('returns expected when servicePackageTier has SubWidgetName', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const tier = 'tier1'; getHighestFullySatisfiedTier.mockImplementationOnce(() => tier); const expected = 'name of sub widget'; const servicePackageNames = [{ Name: tier, SubWidgetName: expected }]; const mockMixin = { methods: { getCmsContent: jest.fn(() => servicePackageNames) } }; mountOptions.mixins = [mockMixin]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.servicePackageLabelWidget; // Assert expect(result).toBe(expected); }); }); describe('recycleFeeCartItem', () => { test.each([ [null], [undefined], [[]] ])('returns null when supporting items %p', (supportingItems) => { // Arrange const storeData = { order: { lineItems: { supportingItems } } }; const { wrapper } = getMountedComponent(storeData); const expected = null; // Act const result = wrapper.vm.recycleFeeCartItem; // Assert expect(result).toStrictEqual(expected); }); test('returns null when recycle fee not in non empty supporting items', () => { // Arrange const storeData = { order: { lineItems: { supportingItems: [{ partNumber: 'not recycle' }] } } }; const { wrapper } = getMountedComponent(storeData); const expected = null; // Act const result = wrapper.vm.recycleFeeCartItem; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when recycle fee in supporting items', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedName = 'recycling fee'; const widgetName = 'RecycleFeeWidget'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? expectedName : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { supportingItems: [{ partNumber: partNumberStrings.RECYCLE_FEE }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.recycleFeeCartItem; // Assert expect(result.name).toBe(expectedName); }); }); describe('mobileFeeCartItem', () => { test.each([[null], [undefined]])('returns null when mobile fee %p', (mobileFee) => { // Arrange const storeData = { order: { lineItems: { mobileFee } } }; const { wrapper } = getMountedComponent(storeData); const expected = null; // Act const result = wrapper.vm.mobileFeeCartItem; // Assert expect(result).toStrictEqual(expected); }); test('returns expected when mobile fee in supporting items', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const expectedName = 'mobile fee'; const widgetName = 'MobileServiceWidget'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? expectedName : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { mobileFee: { partType: partTypeStrings.MOBILE_FEE } } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.mobileFeeCartItem; // Assert expect(result.name).toBe(expectedName); }); }); describe('packagePrice', () => { test('returns 0 when servicePackageCartItems is empty', () => { // Arrange getPriceOfLineItems.mockImplementation(() => 123); getPackageContents.mockImplementationOnce(() => []); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.REAR_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.packagePrice; // Assert expect(result).toBe(0); }); test('returns expected when servicePackageCartItems not empty', () => { // Arrange const rearPrice = 101; const frontPrice = 9; getPriceOfLineItems.mockImplementation((lineItems) => { if (lineItems.some((item) => item?.partType === partTypeStrings.FRONT_WIPER)) { return frontPrice; } if (lineItems.some((item) => item?.partType === partTypeStrings.REAR_WIPER)) { return rearPrice; } return 1; }); getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER, partTypeStrings.REAR_WIPER]); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.FRONT_WIPER }, { partType: partTypeStrings.REAR_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); const expectedPrice = 110; // Act const result = wrapper.vm.packagePrice; // Assert expect(result).toBe(expectedPrice); }); test('returns expected when servicePackageCartItems has one item', () => { // Arrange const frontPrice = 9; getPriceOfLineItems.mockImplementation((lineItems) => { if (lineItems.some((item) => item?.partType === partTypeStrings.FRONT_WIPER)) { return frontPrice; } return 1; }); getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER, partTypeStrings.REAR_WIPER]); const storeData = { order: { lineItems: { vaps: [ { partType: partTypeStrings.FRONT_WIPER } ] } } }; const { wrapper } = getMountedComponent(storeData); // Act const result = wrapper.vm.packagePrice; // Assert expect(result).toBe(frontPrice); }); }); }); describe('method', () => { describe('getDisplayed', () => { test('returns "Verifying coverage" when not no comp, not itac, and deductible null', () => { // Arrange const storeData = { order: { policy: { noCoverage: false, isITAC: false }, currentDeductible: null } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(VERIFYING_COVERAGE); }); test('returns "Verifying coverage" when not no comp, not itac, and coverage status PENDING', () => { // Arrange const storeData = { order: { policy: { noCoverage: false, isITAC: false }, currentDeductible: 321 } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(VERIFYING_COVERAGE); }); test('returns dollar amount when itac', () => { // Arrange const storeData = { order: { payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: true, noCoverage: false, policyLookupSuccessful: true }, currentDeductible: 321 } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; const dollarAmount = '$84.00'; formatAmountInDollars.mockImplementationOnce(() => dollarAmount); // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(dollarAmount); }); test('returns dollar amount when no comp and enableNoCompQuotes true', () => { // Arrange const storeData = { order: { payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: false, noCoverage: true, policyLookupSuccessful: true }, currentDeductible: 321 }, issConfig: { enableNoCompQuote: true } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; const dollarAmount = '$84.00'; formatAmountInDollars.mockImplementationOnce(() => dollarAmount); // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(dollarAmount); }); test('returns "Verifying Coverage" when no comp and enableNoCompQuotes false', () => { // Arrange const storeData = { order: { payment: { insuranceCoverage: { isVerified: true } }, policy: { isITAC: false, noCoverage: true, policyLookupSuccessful: true }, currentDeductible: 321 }, issConfig: { enableNoCompQuote: false } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(VERIFYING_COVERAGE); }); test('returns dollar amount when deductible set, not itac, not no comp, and verified', () => { // Arrange const storeData = { order: { policy: { isITAC: false, noCoverage: false, policyLookupSuccessful: true }, currentDeductible: 321, policyLookupSuccessful: true, payment: { insuranceCoverage: { isVerified: true } } } }; const { wrapper } = getMountedComponent(storeData); const amount = 123; const dollarAmount = '$84.00'; formatAmountInDollars .mockImplementationOnce((value) => (value === amount ? dollarAmount : 1)); // Act const result = wrapper.vm.getDisplayed(amount); // Assert expect(result).toBe(dollarAmount); }); }); describe('getCartItemForVapsPart', () => { test('returns item with no label when no descriptions returned', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const descriptions = []; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? descriptions : [])) } }; mountOptions.mixins = [mockMixin]; const part = 'some part'; const storeData = { order: { lineItems: { vaps: [{ partType: part }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); const expectedName = ''; // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result.name).toBe(expectedName); }); test('returns item with no label when type not in descriptions', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const descriptions = [{ Name: 'not part name' }]; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? descriptions : [])) } }; mountOptions.mixins = [mockMixin]; const part = 'some part'; const storeData = { order: { lineItems: { vaps: [{ partType: part }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); const expectedName = ''; // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result.name).toBe(expectedName); }); test('returns item with no label when description text not defined', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const part = 'some part'; const descriptions = [{ Name: part }]; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? descriptions : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [{ partType: part }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); const expectedName = ''; // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result.name).toBe(expectedName); }); test('returns expected label when vaps description text set', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const part = 'some part'; const expectedName = 'name to show up'; const descriptions = [{ Name: part, Text: expectedName }]; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? descriptions : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: [{ partType: part }] } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result.name).toBe(expectedName); }); test.each([ [undefined], [null] ])('returns null when vapsInOrder %p', async (vapsInOrder) => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const part = 'some part'; const expectedName = 'name to show up'; const descriptions = [{ Name: part, Text: expectedName }]; const widgetName = 'VapsItemDescriptions'; const mockMixin = { methods: { getCmsContent: jest.fn((widget, _) => (widget === widgetName ? descriptions : [])) } }; mountOptions.mixins = [mockMixin]; const storeData = { order: { lineItems: { vaps: vapsInOrder } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result).toBe(null); }); test('returns item with expected price when part type found in vapsInOrder', () => { // Arrange const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const part = 'some part'; const vaps = [{ partType: part }]; const storeData = { order: { lineItems: { vaps } } }; const testingPinia = createTestingPinia({ initialState: { main: storeData } }); useMainStore(testingPinia); mountOptions.global.plugins = [testingPinia]; const expectedSubtotal = 93; getPriceOfLineItems.mockImplementation(() => expectedSubtotal); const wrapper = shallowMount(cartDropdown, mountOptions); // Act const result = wrapper.vm.getCartItemForVapsPart(part); // Assert expect(result.subTotal).toBe(expectedSubtotal); }); }); }); });