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';
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
const getAlertReasons = async (ctu) => {
|
export async function getAlertReasons(ctu) {
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
const alertReasons = await store.getAlertReasonsByCtu(ctu);
|
const alertReasons = await store.getAlertReasonsByCtu(ctu);
|
||||||
|
|
||||||
return Promise.resolve(alertReasons);
|
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) {
|
export function calcDaysBetweenDates(dateString1, dateString2) {
|
||||||
|
|
@ -90,5 +70,3 @@ export function getDisplayTextForDurationLength(durationMinimum, durationMaximum
|
||||||
|
|
||||||
return `${durationText} ${unitText}`;
|
return `${durationText} ${unitText}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getAlertReasons;
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import alert from '@/ux-components/alert/alert.vue';
|
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 {
|
export default {
|
||||||
name: 'location-alerts',
|
name: 'location-alerts',
|
||||||
|
|
@ -44,7 +44,7 @@ export default {
|
||||||
if (providerCtu) {
|
if (providerCtu) {
|
||||||
ctuToUse = providerCtu;
|
ctuToUse = providerCtu;
|
||||||
}
|
}
|
||||||
return mockGetAlertReasons(ctuToUse); // Change to getAlertReasons after testing.
|
return getAlertReasons(ctuToUse);
|
||||||
},
|
},
|
||||||
initializeComponent(initialData) {
|
initializeComponent(initialData) {
|
||||||
this.alertReasons = initialData;
|
this.alertReasons = initialData;
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,50 @@ import { createTestingPinia } from '@pinia/testing';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store/index.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 = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
getCmsContent: jest.fn().mockImplementation(() => ''),
|
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 = {
|
mountOptions.global.stubs = {
|
||||||
siteFooter: footerStub,
|
siteFooter: footerStub,
|
||||||
siteHeader: true,
|
|
||||||
recalModal: true,
|
|
||||||
contentGroupModal: true,
|
|
||||||
alert: true,
|
|
||||||
loadingModal: loadingModalStub
|
loadingModal: loadingModalStub
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,6 +137,9 @@ beforeEach(() => {
|
||||||
});
|
});
|
||||||
useMainStore(testingPinia);
|
useMainStore(testingPinia);
|
||||||
});
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
describe('schedule-page.vue', () => {
|
describe('schedule-page.vue', () => {
|
||||||
describe('Initial Load', () => {
|
describe('Initial Load', () => {
|
||||||
|
|
@ -171,6 +209,88 @@ describe('schedule-page.vue', () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(false);
|
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', () => {
|
describe('Rendering', () => {
|
||||||
test('Schedule page loads', () => {
|
test('Schedule page loads', () => {
|
||||||
|
|
@ -181,4 +301,128 @@ describe('schedule-page.vue', () => {
|
||||||
expect(wrapper).toBeTruthy();
|
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.appointmentType === AppointmentTypeStrings.MOBILE
|
||||||
&& this.selectedTimeSlotInfo?.isPremiumAppointment
|
&& 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) {
|
if (premiumFeeIndex >= 0) {
|
||||||
supportingItems[earlyBirdIndex].laborAmount =
|
supportingItems[premiumFeeIndex].laborAmount =
|
||||||
this.mobilePremiumAppointmentFee.laborAmount;
|
this.mobilePremiumAppointmentFee.laborAmount;
|
||||||
supportingItems[earlyBirdIndex].selingPrice =
|
supportingItems[premiumFeeIndex].sellingPrice =
|
||||||
this.mobilePremiumAppointmentFee.selingPrice;
|
this.mobilePremiumAppointmentFee.sellingPrice;
|
||||||
supportingItems[earlyBirdIndex].kitPrice =
|
supportingItems[premiumFeeIndex].kitPrice =
|
||||||
this.mobilePremiumAppointmentFee.kitPrice;
|
this.mobilePremiumAppointmentFee.kitPrice;
|
||||||
} else {
|
} else {
|
||||||
supportingItems.push(this.mobilePremiumAppointmentFee);
|
supportingItems.push(this.mobilePremiumAppointmentFee);
|
||||||
|
|
@ -453,10 +453,10 @@ export default {
|
||||||
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
||||||
} else {
|
} else {
|
||||||
// if it's not a mobile and/or premium early bird, then make sure we remove any that may have been added
|
// 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) {
|
if (removePremiumFeeIndex >= 0) {
|
||||||
supportingItems.splice(removeEarlyBirdIndex, 1);
|
supportingItems.splice(removePremiumFeeIndex, 1);
|
||||||
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
this.mainStore.saveSupportingItemsSuppressingStateResetting(supportingItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue