// Components import { shallowMount } from '@vue/test-utils'; import { createTestingPinia } from '@pinia/testing'; import tpaSubmit from '@/layouts/tpa-submit/tpa-submit.vue'; // Supporting Files import { getEnumName, getMountOptions } from '@/helpers/unit-test-helper.js'; import { useMainStore } from '@/store'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import settleAllPromises from '@/helpers/layout-helper.js'; import widgetFields from '@/constants/cms-widget-fields.js'; import { toTitleCase, formatAddress, toDisplayPhoneNumber, formatAmountInDollars } from '@/helpers/text-helper.js'; import { getDamageDisplayContent } from '@/helpers/damage-review-content-generator.js'; import baseMixin from '@/mixins/base-mixin'; import coverageStatuses from '@/constants/coverage-statuses'; // Mock fetchCmsContentForPage jest.mock('@/helpers/cms-content-helper', () => ({ fetchCmsContentForPage: jest.fn(), doesCopyContainRouterLink: jest.fn(), getStringWithCustomValues: jest.fn(), processIfStatements: jest.fn() })); jest.mock('@/helpers/text-helper.js', () => ({ formatAddress: jest.fn(), toDisplayPhoneNumber: jest.fn(), formatAmountInDollars: jest.fn(), toTitleCase: jest.fn() })); jest.mock('@/helpers/damage-review-content-generator.js', () => ({ getDamageDisplayContent: jest.fn(), getLocationAnswer: jest.fn() })); // Mock our module for promises. jest.mock('@/helpers/layout-helper.js', () => jest.fn()); const mockMixin = { methods: { ...baseMixin.methods } }; function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRunAfterInitializingStore = () => {}) { const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); const testingPinia = createTestingPinia({ initialState: { main: mainInitialState } }); useMainStore(testingPinia); methodToRunAfterInitializingStore(); mountOptions.global.plugins = [testingPinia]; mountOptions.data = () => (initialData); mountOptions.mixins = [mockMixin]; const apiResponses = { cmsContent: {} }; settleAllPromises.mockImplementation(() => apiResponses); fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); const wrapper = shallowMount(tpaSubmit, mountOptions); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {}); wrapper.vm.setCmsContent = jest.fn(); return { wrapper }; } beforeEach(() => { formatAddress.mockClear(); toDisplayPhoneNumber.mockClear(); getDamageDisplayContent.mockClear(); formatAmountInDollars.mockClear(); }); describe('tpa-submit', () => { test('returns the initial data', () => { // Arrange const companyName = 'Frederick Jones'; const mainInitialState = { order: { serviceLocation: { provider: { companyName } } } }; const { wrapper } = getMountedComponent(mainInitialState); // Assert expect(wrapper.vm.$data).toMatchSnapshot(); }); describe('should render', () => { test('tpa submit form', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const form = wrapper.findComponent({ ref: 'tpaSubmitFormRef' }); // Assert expect(form.exists()).toBeTruthy(); expect(form.classes()).toContain('tpa-submit'); }); test('site header', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); const expectedWidgetName = 'SiteHeaderWidget'; // Act const siteHeader = wrapper.findComponent({ ref: 'siteHeader' }); // Assert expect(siteHeader.exists()).toBeTruthy(); expect(siteHeader.props().cmsWidgetName).toBe(expectedWidgetName); }); test('vehicle banner', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); const expectedWidgetName = 'VehicleBannerWidget'; // Act const vehicleBanner = wrapper.findComponent({ ref: 'vehicleBanner' }); // Assert expect(vehicleBanner.exists()).toBeTruthy(); expect(vehicleBanner.props().cmsWidgetName).toBe(expectedWidgetName); expect(vehicleBanner.props().displayGenericVehicleImage).toBe(false); expect(vehicleBanner.classes()).toContain('mt-5'); }); test('sub header', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const subHeader = wrapper.findComponent({ ref: 'subHeaderTitle' }); // Assert expect(subHeader.exists()).toBeTruthy(); expect(subHeader.props().justifyText).toBe('center'); expect(subHeader.props().marginTopSizeOverride).toBe(4); expect(subHeader.classes()).toContain('text-color--black'); expect(subHeader.classes()).toContain('fs-5'); expect(subHeader.classes()).toContain('tpa-submit__title--line-height'); }); test('sub header body one', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const subHeaderBodyOne = wrapper.findComponent({ ref: 'tpaSubmitSubHeaderBodyOne' }); // Assert expect(subHeaderBodyOne.exists()).toBeTruthy(); expect(subHeaderBodyOne.classes()).toContain('small'); expect(subHeaderBodyOne.classes()).toContain('text-color--darker-gray'); }); test('sub header body two', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const subHeaderBodyTwo = wrapper.findComponent({ ref: 'tpaSubmitSubHeaderBodyTwo' }); // Assert expect(subHeaderBodyTwo.exists()).toBeTruthy(); expect(subHeaderBodyTwo.classes()).toContain('mb-4'); expect(subHeaderBodyTwo.classes()).toContain('small'); expect(subHeaderBodyTwo.classes()).toContain('text-color--darker-gray'); }); test('main button one', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const mainButton = wrapper.findComponent({ ref: 'buttonMainOne' }); // Assert expect(mainButton.exists()).toBeTruthy(); expect(mainButton.props().isPrimary).toBe(true); expect(mainButton.props().loaderColor).toBe('white'); expect(mainButton.classes()).toContain('w-100'); expect(mainButton.classes()).toContain('mb-5'); }); test('service summary section', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const serviceSummarySection = wrapper.find('#serviceSummarySection'); // Assert expect(serviceSummarySection.exists()).toBeTruthy(); }); test('service summary title', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const serviceSummaryTitle = wrapper.findComponent({ ref: 'tpaSubmitServiceSummaryTitle' }); // Assert expect(serviceSummaryTitle.exists()).toBeTruthy(); expect(serviceSummaryTitle.props().marginTopSizeOverride).toBe(4); expect(serviceSummaryTitle.classes()).toContain('fw-bold'); expect(serviceSummaryTitle.classes()).toContain('fs-1'); expect(serviceSummaryTitle.classes()).toContain('lh-lg'); expect(serviceSummaryTitle.classes()).toContain('text-color--black'); }); describe('review blocks', () => { const title1 = 'Section 1'; const title2 = 'Another Section'; const lines1 = ['apple', 'banana', 'cherry']; const lines2 = ['soccer', 'golf']; const sections = [ { title: title1, lines: lines1, onClickEdit: () => {} }, { title: title2, lines: lines2, onClickEdit: () => {} } ]; const initialData = { sections }; const { wrapper } = getMountedComponent({}, initialData); test.each([ [0, true, title1, lines1], [1, true, title2, lines2], [2, false, null, null], [-1, false, null, null] ])('section %p exists value is %p with header text %p and lines %p', (index, exists, headerText, lines) => { // Act const reviewBlocks = wrapper.findComponent(`#review-block-${index}`); // Assert expect(reviewBlocks.exists()).toBe(exists); if (exists) { expect(reviewBlocks.props().customHeaderText).toBe(headerText); expect(reviewBlocks.props().lines).toStrictEqual(lines); } }); }); test('submit order details section', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const submitOrderDetailsSection = wrapper.find({ ref: 'submitOrderDetailsSection' }); // Assert expect(submitOrderDetailsSection.exists()).toBeTruthy(); }); test('submit order details title', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const submitOrderDetailsTitle = wrapper.findComponent({ ref: 'tpaSubmitOrderDetailsTitle' }); // Assert expect(submitOrderDetailsTitle.exists()).toBeTruthy(); expect(submitOrderDetailsTitle.props().marginTopSizeOverride).toBe(4); expect(submitOrderDetailsTitle.classes()).toContain('fw-bold'); expect(submitOrderDetailsTitle.classes()).toContain('text-color--black'); }); test('submit order details body', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const submitOrderDetailsTitle = wrapper.findComponent({ ref: 'tpaSubmitOrderDetailsBody' }); // Assert expect(submitOrderDetailsTitle.exists()).toBeTruthy(); expect(submitOrderDetailsTitle.props().marginTopSizeOverride).toBe(4); expect(submitOrderDetailsTitle.classes()).toContain('mb-4'); expect(submitOrderDetailsTitle.classes()).toContain('px-4'); expect(submitOrderDetailsTitle.classes()).toContain('small'); expect(submitOrderDetailsTitle.classes()).toContain('text-color--darker-gray'); }); test('deductible box', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const deductibleBox = wrapper.findComponent({ ref: 'deductibleBox' }); // Assert expect(deductibleBox.exists()).toBeTruthy(); }); test('site footer', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const siteFooter = wrapper.findComponent({ ref: 'siteFooter' }); // Assert expect(siteFooter.exists()).toBeTruthy(); expect(siteFooter.props().cmsWidgetName).toBe('SiteFooterWidget'); expect(siteFooter.classes()).toContain('mt-5'); }); test('contact details drawer', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const contactDetailsDrawer = wrapper.findComponent({ ref: 'contactDetailsDrawer' }); // Assert expect(contactDetailsDrawer.exists()).toBeTruthy(); }); }); describe('before route enter', () => { test('produces 4 sections', async () => { // Arrange const { wrapper } = getMountedComponent(); expect(wrapper.vm.sections.length).toBe(0); // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert expect(wrapper.vm.sections.length).toBe(4); }); test.each([ ['2004', 'Honda', 'Civic', '2004 Honda Civic'], [null, 'Honda', 'Civic', 'Honda Civic'], ['2004', '', 'Civic', '2004 Civic'], ['2004', 'Honda', null, '2004 Honda'], ['2004', null, undefined, '2004'], [null, null, null, ''] ])( 'when store vehicle has year %p, make %p, and model %p, has line %p', async (year, make, model, line) => { // Arrange const initialStore = { order: { vehicle: { year, make, model } } }; const { wrapper } = getMountedComponent(initialStore); const vehicleSectionIndex = 0; const expectedLines = [line]; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const vehicleSection = wrapper.vm.sections[vehicleSectionIndex]; expect(vehicleSection.lines).toStrictEqual(expectedLines); } ); test('damage section lines equal result from getDamageDisplayContent', async () => { // Arrange const { wrapper } = getMountedComponent(); const damageSectionIndex = 1; const expectedLines = ['hi', 'potato', 'vehicle 3']; getDamageDisplayContent.mockImplementationOnce(() => expectedLines); // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const damageSection = wrapper.vm.sections[damageSectionIndex]; expect(damageSection.lines).toEqual(expectedLines); }); describe('preferred shop section', () => { test('has three lines', async () => { // Arrange const { wrapper } = getMountedComponent(); const preferredShopSectionIndex = 2; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex]; expect(preferredShopSection.lines.length).toBe(3); }); test('first line is value returned from toTitleCase method', async () => { // Arrange const initialData = { companyName: 'some value' }; const { wrapper } = getMountedComponent({}, initialData); const expectedName = 'some expected name'; toTitleCase.mockImplementationOnce(() => expectedName); const preferredShopSectionIndex = 2; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex]; expect(preferredShopSection.lines[0]).toBe(expectedName); }); test('second line is expected and formatAddress called', async () => { // Arrange const address = { streetAddress: '123 South Ln', city: 'Oneida', state: 'FL', zipCode: '78226' }; const initialStore = { order: { serviceLocation: { provider: { address } } } }; const { wrapper } = getMountedComponent(initialStore); const line = 'some returned line'; formatAddress.mockImplementationOnce(() => line); const preferredShopSectionIndex = 2; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex]; expect(preferredShopSection.lines[1]).toBe(line); expect(formatAddress).toHaveBeenCalledTimes(1); expect(formatAddress).toHaveBeenCalledWith( address.streetAddress, null, address.city, address.state, address.zipCode ); }); test('third line is expected and toDisplayPhoneNumber called', async () => { // Arrange const phoneNumber = '9998887777'; const initialStore = { order: { serviceLocation: { provider: { phoneNumber } } } }; const { wrapper } = getMountedComponent(initialStore); const expectedLine = 'returned from to display phone num'; toDisplayPhoneNumber.mockImplementationOnce(() => expectedLine); const preferredShopSectionIndex = 2; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex]; expect(preferredShopSection.lines[2]).toBe(expectedLine); expect(toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber); }); }); test('contact info section has expected content', async () => { // Arrange const firstName = 'Jones'; const lastName = 'Eddison'; const emailAddress = 'myname@gmail.com'; const servicePhone = '0001112222'; const initialStore = { order: { contactInfo: { firstName, lastName, emailAddress, servicePhone } } }; const { wrapper } = getMountedComponent(initialStore); const expectedLine1 = 'Jones Eddison'; const expectedLine2 = emailAddress; const expectedLine3 = 'some value returned'; toDisplayPhoneNumber.mockImplementation((number) => (number === servicePhone ? expectedLine3 : '')); const contactInfoSectionIndex = 3; // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); // Assert const contactInfoSection = wrapper.vm.sections[contactInfoSectionIndex]; expect(contactInfoSection.lines[0]).toBe(expectedLine1); expect(contactInfoSection.lines[1]).toBe(expectedLine2); expect(contactInfoSection.lines[2]).toBe(expectedLine3); expect(toDisplayPhoneNumber).toHaveBeenCalledWith(servicePhone); }); }); describe('computed', () => { test.each([ ['subHeaderTitle', 'SiteSubHeaderWidget', widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT, 'site sub header'], ['subHeaderBodyOne', 'SiteSubHeaderWidget', widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT, 'sub header body one'], ['serviceSummaryText', 'ServiceSummaryContent', widgetFields.TEXT_BLOCK_WIDGET.TEXT, 'service summary text'], ['orderDetailsTitle', 'OrderDetailsContent', widgetFields.CONTENT_GROUP_WIDGET.HEADER_TEXT, 'order details title'], ['forwardButtonText', 'SiteFooterWidget', widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT, 'forward button text'] ])('computed %p returns expected value', (computedName, widgetLabel, fieldLabel, expected) => { // Arrange const mountOptions = getMountOptions(); mountOptions.mixins = [{ methods: { getCmsContent: jest.fn().mockImplementation((widget, field) => (widget === widgetLabel && field === fieldLabel ? expected : '')) } }]; const wrapper = shallowMount(tpaSubmit, mountOptions); // Act const result = wrapper.vm[computedName]; // Assert expect(result).toEqual(expected); }); describe.each([ [false, coverageStatuses.PENDING], [true, coverageStatuses.VERIFIED], [false, coverageStatuses.NO_COVERAGE] ])('isVerified', (expected, status) => { test(`returns ${expected} when coverageStatus is ${getEnumName(coverageStatuses, status)}`, () => { // Arrange const initialStore = { order: { insuranceCoverage: { coverageStatus: status } } }; const { wrapper } = getMountedComponent(initialStore); // Assert expect(wrapper.vm.isVerified).toBe(expected); }); }); test.each([ [5, 5], [-1, -1], [0, 0], [null, null], [undefined, undefined] ])('currentDeductible returns %p when store value %p', (expected, storeValue) => { // Arrange const initialStore = { order: { currentDeductible: storeValue } }; const { wrapper } = getMountedComponent(initialStore); // Assert expect(wrapper.vm.currentDeductible).toBe(expected); }); describe.each([ ['Verifying coverage', coverageStatuses.PENDING], ['$123.46', coverageStatuses.VERIFIED], ['Verifying coverage', coverageStatuses.NO_COVERAGE] ])('deductibleBoxValue', (expected, status) => { test(`returns ${expected} when coverageStatus is ${getEnumName(coverageStatuses, status)}`, () => { // Arrange const initialStore = { order: { insuranceCoverage: { coverageStatus: status }, currentDeductible: 123.456 } }; formatAmountInDollars.mockReturnValue('$123.46'); const { wrapper } = getMountedComponent(initialStore); // Assert expect(wrapper.vm.deductibleBoxValue).toBe(expected); }); }); }); describe('methods', () => { describe('getCustomValueFromString', () => { describe.each([ [false, coverageStatuses.PENDING, 0], [false, coverageStatuses.PENDING, 100], [false, coverageStatuses.VERIFIED, 0], [true, coverageStatuses.VERIFIED, 100], [false, coverageStatuses.NO_COVERAGE, 0], [false, coverageStatuses.NO_COVERAGE, 100] ])('with argument deductibleAboveZero', (expected, status, deductible) => { test(`returns ${expected} when coverageStatus is ${getEnumName(coverageStatuses, status)} and currentDeductible is ${deductible}`, () => { // Arrange const initialStore = { order: { insuranceCoverage: { coverageStatus: status }, currentDeductible: deductible } }; const { wrapper } = getMountedComponent(initialStore); const argument = 'deductibleAboveZero'; // Act const result = wrapper.vm.getCustomValueFromString(argument); // Assert expect(result).toBe(expected); }); }); describe.each([ [false, coverageStatuses.PENDING, 0], [false, coverageStatuses.PENDING, 100], [true, coverageStatuses.VERIFIED, 0], [false, coverageStatuses.VERIFIED, 100], [false, coverageStatuses.NO_COVERAGE, 0], [false, coverageStatuses.NO_COVERAGE, 100] ])('with argument zeroDeductible', (expected, status, deductible) => { test(`returns ${expected} when coverageStatus is ${getEnumName(coverageStatuses, status)} and currentDeductible is ${deductible}`, () => { // Arrange const initialStore = { order: { insuranceCoverage: { coverageStatus: status }, currentDeductible: deductible } }; const { wrapper } = getMountedComponent(initialStore); const argument = 'zeroDeductible'; // Act const result = wrapper.vm.getCustomValueFromString(argument); // Assert expect(result).toBe(expected); }); }); describe.each([ [true, coverageStatuses.PENDING], [false, coverageStatuses.VERIFIED], [true, coverageStatuses.NO_COVERAGE] ])('with argument verifyingCoverage', (expected, status) => { test(`returns ${expected} when coverageStatus is ${getEnumName(coverageStatuses, status)}`, () => { // Arrange const initialStore = { order: { insuranceCoverage: { coverageStatus: status } } }; const { wrapper } = getMountedComponent(initialStore); const argument = 'verifyingCoverage'; // Act const result = wrapper.vm.getCustomValueFromString(argument); // Assert expect(result).toBe(expected); }); }); test('with unknown argument returns null', () => { // Arrange const initialStore = { order: { payment: { insuranceCoverage: { isVerified: true } }, currentDeductible: 26 } }; const { wrapper } = getMountedComponent(initialStore); const argument = 'some random string'; // Act const result = wrapper.vm.getCustomValueFromString(argument); // Assert expect(result).toBe(null); }); }); test.each([ [[1, 5, 6], [1, 5, 6]], [[], []], [undefined, []], [null, []] ])('getInputQuestionWidgetAnswersNullSafe', (rawAnswers, expected) => { // Arrange const widgetName = 'WidgetName'; const { wrapper } = getMountedComponent(); wrapper.vm.getCmsContent = jest.fn().mockImplementationOnce(() => rawAnswers); // Act const result = wrapper.vm.getInputQuestionWidgetAnswersNullSafe(widgetName); // Assert expect(result).toEqual(expected); }); }); });