Merge pull request #1331 from Safelite/feature/CSR-1621
Feature/csr 1621
This commit is contained in:
commit
bbb1bce769
5 changed files with 460 additions and 219 deletions
|
|
@ -4,7 +4,7 @@ const AppointmentTypeStrings = {
|
||||||
DROP_OFF: "Dropoff",
|
DROP_OFF: "Dropoff",
|
||||||
};
|
};
|
||||||
|
|
||||||
const PREMIUM_TIME_SLOT_ID_FLAG = "-premium";
|
const PREMIUM_TIME_SLOT_ID_FLAG = "-PREMIUM";
|
||||||
|
|
||||||
const PREMIUM_FEE_PART_TYPE = "EARLY BIRD";
|
const PREMIUM_FEE_PART_TYPE = "EARLY BIRD";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { nextTick } from "vue";
|
|
||||||
import baseMixin from "../../mixins/base-mixin";
|
import baseMixin from "../../mixins/base-mixin";
|
||||||
|
|
||||||
// Mock basemixin
|
// Mock basemixin
|
||||||
|
|
@ -130,64 +129,67 @@ afterEach(() => {
|
||||||
describe("schedule.vue...", () => {
|
describe("schedule.vue...", () => {
|
||||||
describe("initial load", () => {
|
describe("initial load", () => {
|
||||||
test("should pass arePagePrerequisitesValid with a mobile order and no providerNumber", () => {
|
test("should pass arePagePrerequisitesValid with a mobile order and no providerNumber", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
||||||
store.getters.order.serviceLocation.provider = null;
|
store.getters.order.serviceLocation.provider = null;
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should pass arePagePrerequisitesValid with a inshop order and providerNumber", () => {
|
test("should pass arePagePrerequisitesValid with a inshop order and providerNumber", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should fail arePagePrerequisitesValid with a replace with no glass parts", async () => {
|
test("should fail arePagePrerequisitesValid with a replace with no glass parts", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
store.getters.order.lineItems.glassParts = [];
|
store.getters.order.lineItems.glassParts = [];
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const arePagePrerequisitesValid2 = await wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid2 = await wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid2).toBe(false);
|
expect(arePagePrerequisitesValid2).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should fail arePagePrerequisitesValid without isInsurance", () => {
|
test("should fail arePagePrerequisitesValid without isInsurance", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
store.getters.payment.isInsurance = null;
|
store.getters.payment.isInsurance = null;
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(false);
|
expect(arePagePrerequisitesValid).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should return newShopTimeSlots when getAvailableDatesMethod is called", async () => {
|
test("should return newShopTimeSlots when getAvailableDatesMethod is called", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const newShopTimeSlots = await wrapper.vm.getAvailableDatesMethod(
|
const newShopTimeSlots = await wrapper.vm.getAvailableDatesMethod(
|
||||||
"2023-01-01",
|
"2023-01-01",
|
||||||
"2023-01-31"
|
"2023-01-31"
|
||||||
);
|
);
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(newShopTimeSlots).toStrictEqual({
|
expect(newShopTimeSlots).toStrictEqual({
|
||||||
days: [
|
days: [
|
||||||
{
|
{
|
||||||
|
|
@ -208,13 +210,13 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should call API service in day ranges of 34 or less when getAvailableDatesMethod is called with large date ranges", async () => {
|
test("should call API service in day ranges of 34 or less when getAvailableDatesMethod is called with large date ranges", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await wrapper.vm.getAvailableDates.call(
|
await wrapper.vm.getAvailableDates.call(
|
||||||
wrapper.vm,
|
wrapper.vm,
|
||||||
"2023-01-01",
|
"2023-01-01",
|
||||||
|
|
@ -223,7 +225,7 @@ describe("schedule.vue...", () => {
|
||||||
"123"
|
"123"
|
||||||
);
|
);
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledTimes(3);
|
expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledTimes(3);
|
||||||
expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
|
||||||
"getShopTimeSlots",
|
"getShopTimeSlots",
|
||||||
|
|
@ -234,7 +236,7 @@ describe("schedule.vue...", () => {
|
||||||
|
|
||||||
describe("beforeRouteEnter function... ", () => {
|
describe("beforeRouteEnter function... ", () => {
|
||||||
test("should call next() and call all functions within next", async () => {
|
test("should call next() and call all functions within next", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
|
|
@ -244,7 +246,7 @@ describe("schedule.vue...", () => {
|
||||||
c(wrapper.vm);
|
c(wrapper.vm);
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await schedule.beforeRouteEnter.call(
|
await schedule.beforeRouteEnter.call(
|
||||||
wrapper.vm,
|
wrapper.vm,
|
||||||
{ query: { fmgPage: "schedule" } },
|
{ query: { fmgPage: "schedule" } },
|
||||||
|
|
@ -252,7 +254,7 @@ describe("schedule.vue...", () => {
|
||||||
nextFunction
|
nextFunction
|
||||||
);
|
);
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(nextFunction).toHaveBeenCalled();
|
expect(nextFunction).toHaveBeenCalled();
|
||||||
expect(wrapper.vm.setCmsContent).toHaveBeenCalledWith("content");
|
expect(wrapper.vm.setCmsContent).toHaveBeenCalledWith("content");
|
||||||
expect(wrapper.vm.$refs.datePicker.initializeComponent).toHaveBeenCalledWith(
|
expect(wrapper.vm.$refs.datePicker.initializeComponent).toHaveBeenCalledWith(
|
||||||
|
|
@ -279,7 +281,7 @@ describe("schedule.vue...", () => {
|
||||||
|
|
||||||
describe("computed properties...", () => {
|
describe("computed properties...", () => {
|
||||||
test("timeSlotsForSelectedDate should return timeslots if selected date is available", () => {
|
test("timeSlotsForSelectedDate should return timeslots if selected date is available", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [
|
days: [
|
||||||
|
|
@ -306,10 +308,10 @@ describe("schedule.vue...", () => {
|
||||||
selectedDate: "2022-11-11",
|
selectedDate: "2022-11-11",
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const testValue = wrapper.vm.timeSlotsForSelectedDate;
|
const testValue = wrapper.vm.timeSlotsForSelectedDate;
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(testValue).toStrictEqual(
|
expect(testValue).toStrictEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
date: "2022-11-11",
|
date: "2022-11-11",
|
||||||
|
|
@ -318,7 +320,7 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("timeSlotsForSelectedDate should be null if no date has been selected", () => {
|
test("timeSlotsForSelectedDate should be null if no date has been selected", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [
|
days: [
|
||||||
|
|
@ -345,10 +347,10 @@ describe("schedule.vue...", () => {
|
||||||
selectedDate: undefined,
|
selectedDate: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const testValue = wrapper.vm.timeSlotsForSelectedDate;
|
const testValue = wrapper.vm.timeSlotsForSelectedDate;
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(testValue).toBe(null);
|
expect(testValue).toBe(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -356,75 +358,67 @@ describe("schedule.vue...", () => {
|
||||||
|
|
||||||
describe("schedule page methods...", () => {
|
describe("schedule page methods...", () => {
|
||||||
test("getServiceZipCtuCodeFromStore should return zipCodeCtu", () => {
|
test("getServiceZipCtuCodeFromStore should return zipCodeCtu", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const testValue = wrapper.vm.getServiceZipCtuCodeFromStore();
|
const testValue = wrapper.vm.getServiceZipCtuCodeFromStore();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(testValue).toStrictEqual("01234");
|
expect(testValue).toStrictEqual("01234");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("openInshopTimeSlotsModal should trigger openModal method", () => {
|
test("openInshopTimeSlotsModal should trigger openModal method", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
wrapper.vm.openInshopTimeSlotsModal();
|
wrapper.vm.openInshopTimeSlotsModal();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.$refs.timeSlotModalQuestion.openModal).toBeCalled();
|
expect(wrapper.vm.$refs.timeSlotModalQuestion.openModal).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getSelectedRouteCode should return schedule routeCode", () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({});
|
|
||||||
|
|
||||||
wrapper.vm.selectableDatesData = {
|
|
||||||
days: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const testValue = wrapper.vm.getSelectedRouteCode();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(testValue).toStrictEqual("000");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("timeSlotModalClosed should null any selected date when there's no route code", () => {
|
test("timeSlotModalClosed should null any selected date when there's no route code", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
wrapper.setData({
|
wrapper.setData({
|
||||||
selectedDate: "1980-05-05",
|
selectedDate: "1980-05-05",
|
||||||
});
|
});
|
||||||
wrapper.setData({
|
|
||||||
selectedTimeSlot: {
|
const selectedTimeSlotInfo = {
|
||||||
|
timeSlot: {
|
||||||
date: "2019-01-01",
|
date: "2019-01-01",
|
||||||
startTime: "09:00",
|
startTime: "09:00",
|
||||||
endTime: "10:00",
|
endTime: "10:00",
|
||||||
routeCode: null,
|
routeCode: null,
|
||||||
},
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapper.setData({
|
||||||
|
selectedTimeSlotInfo: selectedTimeSlotInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
wrapper.vm.timeSlotModalClosed();
|
wrapper.vm.timeSlotModalClosed();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.selectedDate).toBe(null);
|
expect(wrapper.vm.selectedDate).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
|
test("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
|
|
@ -432,13 +426,13 @@ describe("schedule.vue...", () => {
|
||||||
const timeInput1 = "15:00";
|
const timeInput1 = "15:00";
|
||||||
const timeInput2 = "15:30";
|
const timeInput2 = "15:30";
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
const testOutput1 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1);
|
const testOutput1 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1);
|
||||||
const testOutput2 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2);
|
const testOutput2 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2);
|
||||||
const testOutput3 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1, true);
|
const testOutput3 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput1, true);
|
||||||
const testOutput4 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2, true);
|
const testOutput4 = wrapper.vm.getDisplayTextForMilitaryTime(timeInput2, true);
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(testOutput1).toBe("3:00 PM");
|
expect(testOutput1).toBe("3:00 PM");
|
||||||
expect(testOutput2).toBe("3:30 PM");
|
expect(testOutput2).toBe("3:30 PM");
|
||||||
expect(testOutput3).toBe("3 PM");
|
expect(testOutput3).toBe("3 PM");
|
||||||
|
|
@ -446,7 +440,7 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
|
test("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.selectableDatesData = {
|
wrapper.vm.selectableDatesData = {
|
||||||
days: [],
|
days: [],
|
||||||
|
|
@ -454,10 +448,10 @@ describe("schedule.vue...", () => {
|
||||||
wrapper.vm.$router.navigateWithoutSaving = jest.fn();
|
wrapper.vm.$router.navigateWithoutSaving = jest.fn();
|
||||||
wrapper.vm.$route = "testRoute";
|
wrapper.vm.$route = "testRoute";
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
||||||
"CLICKED_BACK",
|
"CLICKED_BACK",
|
||||||
"testRoute"
|
"testRoute"
|
||||||
|
|
@ -466,7 +460,7 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("forwardButtonAction should call route method navigateWithoutSaving", async () => {
|
test("forwardButtonAction should call route method navigateWithoutSaving", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -477,15 +471,15 @@ describe("schedule.vue...", () => {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("for mobile appts, updateSupportingItems should call store action to save supporting items", async () => {
|
test("for mobile appts, updateSupportingItems should call store action to save supporting items", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
||||||
store.getters.lineItems.supportingItems = [
|
store.getters.lineItems.supportingItems = [
|
||||||
{
|
{
|
||||||
|
|
@ -514,10 +508,10 @@ describe("schedule.vue...", () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await wrapper.vm.updateSupportingItems();
|
await wrapper.vm.updateSupportingItems();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
|
expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
|
||||||
"saveSupportingItemsSuppressingStateResetting",
|
"saveSupportingItemsSuppressingStateResetting",
|
||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
|
|
@ -530,7 +524,7 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("for Inshop appts, updateSupportingItems should call store action to save supporting items WITHOUT the EARLY BIRD supporting item", async () => {
|
test("for Inshop appts, updateSupportingItems should call store action to save supporting items WITHOUT the EARLY BIRD supporting item", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
store.getters.order.serviceLocation.appointmentType = "Inshop";
|
store.getters.order.serviceLocation.appointmentType = "Inshop";
|
||||||
store.getters.lineItems.supportingItems = [
|
store.getters.lineItems.supportingItems = [
|
||||||
{
|
{
|
||||||
|
|
@ -559,10 +553,10 @@ describe("schedule.vue...", () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await wrapper.vm.updateSupportingItems();
|
await wrapper.vm.updateSupportingItems();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
|
expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
|
||||||
"saveSupportingItemsSuppressingStateResetting",
|
"saveSupportingItemsSuppressingStateResetting",
|
||||||
expect.not.arrayContaining([
|
expect.not.arrayContaining([
|
||||||
|
|
@ -575,7 +569,7 @@ describe("schedule.vue...", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("if no EARLY BIRD supporting item, then updateSupportingItems should NOT call store action", async () => {
|
test("if no EARLY BIRD supporting item, then updateSupportingItems should NOT call store action", async () => {
|
||||||
//Arrange
|
// Arrange
|
||||||
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
store.getters.order.serviceLocation.appointmentType = "Mobile";
|
||||||
store.getters.lineItems.supportingItems = [];
|
store.getters.lineItems.supportingItems = [];
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -595,10 +589,10 @@ describe("schedule.vue...", () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
// Act
|
||||||
await wrapper.vm.updateSupportingItems();
|
await wrapper.vm.updateSupportingItems();
|
||||||
|
|
||||||
//Assert
|
// Assert
|
||||||
expect(wrapper.vm.dispatchStoreAction).not.toBeCalled();
|
expect(wrapper.vm.dispatchStoreAction).not.toBeCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,17 @@
|
||||||
<timeSlotModalQuestion
|
<timeSlotModalQuestion
|
||||||
ref="timeSlotModalQuestion"
|
ref="timeSlotModalQuestion"
|
||||||
customComponentId="timeSlotModalQuestion"
|
customComponentId="timeSlotModalQuestion"
|
||||||
|
v-model="selectedTimeSlotInfo"
|
||||||
cmsWidgetName="TimeSlotModalQuestion"
|
cmsWidgetName="TimeSlotModalQuestion"
|
||||||
mobilePremiumCmsWidgetName="MobilePremiumTimeSlotModal"
|
mobilePremiumCmsWidgetName="MobilePremiumTimeSlotModal"
|
||||||
mobileCmsWidgetName="MobileTimeSlotModal"
|
mobileCmsWidgetName="MobileTimeSlotModal"
|
||||||
dropoffCmsWidgetName="DropOffTimeSlotModal"
|
dropoffCmsWidgetName="DropOffTimeSlotModal"
|
||||||
sameDayDropOffCmsWidgetName="SameDayDropOffTimeSlotModal"
|
sameDayDropOffCmsWidgetName="SameDayDropOffTimeSlotModal"
|
||||||
overnightDropOffCmsWidgetName="OvernightDropOffTimeSlotModal"
|
overnightDropOffCmsWidgetName="OvernightDropOffTimeSlotModal"
|
||||||
v-model="selectedTimeSlot"
|
|
||||||
:selectedDate="selectedDate"
|
:selectedDate="selectedDate"
|
||||||
:appointmentType="appointmentType"
|
:appointmentType="appointmentType"
|
||||||
:premiumAppointmentFee="mobilePremiumAppointmentFee"
|
:premiumAppointmentFee="mobilePremiumAppointmentFee"
|
||||||
:dateAndTimeSlotData="timeSlotsForSelectedDate"
|
:timeSlotsForSelectedDate="timeSlotsForSelectedDate"
|
||||||
:estimatedServiceMinutesMinimum="selectableDatesData.estimatedServiceMinutesMinimum"
|
:estimatedServiceMinutesMinimum="selectableDatesData.estimatedServiceMinutesMinimum"
|
||||||
:estimatedServiceMinutesMaximum="selectableDatesData.estimatedServiceMinutesMaximum"
|
:estimatedServiceMinutesMaximum="selectableDatesData.estimatedServiceMinutesMaximum"
|
||||||
@time-slot-modal-closed="timeSlotModalClosed"
|
@time-slot-modal-closed="timeSlotModalClosed"
|
||||||
|
|
@ -81,12 +81,7 @@ import store from "@/store";
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
|
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
|
||||||
defineRule("time-slot-selection-required", (value) => {
|
defineRule("time-slot-selection-required", (value) => {
|
||||||
if (
|
if (value?.timeSlot?.routeCode == null) {
|
||||||
value.date == null ||
|
|
||||||
value.startTime == null ||
|
|
||||||
value.routeCode == null ||
|
|
||||||
value.estimatedServiceMinutesMaximum
|
|
||||||
) {
|
|
||||||
return errorMessages.DATE_REQUIRED;
|
return errorMessages.DATE_REQUIRED;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -190,7 +185,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedDate: this.getSelectedDate(),
|
selectedDate: this.getSelectedDate(),
|
||||||
selectedTimeSlot: this.getSelectedTimeSlot(),
|
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
|
||||||
selectableDatesData: [],
|
selectableDatesData: [],
|
||||||
mobilePremiumAppointmentFee: null,
|
mobilePremiumAppointmentFee: null,
|
||||||
};
|
};
|
||||||
|
|
@ -265,7 +260,7 @@ export default {
|
||||||
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
|
vm.mobilePremiumAppointmentFee = resultMap.premiumFeeWithPrice
|
||||||
? resultMap.premiumFeeWithPrice[0]
|
? resultMap.premiumFeeWithPrice[0]
|
||||||
: null;
|
: null;
|
||||||
vm.updateFooterButtonText(vm.selectedTimeSlot);
|
vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -293,18 +288,22 @@ export default {
|
||||||
splitCopyOnCMSPlaceHolder,
|
splitCopyOnCMSPlaceHolder,
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const serviceLocation = store.getters.order.serviceLocation;
|
const serviceLocation = store.getters.order.serviceLocation;
|
||||||
|
|
||||||
const serviceLocationPreReqs =
|
const serviceLocationPreReqs =
|
||||||
serviceLocation.zipCode &&
|
serviceLocation.zipCode &&
|
||||||
serviceLocation.zipCodeCtu &&
|
serviceLocation.zipCodeCtu &&
|
||||||
serviceLocation.appointmentType &&
|
serviceLocation.appointmentType &&
|
||||||
(serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE ||
|
(serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE ||
|
||||||
serviceLocation.provider.providerNumber);
|
serviceLocation.provider.providerNumber);
|
||||||
|
|
||||||
const paymentInfo = store.getters.payment.isInsurance !== null;
|
const paymentInfo = store.getters.payment.isInsurance !== null;
|
||||||
const supportingItems = store.getters.lineItems.supportingItems !== null;
|
const supportingItems = store.getters.lineItems.supportingItems !== null;
|
||||||
|
|
||||||
const damageInfo =
|
const damageInfo =
|
||||||
store.getters.order.damage.isRepair ||
|
store.getters.order.damage.isRepair ||
|
||||||
(store.getters.order.lineItems?.glassParts != null &&
|
(store.getters.order.lineItems?.glassParts != null &&
|
||||||
store.getters.order.lineItems.glassParts.length > 0);
|
store.getters.order.lineItems.glassParts.length > 0);
|
||||||
|
|
||||||
return serviceLocationPreReqs && paymentInfo && supportingItems && damageInfo;
|
return serviceLocationPreReqs && paymentInfo && supportingItems && damageInfo;
|
||||||
},
|
},
|
||||||
async getAvailableDatesMethod(startDate, endDate) {
|
async getAvailableDatesMethod(startDate, endDate) {
|
||||||
|
|
@ -327,45 +326,55 @@ export default {
|
||||||
openInshopTimeSlotsModal() {
|
openInshopTimeSlotsModal() {
|
||||||
this.$refs["timeSlotModalQuestion"].openModal();
|
this.$refs["timeSlotModalQuestion"].openModal();
|
||||||
},
|
},
|
||||||
getSelectedTimeSlot() {
|
|
||||||
return store.getters.order.schedule;
|
|
||||||
},
|
|
||||||
getSelectedDate() {
|
getSelectedDate() {
|
||||||
return store.getters.order.schedule.date;
|
return store.getters.order.schedule.date;
|
||||||
},
|
},
|
||||||
getSelectedRouteCode() {
|
getSelectedTimeSlotInfo() {
|
||||||
return store.getters.order.schedule.routeCode;
|
const supportingItems = this.getSupportingItems();
|
||||||
|
const isPremiumAppointment =
|
||||||
|
!!supportingItems.filter((lineItem) => lineItem.partType === PREMIUM_FEE_PART_TYPE)
|
||||||
|
.length > 0;
|
||||||
|
|
||||||
|
const selectedTimeSlotInfo = {
|
||||||
|
timeSlot: store.getters.order.schedule,
|
||||||
|
isPremiumAppointment: isPremiumAppointment,
|
||||||
|
};
|
||||||
|
|
||||||
|
return selectedTimeSlotInfo;
|
||||||
},
|
},
|
||||||
getSupportingItems() {
|
getSupportingItems() {
|
||||||
return store.getters.lineItems.supportingItems;
|
return store.getters.lineItems.supportingItems;
|
||||||
},
|
},
|
||||||
timeSlotModalClosed() {
|
timeSlotModalClosed() {
|
||||||
// Clear the selectedDate if no timeSlot has been selected
|
// Clear the selectedDate if no timeSlot has been selected
|
||||||
if (this.selectedTimeSlot.routeCode == null) {
|
if (this.selectedTimeSlotInfo.timeSlot.routeCode == null) {
|
||||||
this.selectedDate = null;
|
this.selectedDate = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateFooterButtonText(timeSlot) {
|
updateFooterButtonText(timeSlotInfo) {
|
||||||
let funnelFooterButtonText;
|
let funnelFooterButtonText;
|
||||||
if (!timeSlot || !timeSlot.date) {
|
if (!timeSlotInfo || !timeSlotInfo.timeSlot.date) {
|
||||||
funnelFooterButtonText = "Continue";
|
funnelFooterButtonText = "Continue";
|
||||||
} else {
|
} else {
|
||||||
funnelFooterButtonText = `Select ${this.convertSelectedDateToShortMonthAndDay(
|
funnelFooterButtonText = `Select ${this.convertSelectedDateToShortMonthAndDay(
|
||||||
timeSlot.date
|
timeSlotInfo.timeSlot.date
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
||||||
funnelFooterButtonText += ` at ${this.getDisplayTextForMilitaryTime(
|
funnelFooterButtonText += ` at ${this.getDisplayTextForMilitaryTime(
|
||||||
timeSlot.startTime
|
timeSlotInfo.timeSlot.startTime
|
||||||
)}`;
|
)}`;
|
||||||
} else if (
|
} else if (
|
||||||
this.appointmentType === AppointmentTypeStrings.MOBILE &&
|
this.appointmentType === AppointmentTypeStrings.MOBILE &&
|
||||||
!timeSlot.isPremiumAppointment
|
!timeSlotInfo.isPremiumAppointment
|
||||||
) {
|
) {
|
||||||
funnelFooterButtonText += ` at ${this.getDisplayTextForMilitaryTime(
|
funnelFooterButtonText += ` at ${this.getDisplayTextForMilitaryTime(
|
||||||
timeSlot.startTime,
|
timeSlotInfo.timeSlot.startTime,
|
||||||
true
|
true
|
||||||
)} - ${this.getDisplayTextForMilitaryTime(timeSlot.endTime, true)}`;
|
)} - ${this.getDisplayTextForMilitaryTime(
|
||||||
|
timeSlotInfo.timeSlot.endTime,
|
||||||
|
true
|
||||||
|
)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$refs.funnelFooter.updateButtonText(funnelFooterButtonText);
|
this.$refs.funnelFooter.updateButtonText(funnelFooterButtonText);
|
||||||
|
|
@ -376,14 +385,16 @@ export default {
|
||||||
// Ex: April 25
|
// Ex: April 25
|
||||||
return dateObject.toLocaleDateString("en-us", { month: "short", day: "numeric" });
|
return dateObject.toLocaleDateString("en-us", { month: "short", day: "numeric" });
|
||||||
},
|
},
|
||||||
// Expected input: "HH:MM"
|
|
||||||
getDisplayTextForMilitaryTime(militaryTimeInput, shouldTrimMinutesIfEmpty = false) {
|
getDisplayTextForMilitaryTime(militaryTimeInput, shouldTrimMinutesIfEmpty = false) {
|
||||||
|
// Expected input: "HH:MM"
|
||||||
let hours = parseInt(militaryTimeInput.split(":")[0]);
|
let hours = parseInt(militaryTimeInput.split(":")[0]);
|
||||||
const minutes = militaryTimeInput.split(":")[1];
|
const minutes = militaryTimeInput.split(":")[1];
|
||||||
const meridianNotation = hours > 11 ? "PM" : "AM";
|
const meridianNotation = hours > 11 ? "PM" : "AM";
|
||||||
|
|
||||||
if (hours > 12) {
|
if (hours > 12) {
|
||||||
hours -= 12;
|
hours -= 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldTrimMinutesIfEmpty && minutes === "00") {
|
if (shouldTrimMinutesIfEmpty && minutes === "00") {
|
||||||
return `${hours} ${meridianNotation}`;
|
return `${hours} ${meridianNotation}`;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -395,7 +406,12 @@ export default {
|
||||||
},
|
},
|
||||||
forwardButtonAction() {
|
forwardButtonAction() {
|
||||||
this.updateSupportingItems();
|
this.updateSupportingItems();
|
||||||
this.dispatchStoreAction(this.storeActions.SAVE_SCHEDULE, this.selectedTimeSlot, false);
|
|
||||||
|
this.dispatchStoreAction(
|
||||||
|
this.storeActions.SAVE_SCHEDULE,
|
||||||
|
this.selectedTimeSlotInfo.timeSlot,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
},
|
},
|
||||||
|
|
@ -405,7 +421,7 @@ export default {
|
||||||
// if we have a premium fee(early bird), then save/update supporting items
|
// if we have a premium fee(early bird), then save/update supporting items
|
||||||
if (
|
if (
|
||||||
this.appointmentType === AppointmentTypeStrings.MOBILE &&
|
this.appointmentType === AppointmentTypeStrings.MOBILE &&
|
||||||
this.selectedTimeSlot?.isPremiumAppointment
|
this.selectedTimeSlotInfo?.isPremiumAppointment
|
||||||
) {
|
) {
|
||||||
const earlyBirdIndex = supportingItems.findIndex(
|
const earlyBirdIndex = supportingItems.findIndex(
|
||||||
(item) => item.partType == PREMIUM_FEE_PART_TYPE
|
(item) => item.partType == PREMIUM_FEE_PART_TYPE
|
||||||
|
|
@ -448,17 +464,20 @@ export default {
|
||||||
selectedDate(newValue, oldValue) {
|
selectedDate(newValue, oldValue) {
|
||||||
// Clear time slot selection if date selected changes
|
// Clear time slot selection if date selected changes
|
||||||
if (newValue !== oldValue) {
|
if (newValue !== oldValue) {
|
||||||
this.selectedTimeSlot = {
|
this.selectedTimeSlotInfo = {
|
||||||
date: null,
|
timeSlot: {
|
||||||
routeCode: null,
|
date: null,
|
||||||
startTime: null,
|
routeCode: null,
|
||||||
endTime: null,
|
startTime: null,
|
||||||
jobMaxMinutes: null,
|
endTime: null,
|
||||||
jobMinMinutes: null,
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedTimeSlot(newValue) {
|
selectedTimeSlotInfo(newValue) {
|
||||||
this.updateFooterButtonText(newValue);
|
this.updateFooterButtonText(newValue);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,76 @@ import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import timeSlotModalQuestion from "@/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue";
|
import timeSlotModalQuestion from "@/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
RouteCodeFlags,
|
RouteCodeFlags,
|
||||||
PREMIUM_TIME_SLOT_ID_FLAG,
|
PREMIUM_TIME_SLOT_ID_FLAG,
|
||||||
PREMIUM_FEE_PART_TYPE,
|
PREMIUM_FEE_PART_TYPE,
|
||||||
} from "@/constants/schedule-constants";
|
} from "@/constants/schedule-constants";
|
||||||
|
|
||||||
describe("time-slot-modal-list-button-question.vue", () => {
|
describe("time-slot-modal-question.vue", () => {
|
||||||
|
const timeSlotsForSelectedDate = {
|
||||||
|
date: "2023-09-02",
|
||||||
|
timeSlots: [
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*8 AM",
|
||||||
|
startTime: "08:00",
|
||||||
|
endTime: "09:00",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*830 AM",
|
||||||
|
startTime: "08:30",
|
||||||
|
endTime: "09:30",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*9 AM",
|
||||||
|
startTime: "09:00",
|
||||||
|
endTime: "10:00",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*930 AM",
|
||||||
|
startTime: "09:30",
|
||||||
|
endTime: "10:30",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*10 AM",
|
||||||
|
startTime: "10:00",
|
||||||
|
endTime: "11:00",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "03335-01820-S-B*20334*1030 AM",
|
||||||
|
startTime: "10:30",
|
||||||
|
endTime: "11:30",
|
||||||
|
offerPremium: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
test("When selected time slot is changed, a correctly formatted selectedTimeSlot should be emitted", async () => {
|
test("When selected time slot is changed, a correctly formatted selectedTimeSlot should be emitted", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const date = "2023-07-01";
|
const date = "2023-09-02";
|
||||||
const timeSlotId = "testRouteCodeId";
|
const routeCode = "03335-01820-S-B*20334*830 AM";
|
||||||
const startTime = "8:00 AM";
|
const startTime = "08:30";
|
||||||
const endTime = "8:30 AM";
|
const endTime = "09:30";
|
||||||
const jobMaxMinutes = 100;
|
const jobMaxMinutes = 100;
|
||||||
const jobMinMinutes = 50;
|
const jobMinMinutes = 50;
|
||||||
const expectedEmit = [
|
const expectedEmit = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
date: date,
|
timeSlot: {
|
||||||
routeCode: timeSlotId,
|
date: date,
|
||||||
startTime: startTime,
|
routeCode: routeCode,
|
||||||
endTime: endTime,
|
startTime: startTime,
|
||||||
jobMaxMinutes: jobMaxMinutes.toString(),
|
endTime: endTime,
|
||||||
jobMinMinutes: jobMinMinutes.toString(),
|
jobMaxMinutes: jobMaxMinutes.toString(),
|
||||||
|
jobMinMinutes: jobMinMinutes.toString(),
|
||||||
|
},
|
||||||
|
isPremiumAppointment: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
@ -35,22 +81,16 @@ describe("time-slot-modal-list-button-question.vue", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: timeSlotsForSelectedDate,
|
||||||
date: date,
|
|
||||||
timeSlots: [
|
|
||||||
{
|
|
||||||
id: timeSlotId,
|
|
||||||
startTime: startTime,
|
|
||||||
endTime: endTime,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper.vm.$refs.timeSlots.closeModal = jest.fn();
|
wrapper.vm.$refs.timeSlots.closeModal = jest.fn();
|
||||||
wrapper.vm.selectedTimeSlotId = timeSlotId;
|
|
||||||
|
await wrapper.setData({
|
||||||
|
selectedRouteCode: routeCode,
|
||||||
|
});
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
wrapper.vm.setSelectedTimeSlot();
|
wrapper.vm.setSelectedTimeSlot();
|
||||||
|
|
@ -59,7 +99,8 @@ describe("time-slot-modal-list-button-question.vue", () => {
|
||||||
expect(wrapper.emitted()["update:modelValue"]).toEqual(expectedEmit);
|
expect(wrapper.emitted()["update:modelValue"]).toEqual(expectedEmit);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("time-slot-modal-list-button-question.vue Supplemental information", () => {
|
|
||||||
|
describe("time-slot-modal-question.vue Supplemental information", () => {
|
||||||
test("The correct supplemental information should be obtained from CMS - Mobile - Not Premium ", async () => {
|
test("The correct supplemental information should be obtained from CMS - Mobile - Not Premium ", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const mobileCmsWidgetName = "MobileNotPremium";
|
const mobileCmsWidgetName = "MobileNotPremium";
|
||||||
|
|
@ -72,11 +113,13 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
||||||
mockCmsContent[mobileCmsWidgetName]["BodyText"]
|
mockCmsContent[mobileCmsWidgetName]["BodyText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("The correct supplemental information should be obtained from CMS - Mobile - Premium", async () => {
|
test("The correct supplemental information should be obtained from CMS - Mobile - Premium", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const mobileCmsWidgetName = "MobilePremium";
|
const mobileCmsWidgetName = "MobilePremium";
|
||||||
|
|
@ -89,11 +132,13 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
||||||
mockCmsContent[mobileCmsWidgetName]["BodyText"]
|
mockCmsContent[mobileCmsWidgetName]["BodyText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("No supplemental information should be obtained from CMS - Inshop", async () => {
|
test("No supplemental information should be obtained from CMS - Inshop", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const inshopWidgetName = "Inshop";
|
const inshopWidgetName = "Inshop";
|
||||||
|
|
@ -109,6 +154,7 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toBeNull();
|
expect(wrapper.vm.supplementalInformationBlock).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("No supplemental information should be obtained from CMS - Drop off, nothing selected", async () => {
|
test("No supplemental information should be obtained from CMS - Drop off, nothing selected", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const dropOffWidgetName = "Dropoff";
|
const dropOffWidgetName = "Dropoff";
|
||||||
|
|
@ -124,40 +170,69 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toBeNull();
|
expect(wrapper.vm.supplementalInformationBlock).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct supplemental information should be retrieved, Dropoff regular", async () => {
|
test("Correct supplemental information should be retrieved, Dropoff regular", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const dropOffWidgetName = "Dropoff";
|
const dropOffWidgetName = "Dropoff";
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test${RouteCodeFlags.ALL_DAY_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
dropoffCmsWidgetName: dropOffWidgetName,
|
dropoffCmsWidgetName: dropOffWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
||||||
mockCmsContent[dropOffWidgetName]["BodyText"]
|
mockCmsContent[dropOffWidgetName]["BodyText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct supplemental information should be retrieved, Dropoff Overnight", async () => {
|
test("Correct supplemental information should be retrieved, Dropoff Overnight", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const overnightDropOffCmsWidgetName = "Overnight";
|
const overnightDropOffCmsWidgetName = "Overnight";
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test${RouteCodeFlags.OVERNIGHT_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
expect(wrapper.vm.supplementalInformationBlock).toEqual(
|
||||||
mockCmsContent[overnightDropOffCmsWidgetName]["BodyText"]
|
mockCmsContent[overnightDropOffCmsWidgetName]["BodyText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct supplemental information should be retrieved, Dropoff Sameday", async () => {
|
test("Correct supplemental information should be retrieved, Dropoff Sameday", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const sameDayDropOffCmsWidgetName = "Sameday";
|
const sameDayDropOffCmsWidgetName = "Sameday";
|
||||||
|
|
@ -167,13 +242,24 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
const endTime = "8:30 AM";
|
const endTime = "8:30 AM";
|
||||||
const jobMaxMinutes = 100;
|
const jobMaxMinutes = 100;
|
||||||
const jobMinMinutes = 50;
|
const jobMinMinutes = 50;
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test${RouteCodeFlags.ALL_DAY_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -183,7 +269,7 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
|
|
@ -208,12 +294,24 @@ describe("time-slot-modal-list-button-question.vue Disclaimer", () => {
|
||||||
const jobMaxMinutes = 100;
|
const jobMaxMinutes = 100;
|
||||||
const jobMinMinutes = 50;
|
const jobMinMinutes = 50;
|
||||||
|
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `Test${RouteCodeFlags.ALL_DAY_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -223,7 +321,7 @@ describe("time-slot-modal-list-button-question.vue Disclaimer", () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
|
|
@ -235,47 +333,88 @@ describe("time-slot-modal-list-button-question.vue Disclaimer", () => {
|
||||||
mockCmsContent[sameDayDropOffCmsWidgetName]["FooterText"]
|
mockCmsContent[sameDayDropOffCmsWidgetName]["FooterText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct disclaimer information should be retrieved, Dropoff regular", async () => {
|
test("Correct disclaimer information should be retrieved, Dropoff regular", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const dropOffWidgetName = "Dropoff";
|
const dropOffWidgetName = "Dropoff";
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `Test${RouteCodeFlags.ALL_DAY_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
dropoffCmsWidgetName: dropOffWidgetName,
|
dropoffCmsWidgetName: dropOffWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.disclaimerTextBlockCopy).toEqual(
|
expect(wrapper.vm.disclaimerTextBlockCopy).toEqual(
|
||||||
mockCmsContent[dropOffWidgetName]["FooterText"]
|
mockCmsContent[dropOffWidgetName]["FooterText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct disclaimer information should be retrieved, Dropoff overnight", async () => {
|
test("Correct disclaimer information should be retrieved, Dropoff overnight", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const overnightDropOffCmsWidgetName = "Overnight";
|
const overnightDropOffCmsWidgetName = "Overnight";
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `Test${RouteCodeFlags.OVERNIGHT_DROP_OFF}`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.disclaimerTextBlockCopy).toEqual(
|
expect(wrapper.vm.disclaimerTextBlockCopy).toEqual(
|
||||||
mockCmsContent[overnightDropOffCmsWidgetName]["FooterText"]
|
mockCmsContent[overnightDropOffCmsWidgetName]["FooterText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("No disclaimer information should be retrieved, non-dropoff", async () => {
|
test("No disclaimer information should be retrieved, non-dropoff", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const inshopWidgetName = "Inshop";
|
const inshopWidgetName = "Inshop";
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "test" },
|
modelValue: modelValue,
|
||||||
appointmentType: "Inshop",
|
appointmentType: "Inshop",
|
||||||
cmsWidgetName: inshopWidgetName,
|
cmsWidgetName: inshopWidgetName,
|
||||||
},
|
},
|
||||||
|
|
@ -286,7 +425,7 @@ describe("time-slot-modal-list-button-question.vue Disclaimer", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("time-slot-modal-list-button-question.vue Duration", () => {
|
describe("time-slot-modal-question.vue Duration", () => {
|
||||||
test("The correct duration information should be displayed - Dropoff - Sameday ", async () => {
|
test("The correct duration information should be displayed - Dropoff - Sameday ", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const sameDayDropOffCmsWidgetName = "Sameday";
|
const sameDayDropOffCmsWidgetName = "Sameday";
|
||||||
|
|
@ -297,12 +436,24 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
const jobMaxMinutes = 100;
|
const jobMaxMinutes = 100;
|
||||||
const jobMinMinutes = 50;
|
const jobMinMinutes = 50;
|
||||||
|
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test` + RouteCodeFlags.ALL_DAY_DROP_OFF,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -312,7 +463,7 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
sameDayDropOffCmsWidgetName: sameDayDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
|
|
@ -324,30 +475,59 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
mockCmsContent[sameDayDropOffCmsWidgetName]["SubheaderText"]
|
mockCmsContent[sameDayDropOffCmsWidgetName]["SubheaderText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct duration information should be retrieved, Dropoff overnight", async () => {
|
test("Correct duration information should be retrieved, Dropoff overnight", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const overnightDropOffCmsWidgetName = "Overnight";
|
const overnightDropOffCmsWidgetName = "Overnight";
|
||||||
|
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test` + RouteCodeFlags.OVERNIGHT_DROP_OFF,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.OVERNIGHT_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
overnightDropOffCmsWidgetName: overnightDropOffCmsWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.durationTextBlockCopy).toEqual(
|
expect(wrapper.vm.durationTextBlockCopy).toEqual(
|
||||||
mockCmsContent[overnightDropOffCmsWidgetName]["SubheaderText"]
|
mockCmsContent[overnightDropOffCmsWidgetName]["SubheaderText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct duration information should be retrieved, Dropoff", async () => {
|
test("Correct duration information should be retrieved, Dropoff", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const dropoffCmsWidgetName = "Dropoff";
|
const dropoffCmsWidgetName = "Dropoff";
|
||||||
|
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test` + RouteCodeFlags.ALL_DAY_DROP_OFF,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
modelValue: { routeCode: "Test" + RouteCodeFlags.ALL_DAY_DROP_OFF },
|
modelValue: modelValue,
|
||||||
appointmentType: "Dropoff",
|
appointmentType: "Dropoff",
|
||||||
dropoffCmsWidgetName: dropoffCmsWidgetName,
|
dropoffCmsWidgetName: dropoffCmsWidgetName,
|
||||||
},
|
},
|
||||||
|
|
@ -358,25 +538,39 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
mockCmsContent[dropoffCmsWidgetName]["SubheaderText"]
|
mockCmsContent[dropoffCmsWidgetName]["SubheaderText"]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct duration information should be retrieved, Inshop - convert to hours", async () => {
|
test("Correct duration information should be retrieved, Inshop - convert to hours", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const cmsWidgetName = "Inshop";
|
const cmsWidgetName = "Inshop";
|
||||||
|
|
||||||
|
const modelValue = {
|
||||||
|
timeSlot: {
|
||||||
|
routeCode: `test`,
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: 180,
|
estimatedServiceMinutesMaximum: 180,
|
||||||
estimatedServiceMinutesMinimum: 120,
|
estimatedServiceMinutesMinimum: 120,
|
||||||
modelValue: { routeCode: "Test" },
|
modelValue: modelValue,
|
||||||
appointmentType: "Inshop",
|
appointmentType: "Inshop",
|
||||||
cmsWidgetName: cmsWidgetName,
|
cmsWidgetName: cmsWidgetName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.durationTextBlockCopy).toEqual(
|
expect(wrapper.vm.durationTextBlockCopy).toEqual(
|
||||||
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 2 - 3 hours"
|
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 2 - 3 hours"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct duration information should be retrieved, Inshop - convert to minutes", async () => {
|
test("Correct duration information should be retrieved, Inshop - convert to minutes", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const cmsWidgetName = "Inshop";
|
const cmsWidgetName = "Inshop";
|
||||||
|
|
@ -396,6 +590,7 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 60 - 90 minutes"
|
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 60 - 90 minutes"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Correct duration information should be retrieved, Inshop - min = maximum time", async () => {
|
test("Correct duration information should be retrieved, Inshop - min = maximum time", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const cmsWidgetName = "Inshop";
|
const cmsWidgetName = "Inshop";
|
||||||
|
|
@ -415,6 +610,7 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
|
||||||
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 4 hours"
|
mockCmsContent[cmsWidgetName]["SubheaderText"] + " 4 hours"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("No duration information should be displayed, Mobile", async () => {
|
test("No duration information should be displayed, Mobile", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const mobileCmsWidgetName = "Mobile";
|
const mobileCmsWidgetName = "Mobile";
|
||||||
|
|
@ -450,7 +646,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -473,6 +669,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
};
|
};
|
||||||
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Available Timeslots should be formatted correctly - Dropoff - Overnight ", async () => {
|
test("Available Timeslots should be formatted correctly - Dropoff - Overnight ", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const overnightDropOffCmsWidgetName = "Overnight";
|
const overnightDropOffCmsWidgetName = "Overnight";
|
||||||
|
|
@ -488,7 +685,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -511,6 +708,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
};
|
};
|
||||||
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Available Timeslots should be formatted correctly - Dropoff", async () => {
|
test("Available Timeslots should be formatted correctly - Dropoff", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const dropoffCmsWidgetName = "Dropoff";
|
const dropoffCmsWidgetName = "Dropoff";
|
||||||
|
|
@ -526,7 +724,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -549,6 +747,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
};
|
};
|
||||||
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Available Timeslots should be formatted correctly - Mobile not premium", async () => {
|
test("Available Timeslots should be formatted correctly - Mobile not premium", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const mobileCmsWidgetName = "MobileNotPremium";
|
const mobileCmsWidgetName = "MobileNotPremium";
|
||||||
|
|
@ -564,7 +763,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -587,6 +786,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
};
|
};
|
||||||
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Available Timeslots should be formatted correctly - Mobile with premium", async () => {
|
test("Available Timeslots should be formatted correctly - Mobile with premium", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const mobilePremiumCmsWidgetName = "MobilePremium";
|
const mobilePremiumCmsWidgetName = "MobilePremium";
|
||||||
|
|
@ -605,7 +805,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
premiumAppointmentFee: {
|
premiumAppointmentFee: {
|
||||||
partType: PREMIUM_FEE_PART_TYPE,
|
partType: PREMIUM_FEE_PART_TYPE,
|
||||||
},
|
},
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -631,8 +831,10 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
buttonLabelSubCopy: "+$15.99",
|
buttonLabelSubCopy: "+$15.99",
|
||||||
value: timeSlotId + PREMIUM_TIME_SLOT_ID_FLAG,
|
value: timeSlotId + PREMIUM_TIME_SLOT_ID_FLAG,
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
expect(wrapper.vm.availableTimeSlots[0]).toEqual(expectedTimeSlotObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Available Timeslots should be formatted correctly - Inshop", async () => {
|
test("Available Timeslots should be formatted correctly - Inshop", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const cmsWidgetName = "Inshop";
|
const cmsWidgetName = "Inshop";
|
||||||
|
|
@ -648,7 +850,7 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
|
||||||
propsData: {
|
propsData: {
|
||||||
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
estimatedServiceMinutesMaximum: jobMaxMinutes,
|
||||||
estimatedServiceMinutesMinimum: jobMinMinutes,
|
estimatedServiceMinutesMinimum: jobMinMinutes,
|
||||||
dateAndTimeSlotData: {
|
timeSlotsForSelectedDate: {
|
||||||
date: date,
|
date: date,
|
||||||
timeSlots: [
|
timeSlots: [
|
||||||
{
|
{
|
||||||
|
|
@ -678,7 +880,7 @@ const mockCmsContent = {
|
||||||
HeaderText: "Mobile, not premium HeaderText",
|
HeaderText: "Mobile, not premium HeaderText",
|
||||||
},
|
},
|
||||||
MobilePremium: {
|
MobilePremium: {
|
||||||
"BodyText:": "Mobile, with premium BodyText",
|
BodyText: "Mobile, with premium BodyText",
|
||||||
FooterText: "Mobile, with premium FooterText",
|
FooterText: "Mobile, with premium FooterText",
|
||||||
SubheaderText: "Mobile, with premium SubheaderText",
|
SubheaderText: "Mobile, with premium SubheaderText",
|
||||||
HeaderText: "Mobile, with premium HeaderText",
|
HeaderText: "Mobile, with premium HeaderText",
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
:answers="availableTimeSlots"
|
:answers="availableTimeSlots"
|
||||||
groupName="chooseTimeSlot"
|
groupName="chooseTimeSlot"
|
||||||
textPosition="text-center"
|
textPosition="text-center"
|
||||||
v-model="selectedTimeSlotId"
|
v-model="selectedRouteCode"
|
||||||
isRequired
|
isRequired
|
||||||
validationRules="time-slot-required" />
|
validationRules="time-slot-required" />
|
||||||
<div
|
<div
|
||||||
|
|
@ -47,12 +47,12 @@ import buttonQuestion from "@/digital-components/button-question/button-question
|
||||||
import timeSlotModalListButton from "./time-slot-modal-list-button/time-slot-modal-list-button";
|
import timeSlotModalListButton from "./time-slot-modal-list-button/time-slot-modal-list-button";
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
import { deepClone } from "@/helpers/object-helper";
|
||||||
import {
|
import {
|
||||||
convertDateStringToDate,
|
convertDateStringToDate,
|
||||||
militaryToTwelveHourTime,
|
militaryToTwelveHourTime,
|
||||||
getDisplayTextForDurationLength,
|
getDisplayTextForDurationLength,
|
||||||
} from "@/layouts/schedule/helpers/schedule-helper";
|
} from "@/layouts/schedule/helpers/schedule-helper";
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
|
||||||
|
|
||||||
// Validation - TODO: Move this somewhere more global?
|
// Validation - TODO: Move this somewhere more global?
|
||||||
import { defineRule, useField } from "vee-validate";
|
import { defineRule, useField } from "vee-validate";
|
||||||
|
|
@ -87,12 +87,15 @@ export default {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
routeCode: null,
|
timeSlot: {
|
||||||
date: null,
|
routeCode: null,
|
||||||
startTime: null,
|
date: null,
|
||||||
endTime: null,
|
startTime: null,
|
||||||
jobMaxMinutes: null,
|
endTime: null,
|
||||||
jobMinMinutes: null,
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
|
|
@ -102,7 +105,7 @@ export default {
|
||||||
sameDayDropOffCmsWidgetName: String,
|
sameDayDropOffCmsWidgetName: String,
|
||||||
overnightDropOffCmsWidgetName: String,
|
overnightDropOffCmsWidgetName: String,
|
||||||
appointmentType: String,
|
appointmentType: String,
|
||||||
dateAndTimeSlotData: Object,
|
timeSlotsForSelectedDate: Object,
|
||||||
premiumAppointmentFee: Object,
|
premiumAppointmentFee: Object,
|
||||||
estimatedServiceMinutesMinimum: Number,
|
estimatedServiceMinutesMinimum: Number,
|
||||||
estimatedServiceMinutesMaximum: Number,
|
estimatedServiceMinutesMaximum: Number,
|
||||||
|
|
@ -113,7 +116,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isModalOpened: false,
|
isModalOpened: false,
|
||||||
selectedValue: null,
|
selectedRouteCode: this.getSelectedRouteCode(),
|
||||||
timeSlotModalListButton: timeSlotModalListButton,
|
timeSlotModalListButton: timeSlotModalListButton,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -150,36 +153,31 @@ export default {
|
||||||
modalName() {
|
modalName() {
|
||||||
return "timeSlots";
|
return "timeSlots";
|
||||||
},
|
},
|
||||||
selectedTimeSlotId: {
|
modal() {
|
||||||
get: function () {
|
return this.$refs[this.modalName];
|
||||||
return this.modelValue?.routeCode;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
// Button Question only supports Number, or String data types so we must convert to the full object before emitting
|
|
||||||
this.selectedValue = this.getSelectedTimeSlotObject(newValue);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
supplementalInformationBlock() {
|
supplementalInformationBlock() {
|
||||||
let appointmentTypeCmsWidgetName;
|
let appointmentTypeCmsWidgetName;
|
||||||
if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
||||||
return null;
|
return null;
|
||||||
} else if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
|
} else if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
|
||||||
appointmentTypeCmsWidgetName = this.selectedTimeSlotId?.includes(
|
appointmentTypeCmsWidgetName = this.selectedRouteCode?.includes(
|
||||||
PREMIUM_TIME_SLOT_ID_FLAG
|
PREMIUM_TIME_SLOT_ID_FLAG
|
||||||
)
|
)
|
||||||
? this.mobilePremiumCmsWidgetName
|
? this.mobilePremiumCmsWidgetName
|
||||||
: this.mobileCmsWidgetName;
|
: this.mobileCmsWidgetName;
|
||||||
} else {
|
} else {
|
||||||
if (!this.selectedTimeSlotId) {
|
if (!this.selectedRouteCode) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
appointmentTypeCmsWidgetName =
|
appointmentTypeCmsWidgetName =
|
||||||
this.getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
|
this.getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
|
||||||
this.selectedTimeSlotId,
|
this.selectedRouteCode,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getCmsContent(
|
return this.getCmsContent(
|
||||||
appointmentTypeCmsWidgetName,
|
appointmentTypeCmsWidgetName,
|
||||||
cmsWidgetFieldMappings.SUPPLEMENTAL_INFORMATION
|
cmsWidgetFieldMappings.SUPPLEMENTAL_INFORMATION
|
||||||
|
|
@ -232,13 +230,13 @@ export default {
|
||||||
},
|
},
|
||||||
disclaimerTextBlockCopy() {
|
disclaimerTextBlockCopy() {
|
||||||
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
|
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
|
||||||
if (this.selectedTimeSlotId?.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
if (this.selectedRouteCode?.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
||||||
if (this.isSameDay) {
|
if (this.isSameDay) {
|
||||||
return this.sameDayDropOffDisclaimerText;
|
return this.sameDayDropOffDisclaimerText;
|
||||||
} else {
|
} else {
|
||||||
return this.dropoffDisclaimerText;
|
return this.dropoffDisclaimerText;
|
||||||
}
|
}
|
||||||
} else if (this.selectedTimeSlotId?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
} else if (this.selectedRouteCode?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
||||||
return this.overnightDropOffDisclaimerText;
|
return this.overnightDropOffDisclaimerText;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -281,9 +279,9 @@ export default {
|
||||||
} else if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
} else if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
|
||||||
return this.inshopDurationText;
|
return this.inshopDurationText;
|
||||||
} else {
|
} else {
|
||||||
if (this.selectedTimeSlotId?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
if (this.selectedRouteCode?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
||||||
return this.overnightDropoffDurationText;
|
return this.overnightDropoffDurationText;
|
||||||
} else if (this.selectedTimeSlotId?.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
} else if (this.selectedRouteCode?.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
||||||
if (this.isSameDay) {
|
if (this.isSameDay) {
|
||||||
return this.sameDayDropoffDurationText;
|
return this.sameDayDropoffDurationText;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -295,21 +293,21 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isSameDay() {
|
isSameDay() {
|
||||||
if (!this.dateAndTimeSlotData) {
|
if (!this.timeSlotsForSelectedDate) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedDate = this.dateAndTimeSlotData.date;
|
const selectedDate = this.timeSlotsForSelectedDate.date;
|
||||||
const todaysDate = new Date().toISOString().split("T")[0];
|
const todaysDate = new Date().toISOString().split("T")[0];
|
||||||
return selectedDate === todaysDate;
|
return selectedDate === todaysDate;
|
||||||
},
|
},
|
||||||
dateSelectedReadableDate() {
|
dateSelectedReadableDate() {
|
||||||
if (!this.dateAndTimeSlotData) {
|
if (!this.timeSlotsForSelectedDate) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This conversion ensures we don't get get GMT induced date changes
|
// This conversion ensures we don't get get GMT induced date changes
|
||||||
const dateObject = convertDateStringToDate(this.dateAndTimeSlotData.date);
|
const dateObject = convertDateStringToDate(this.timeSlotsForSelectedDate.date);
|
||||||
// Ex: Tuesday, April 22
|
// Ex: Tuesday, April 22
|
||||||
return dateObject.toLocaleDateString("en-us", {
|
return dateObject.toLocaleDateString("en-us", {
|
||||||
weekday: "long",
|
weekday: "long",
|
||||||
|
|
@ -318,21 +316,20 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
availableTimeSlots() {
|
availableTimeSlots() {
|
||||||
if (!this.dateAndTimeSlotData) {
|
if (!this.timeSlotsForSelectedDate) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
|
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
|
||||||
return this.getAvailableTimeSlotsForDropOff(this.dateAndTimeSlotData.timeSlots);
|
return this.getAvailableTimeSlotsForDropOff(
|
||||||
|
this.timeSlotsForSelectedDate.timeSlots
|
||||||
|
);
|
||||||
} else if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
|
} else if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
|
||||||
return this.getAvailableTimeSlotsForMobile(this.dateAndTimeSlotData.timeSlots);
|
return this.getAvailableTimeSlotsForMobile(this.timeSlotsForSelectedDate.timeSlots);
|
||||||
} else {
|
} else {
|
||||||
return this.getAvailableTimeSlotsForInshop(this.dateAndTimeSlotData.timeSlots);
|
return this.getAvailableTimeSlotsForInshop(this.timeSlotsForSelectedDate.timeSlots);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modal() {
|
|
||||||
return this.$refs[this.modalName];
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModal() {
|
openModal() {
|
||||||
|
|
@ -348,16 +345,19 @@ export default {
|
||||||
this.$emit("time-slot-modal-closed");
|
this.$emit("time-slot-modal-closed");
|
||||||
},
|
},
|
||||||
async setSelectedTimeSlot() {
|
async setSelectedTimeSlot() {
|
||||||
this.$emit("update:modelValue", this.selectedValue);
|
this.$emit(
|
||||||
|
"update:modelValue",
|
||||||
|
this.getSelectedTimeSlotInfoObject(this.selectedRouteCode)
|
||||||
|
);
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
},
|
},
|
||||||
getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
|
getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
|
||||||
selectedTimeSlotId,
|
selectedRouteCode,
|
||||||
isSameDayRelevant = false
|
isSameDayRelevant = false
|
||||||
) {
|
) {
|
||||||
if (selectedTimeSlotId.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
if (selectedRouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
|
||||||
return this.overnightDropOffCmsWidgetName;
|
return this.overnightDropOffCmsWidgetName;
|
||||||
} else if (selectedTimeSlotId.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
} else if (selectedRouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
|
||||||
return this.isSameDay && isSameDayRelevant
|
return this.isSameDay && isSameDayRelevant
|
||||||
? this.sameDayDropOffCmsWidgetName
|
? this.sameDayDropOffCmsWidgetName
|
||||||
: this.dropoffCmsWidgetName;
|
: this.dropoffCmsWidgetName;
|
||||||
|
|
@ -416,8 +416,9 @@ export default {
|
||||||
getPremiumAppointmentTimeSlot(timeSlotData) {
|
getPremiumAppointmentTimeSlot(timeSlotData) {
|
||||||
const formattedPrice =
|
const formattedPrice =
|
||||||
"+$" + this.getTotalLineItemPrice(this.premiumAppointmentFee).toFixed(2);
|
"+$" + this.getTotalLineItemPrice(this.premiumAppointmentFee).toFixed(2);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Unique value is required for each <input> and the premium appoinment shares a timeSlot ID
|
// Unique value is required for each <input> and the premium appoinment shares an id
|
||||||
value: this.addPremiumFlagToInput(timeSlotData.id),
|
value: this.addPremiumFlagToInput(timeSlotData.id),
|
||||||
buttonLabel: this.premiumAppointmentButtonText,
|
buttonLabel: this.premiumAppointmentButtonText,
|
||||||
buttonLabelSubCopy: formattedPrice,
|
buttonLabelSubCopy: formattedPrice,
|
||||||
|
|
@ -426,41 +427,68 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
autoSelectTimeSlotIfOnlyOneIsAvailable(newAvailableTimeSlotsValue) {
|
getSelectedRouteCode() {
|
||||||
const numberOfOptions = newAvailableTimeSlotsValue?.length;
|
let selectedRouteCode;
|
||||||
|
if (!this.modelValue?.timeSlot) {
|
||||||
|
selectedRouteCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.modelValue?.isPremiumAppointment) {
|
||||||
|
selectedRouteCode = this.addPremiumFlagToInput(
|
||||||
|
this.modelValue?.timeSlot?.routeCode
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
selectedRouteCode = this.modelValue?.timeSlot?.routeCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedRouteCode;
|
||||||
|
},
|
||||||
|
autoSelectTimeSlotIfOnlyOneIsAvailable() {
|
||||||
|
const numberOfOptions = this.availableTimeSlots?.length;
|
||||||
if (numberOfOptions === 1) {
|
if (numberOfOptions === 1) {
|
||||||
this.selectedTimeSlotId = newAvailableTimeSlotsValue[0].value;
|
this.selectedRouteCode = this.availableTimeSlots[0].value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addPremiumFlagToInput(timeSlotId) {
|
addPremiumFlagToInput(routeCode) {
|
||||||
return (timeSlotId += PREMIUM_TIME_SLOT_ID_FLAG);
|
return (routeCode += PREMIUM_TIME_SLOT_ID_FLAG);
|
||||||
},
|
},
|
||||||
removePremiumFlagFromInput(timeSlotId) {
|
removePremiumFlagFromInput(routeCode) {
|
||||||
return timeSlotId.substring(0, timeSlotId.length - PREMIUM_TIME_SLOT_ID_FLAG.length);
|
return routeCode.replace(PREMIUM_TIME_SLOT_ID_FLAG, "");
|
||||||
},
|
},
|
||||||
getSelectedTimeSlotObject(timeSlotId) {
|
getSelectedTimeSlotInfoObject(routeCode) {
|
||||||
const timeSlot = this.dateAndTimeSlotData?.timeSlots?.find(
|
const routeCodeIncludesPremium = routeCode?.includes(PREMIUM_TIME_SLOT_ID_FLAG);
|
||||||
(timeSlot) => timeSlot.id == timeSlotId
|
if (routeCodeIncludesPremium) {
|
||||||
|
routeCode = this.removePremiumFlagFromInput(routeCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeSlot = this.timeSlotsForSelectedDate?.timeSlots?.find(
|
||||||
|
(timeSlot) => timeSlot.id == routeCode
|
||||||
);
|
);
|
||||||
|
|
||||||
if (timeSlot) {
|
if (timeSlot) {
|
||||||
return {
|
return {
|
||||||
date: this.dateAndTimeSlotData.date,
|
timeSlot: {
|
||||||
routeCode: timeSlot.id,
|
date: this.timeSlotsForSelectedDate.date,
|
||||||
startTime: timeSlot.startTime,
|
routeCode: timeSlot.id,
|
||||||
endTime: timeSlot.endTime,
|
startTime: timeSlot.startTime,
|
||||||
jobMaxMinutes: this.estimatedServiceMinutesMaximum.toString(),
|
endTime: timeSlot.endTime,
|
||||||
jobMinMinutes: this.estimatedServiceMinutesMinimum.toString(),
|
jobMaxMinutes: this.estimatedServiceMinutesMaximum.toString(),
|
||||||
|
jobMinMinutes: this.estimatedServiceMinutesMinimum.toString(),
|
||||||
|
},
|
||||||
|
isPremiumAppointment: routeCodeIncludesPremium ? true : false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
date: null,
|
timeSlot: {
|
||||||
startTime: null,
|
date: null,
|
||||||
endTime: null,
|
startTime: null,
|
||||||
routeCode: null,
|
endTime: null,
|
||||||
jobMaxMinutes: null,
|
routeCode: null,
|
||||||
jobMinMinutes: null,
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
isPremiumAppointment: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -473,12 +501,10 @@ export default {
|
||||||
},
|
},
|
||||||
selectedDate: {
|
selectedDate: {
|
||||||
handler() {
|
handler() {
|
||||||
this.selectedTimeSlotId = null;
|
this.selectedRouteCode = null;
|
||||||
|
this.autoSelectTimeSlotIfOnlyOneIsAvailable();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
availableTimeSlots(newValue) {
|
|
||||||
this.autoSelectTimeSlotIfOnlyOneIsAvailable(newValue);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
modal,
|
modal,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue