// 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((str, customValueMap) => { let newString = str ?? ''; if (customValueMap != null) { Object.keys(customValueMap).forEach((key) => { newString = newString.replaceAll(`{custom:${key}}`, customValueMap[key]); }); } return newString; }), 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('sub header', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const subHeader = wrapper.findComponent({ ref: 'subHeaderTitle' }); // Assert expect(subHeader.exists()).toBeTruthy(); expect(subHeader.classes()).toContain('tpa-submit-title'); }); test('sub header body one', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const subHeaderBodyOne = wrapper.findComponent({ ref: 'tpaSubmitSubHeaderBodyOne' }); // Assert expect(subHeaderBodyOne.exists()).toBeTruthy(); }); test('service summary section', () => { // Arrange const wrapper = shallowMount(tpaSubmit, getMountOptions()); // Act const serviceSummarySection = wrapper.find('#serviceSummarySection'); // Assert expect(serviceSummarySection.exists()).toBeTruthy(); }); 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.classes()).toContain('fw-bold'); expect(submitOrderDetailsTitle.classes()).toContain('order-details-title'); }); 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 2 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(2); }); describe('preferred shop section', () => { test('has two lines', async () => { // Arrange const { wrapper } = getMountedComponent(); const preferredShopSectionIndex = 0; // 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(2); }); test('title 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 = 0; // 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.title).toBe(expectedName); }); test('first 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 = 0; // 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(line); expect(formatAddress).toHaveBeenCalledTimes(1); expect(formatAddress).toHaveBeenCalledWith( address.streetAddress, null, address.city, address.state, address.zipCode ); }); test('second 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 = 0; // 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(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 providerCompanyName = 'Some Provider LLC'; const initialStore = { order: { serviceLocation: { provider: { companyName: providerCompanyName } }, customer: { firstName, lastName, emailAddress }, contactInfo: { servicePhone } } }; const { wrapper } = getMountedComponent(initialStore); const expectedEmail = emailAddress; const expectedPhone = 'some value returned'; toDisplayPhoneNumber.mockImplementation((number) => (number === servicePhone ? expectedPhone : '')); const contactInfoSectionIndex = 1; wrapper.vm.getCmsContent.mockImplementation(() => '{custom:contactPhone} or {custom:contactEmail}'); // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); wrapper.vm.setSections(); // Assert const contactInfoSection = wrapper.vm.sections[contactInfoSectionIndex]; expect(contactInfoSection.lines[0]).toContain(expectedEmail); expect(contactInfoSection.lines[0]).toContain(expectedPhone); expect(toDisplayPhoneNumber).toHaveBeenCalledWith(servicePhone); }); test('contact info section has expected content with extension', async () => { // Arrange const firstName = 'Jones'; const lastName = 'Eddison'; const emailAddress = 'myname@gmail.com'; const servicePhone = '0001112222'; const extension = '12345'; const providerCompanyName = 'Some Provider LLC'; const initialStore = { order: { serviceLocation: { provider: { companyName: providerCompanyName } }, customer: { firstName, lastName, emailAddress }, contactInfo: { servicePhone, extension } } }; const { wrapper } = getMountedComponent(initialStore); const expectedEmail = emailAddress; const expectedPhone = 'some value returned'; toDisplayPhoneNumber.mockImplementation((number) => (number === servicePhone ? expectedPhone : '')); const contactInfoSectionIndex = 1; wrapper.vm.getCmsContent.mockImplementation(() => '{custom:contactPhone} or {custom:contactEmail}'); // Act await tpaSubmit.beforeRouteEnter.call( wrapper.vm, { query: { issPage: 'tpa-submit' } }, undefined, (c) => c(wrapper.vm) ); wrapper.vm.setSections(); // Assert const contactInfoSection = wrapper.vm.sections[contactInfoSectionIndex]; expect(contactInfoSection.lines[0]).toContain(expectedEmail); expect(contactInfoSection.lines[0]).toContain(expectedPhone); expect(contactInfoSection.lines[0]).toContain(`Ext. ${extension}`); 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'], ['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: { replace: 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: { replace: deductible, repair: 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: { replace: deductible, repair: 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); }); }); });