// Components import schedule from '@/layouts/schedule-page/schedule-page.vue'; // Supporting Files import { createTestingPinia } from '@pinia/testing'; import { shallowMount } from '@vue/test-utils'; import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { useMainStore } from '@/store/index.js'; import { AppointmentTypeStrings } from '@/constants/schedule-constants'; // Mock fetchCmsContentForPage jest.mock('@/helpers/cms-content-helper', () => ({ fetchCmsContentForPage: jest.fn() })); const mockMixin = { methods: { getCmsContent: jest.fn().mockImplementation(() => ''), setCmsContent: jest.fn(), dispatchStoreAction: jest.fn().mockImplementation((storeAction) => { if (storeAction === 'saveSupportingItemsSuppressingStateResetting') { return Promise.resolve([ { partNumber: 'EARLY BIRD', description: null, partType: 'EARLY BIRD', laborAmount: 0, sellingPrice: 14.99, kitPrice: 0 } ]); } return { data: { estimatedServiceMinutesMinimum: 90, estimatedServiceMinutesMaximum: 120, days: [] } }; }) } }; const footerStub = { render: () => {}, methods: { updateButtonText: jest.fn() } }; const loadingModalStub = { render: () => {}, methods: { showModal: jest.fn(), hideModal: jest.fn() } }; function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) { const mountOptions = getMountOptions({ router: { navigate: jest.fn() } }); mountOptions.global.stubs = { siteFooter: footerStub, loadingModal: loadingModalStub }; methodToRun(); mountOptions.mixins = [mockMixin]; mountOptions.data = () => ( initialData ); const wrapper = shallowMount(schedule, mountOptions); return { wrapper }; } beforeEach(() => { const testingPinia = createTestingPinia({ initialState: { main: { order: { schedule: { date: '2019-01-01', startTime: '09:00', endTime: '10:00', routeCode: '000' }, lineItems: { glassParts: [ { partNumber: 'ABC123' } ], supportingItems: [] }, serviceLocation: { appointmentType: 'Inshop', zipCode: '12345', zipCodeCtu: '01234', provider: { providerNumber: '123' } }, damage: { isRepair: false }, referralNumber: '1234567' }, payment: { isInsurance: true }, lineItems: { glassParts: [], supportingItems: [] } } } }); useMainStore(testingPinia); }); afterEach(() => { jest.clearAllMocks(); }); describe('schedule-page.vue', () => { describe('Initial Load', () => { test('Should pass arePagePrerequisitesValid with a mobile order and no providerNumber', () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Mobile'; wrapper.vm.mainStore.order.serviceLocation.provider = null; // Act const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); // Assert expect(arePagePrerequisitesValid).toBe(true); }); test('Should pass arePagePrerequisitesValid with an inshop order and providerNumber', () => { // Arrange const { wrapper } = getShallowMountedComponent(); // Act const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); // Assert expect(arePagePrerequisitesValid).toBe(true); }); test('Should fail arePagePrerequisitesValid with an inshop order and no providerNumber', () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.mainStore.order.serviceLocation.provider.providerNumber = null; // Act const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); // Assert expect(arePagePrerequisitesValid).toBeFalsy(); }); test('Should fail arePagePrerequisitesValid if supportingItems is null', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.mainStore.order.lineItems.supportingItems = null; // Act const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); // Assert expect(arePagePrerequisitesValid).toBe(false); }); test('Should fail arePagePrerequisitesValid with an replace with no glass parts', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.mainStore.order.lineItems.glassParts = []; // Act const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); // Assert expect(arePagePrerequisitesValid).toBe(false); }); test('should return newShopTimeSlots when getAvailableDatesMethod is called', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.selectableDatesData = { days: [] }; const store = useMainStore(); store.getShopTimeSlots.mockImplementation(() => ({ data: { estimatedServiceMinutesMinimum: 90, estimatedServiceMinutesMaximum: 120, days: [ { date: '2023-12-01', timeSlots: [ { id: '06747-01820-S-B*20424*7 AM', startTime: '07:00', endTime: '08:00', offerPremium: false } ] } ] } })); // Act const newShopTimeSlots = await wrapper.vm.getAvailableDatesMethod( '2023-01-01', '2023-01-31' ); // Assert expect(newShopTimeSlots).toStrictEqual({ days: [ { date: '2023-12-01', timeSlots: [ { endTime: '08:00', id: '06747-01820-S-B*20424*7 AM', offerPremium: false, startTime: '07:00' } ] } ], estimatedServiceMinutesMinimum: 90, estimatedServiceMinutesMaximum: 120 }); }); test('Should call API service in days of 34 or less when getAvailableDatesMethod is called with large date ranges', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.selectableDatesData = { days: [] }; const store = useMainStore(); store.getShopTimeSlots.mockImplementation(() => ({ data: { estimatedServiceMinutesMinimum: 90, estimatedServiceMinutesMaximum: 120, days: [] } })); // Act await wrapper.vm.getAvailableDates.call( wrapper.vm, '2023-01-01', '2023-03-31', 'Inshop', '123' ); // Assert // 2023-01-01 --> 2023-02-05 // 2023-02-06 --> 2023-03-12 // 2023-03-13 --> 2023-03-31 expect(store.getShopTimeSlots).toHaveBeenCalledTimes(3); }); }); describe('Rendering', () => { test('Schedule page loads', () => { // Arrange const { wrapper } = getShallowMountedComponent(); // Assert expect(wrapper).toBeTruthy(); }); }); describe('schedule page methods...', () => { test('getServiceZipCtuCodeFromStore should return zipCodeCtu', () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.selectableDatesData = { days: [] }; // Act const testValue = wrapper.vm.getServiceZipCtuCodeFromStore(); // Assert expect(testValue).toStrictEqual('01234'); }); test('getDisplayTextForMilitaryTime should return the correctly formatted string', () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.selectableDatesData = { days: [] }; const timeInput1 = '15:00'; const timeInput2 = '15:30'; // Act const testOutput1 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1); const testOutput2 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2); const testOutput3 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1, true); const testOutput4 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2, true); // Assert expect(testOutput1).toBe('3:00 PM'); expect(testOutput2).toBe('3:30 PM'); expect(testOutput3).toBe('3 PM'); expect(testOutput4).toBe('3:30 PM'); }); }); test('forwardButtonAction should call route method navigateWithoutSaving', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); wrapper.vm.$router.navigate = jest.fn(() => ({})); // Act await wrapper.vm.forwardButtonAction(); // Assert expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); }); });