Merge pull request #485 from Safelite/feature/richardson/SSR-676.3
Add schedule tests
This commit is contained in:
commit
ad1c46f509
4 changed files with 261 additions and 39 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue