Merge pull request #485 from Safelite/feature/richardson/SSR-676.3

Add schedule tests
This commit is contained in:
brich1212safe 2023-10-18 16:14:30 -04:00 committed by GitHub
commit ad1c46f509
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 261 additions and 39 deletions

View file

@ -1,30 +1,10 @@
import { useMainStore } from '@/store';
const getAlertReasons = async (ctu) => {
export async function getAlertReasons(ctu) {
const store = useMainStore();
const alertReasons = await store.getAlertReasonsByCtu(ctu);
return Promise.resolve(alertReasons);
};
// This function will go away after testing.
// The Service already went through testing and had these removed from it.
export async function mockGetAlertReasons(ctu) {
let retList = [];
if (ctu === '01853') { // Ocala, FL 34470
retList = [
'Hurricane', 'ExtremeTemperature'
];
} else if (ctu === '01814') { // Phoenix, AZ 85026
retList = [
'ExtremeTemperature'
];
} else if (ctu === '01845') { // Raleigh, NC 27601
retList = [
'Hurricane'
];
}
return Promise.resolve(retList);
}
export function calcDaysBetweenDates(dateString1, dateString2) {
@ -90,5 +70,3 @@ export function getDisplayTextForDurationLength(durationMinimum, durationMaximum
return `${durationText} ${unitText}`;
}
export default getAlertReasons;

View file

@ -9,7 +9,7 @@
</template>
<script>
import alert from '@/ux-components/alert/alert.vue';
import { mockGetAlertReasons } from '@/layouts/schedule-page/helpers/schedule-helper';
import { getAlertReasons } from '@/layouts/schedule-page/helpers/schedule-helper';
export default {
name: 'location-alerts',
@ -44,7 +44,7 @@ export default {
if (providerCtu) {
ctuToUse = providerCtu;
}
return mockGetAlertReasons(ctuToUse); // Change to getAlertReasons after testing.
return getAlertReasons(ctuToUse);
},
initializeComponent(initialData) {
this.alertReasons = initialData;

View file

@ -6,11 +6,50 @@ 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()
setCmsContent: jest.fn(),
dispatchStoreAction: jest.fn().mockImplementation((storeAction) => {
if (storeAction === 'priceOrderItemsAndSaveServerData') {
return Promise.resolve([
{
partNumber: 'EARLY BIRD',
description: null,
partType: 'EARLY BIRD',
laborAmount: 0,
sellingPrice: 14.99,
kitPrice: 0
}
]);
}
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: []
}
};
})
}
};
@ -40,10 +79,6 @@ function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
mountOptions.global.stubs = {
siteFooter: footerStub,
siteHeader: true,
recalModal: true,
contentGroupModal: true,
alert: true,
loadingModal: loadingModalStub
};
@ -102,6 +137,9 @@ beforeEach(() => {
});
useMainStore(testingPinia);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('schedule-page.vue', () => {
describe('Initial Load', () => {
@ -171,6 +209,88 @@ describe('schedule-page.vue', () => {
// 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', () => {
@ -181,4 +301,128 @@ describe('schedule-page.vue', () => {
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();
});
test('for mobile appts, updateSupportingItems should call store action to save supporting items', async () => {
// Arrange
const { wrapper } = getShallowMountedComponent();
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = true;
wrapper.vm.mainStore.lineItems.supportingItems = [
{
partNumber: 'EARLY BIRD',
description: null,
partType: 'EARLY BIRD',
laborAmount: 0,
sellingPrice: 0,
kitPrice: 0
}
];
const store = useMainStore();
// Act
await wrapper.vm.updateSupportingItems();
// Assert
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(1);
expect(wrapper.vm.mainStore.lineItems.supportingItems)
.toEqual(expect.arrayContaining([
expect.objectContaining({
partType: 'EARLY BIRD'
})
]));
});
test(
'for Inshop appts, updateSupportingItems should call store action to save supporting items WITHOUT the EARLY BIRD supporting item',
async () => {
// Arrange
const { wrapper } = getShallowMountedComponent();
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = true;
wrapper.vm.mainStore.lineItems.supportingItems = [
{
partNumber: 'EARLY BIRD',
description: null,
partType: 'EARLY BIRD',
laborAmount: 0,
sellingPrice: 0,
kitPrice: 0
}
];
const store = useMainStore();
// Act
await wrapper.vm.updateSupportingItems();
// Assert
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(1);
expect(wrapper.vm.mainStore.lineItems.supportingItems)
.not.toEqual(expect.arrayContaining([
expect.objectContaining({
partType: 'EARLY BIRD'
})
]));
}
);
test('if no EARLY BIRD supporting item, then updateSupportingItems should NOT call store action', async () => {
// Arrange
const { wrapper } = getShallowMountedComponent();
wrapper.vm.mainStore.order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
wrapper.vm.mobilePremiumAppointmentFee = 14.99;
wrapper.vm.selectedTimeSlotInfo.isPremiumAppointment = false;
wrapper.vm.mainStore.lineItems.supportingItems = [];
const store = useMainStore();
// Act
await wrapper.vm.updateSupportingItems();
// Assert
expect(store.saveSupportingItemsSuppressingStateResetting).toHaveBeenCalledTimes(0);
});
});

View file

@ -437,14 +437,14 @@ export default {
this.appointmentType === AppointmentTypeStrings.MOBILE
&& this.selectedTimeSlotInfo?.isPremiumAppointment
) {
const earlyBirdIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
const premiumFeeIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
if (earlyBirdIndex >= 0) {
supportingItems[earlyBirdIndex].laborAmount =
if (premiumFeeIndex >= 0) {
supportingItems[premiumFeeIndex].laborAmount =
this.mobilePremiumAppointmentFee.laborAmount;
supportingItems[earlyBirdIndex].selingPrice =
this.mobilePremiumAppointmentFee.selingPrice;
supportingItems[earlyBirdIndex].kitPrice =
supportingItems[premiumFeeIndex].sellingPrice =
this.mobilePremiumAppointmentFee.sellingPrice;
supportingItems[premiumFeeIndex].kitPrice =
this.mobilePremiumAppointmentFee.kitPrice;
} else {
supportingItems.push(this.mobilePremiumAppointmentFee);
@ -453,10 +453,10 @@ export default {
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
} else {
// if it's not a mobile and/or premium early bird, then make sure we remove any that may have been added
const removeEarlyBirdIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
const removePremiumFeeIndex = supportingItems.findIndex((item) => item.partType === PREMIUM_FEE_PART_TYPE);
if (removeEarlyBirdIndex >= 0) {
supportingItems.splice(removeEarlyBirdIndex, 1);
if (removePremiumFeeIndex >= 0) {
supportingItems.splice(removePremiumFeeIndex, 1);
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
}
}