diff --git a/jest.config.js b/jest.config.js
index 0a6fbc048..633a99e67 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -15,10 +15,8 @@ module.exports = {
"!src/layouts/vehicle-damage/windshield-options/windshield-options.vue",
"!src/layouts/reveal/**/*.vue",
"!src/ux-components/text-link/**/*.vue",
- "!src/digital-components/date-picker/**/*.vue", // Temp until unit tests completed
"!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing
"!src/common-components/funnel-header/menu-modal/**/*.vue",
- "!src/layouts/schedule/*.vue", // Temp test exclusion while in development
"!src/layouts/schedule/helpers/schedule-helper.js", // Temp test exclusion while in development
"!src/layouts/review/*.vue", // Temp test exclusion while in development
// END
diff --git a/src/constants/analytics.js b/src/constants/analytics.js
index 2b0fc1a8f..b5b24660d 100644
--- a/src/constants/analytics.js
+++ b/src/constants/analytics.js
@@ -12,7 +12,6 @@ const GaEvents = {
const GaCategories = {
API_RESPONSE: "Api_Response",
EVOX: "Evox",
- FUNNEL_ENTRY: "funnel_entry",
};
const GaActions = {
@@ -21,7 +20,6 @@ const GaActions = {
VIF: "vif",
SUBMITTED: "Submitted",
DISPLAYED: "Displayed",
- ZIP_CODE_PROVIDED: "zip_code_provided",
};
const GaLabels = {
diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js
index 05a55cc5c..373779380 100644
--- a/src/constants/endpoints.js
+++ b/src/constants/endpoints.js
@@ -119,7 +119,7 @@ const endpoints = {
method: "GET",
},
SaveSession: {
- url: "/order/api/v1/order/save-session",
+ url: "/order/api/v1/order/save-session/fmg",
method: "POST",
},
LoadSession: {
diff --git a/src/constants/pay-with-insurance-states.js b/src/constants/pay-with-insurance-states.js
new file mode 100644
index 000000000..e65589557
--- /dev/null
+++ b/src/constants/pay-with-insurance-states.js
@@ -0,0 +1 @@
+export const payWithInsuranceStates = ["AZ", "CT", "FL", "KY", "MA", "MN", "NY", "SC"];
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index fc0daf323..f23a167e1 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -9,7 +9,7 @@ const storeActions = {
GET_VEHICLE_MAKES: "getVehicleMakes",
GET_VEHICLE_MODELS: "getVehicleModels",
GET_VEHICLE_STYLES: "getVehicleStyles",
- SET_VEHICLE: "setVehicle",
+ GET_VEHICLE: "getVehicle",
GET_DAMAGE_OPTIONS: "getDamageOptions",
GET_EVOX_IMAGE: "getEvoxImage",
IS_VIN_OPTIONAL_VEHICLE: "isVinOptionalVehicle",
@@ -58,10 +58,6 @@ const storeActions = {
RESET_STATE: "resetState",
// SAVE COMPONENT STATE
- SAVE_VEHICLE_YEAR: "saveVehicleYear",
- SAVE_VEHICLE_MAKE: "saveVehicleMake",
- SAVE_VEHICLE_MODEL: "saveVehicleModel",
- SAVE_VEHICLE_STYLE: "saveVehicleStyle",
SAVE_VEHICLE: "saveVehicle",
SAVE_VEHICLE_DAMAGE: "saveVehicleDamage",
SAVE_VIN_LOOKUP: "saveVinLookup",
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
index 7b57187c2..fd568ead7 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -23,28 +23,20 @@ const storeMutations = {
UPDATE_SUPPORTING_ITEMS: "updateSupportingItems",
UPDATE_LINE_ITEMS_SERVER_DATA: "updateLineItemsServerData",
- UPDATE_REGISTRATION_LICENSE_PLATE: "updateRegistrationLicensePlate",
- UPDATE_REGISTRATION_ADDRESS: "updateRegistrationAddress",
- UPDATE_REGISTRATION_CITY: "updateRegistrationCity",
- UPDATE_REGISTRATION_STATE: "updateRegistrationState",
- UPDATE_REGISTRATION_ZIP_CODE: "updateRegistrationZipCode",
- UPDATE_REGISTRATION_FIRST_NAME: "updateRegistrationFirstName",
- UPDATE_REGISTRATION_LAST_NAME: "updateRegistrationLastName",
UPDATE_REGISTRATION: "updateRegistration",
UPDATE_SERVICE_ZIP: "updateServiceZip",
UPDATE_SERVICE_LOCATION: "updateServiceLocation",
UPDATE_SERVICE_LOCATION_TECH_NOTES: "updateServiceLocationTechNotes",
- UPDATE_TECH_NOTES: "updateTechNotes",
UPDATE_SCHEDULE: "updateSchedule",
- UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress",
-
// CUSTOMER MUTATIONS
+ UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress",
UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails",
// ORDER MUTATIONS
UPDATE_REFERRAL_NUMBER: "updateReferralNumber",
+ UPDATE_REFERRAL_SEQUENCE_NUMBER: "updateReferralSequenceNumber",
UPDATE_REFERRAL_DATE: "updateReferralDate",
UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId",
UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber",
diff --git a/src/digital-components/date-picker/date-picker.spec.js b/src/digital-components/date-picker/date-picker.spec.js
new file mode 100644
index 000000000..e4416d37a
--- /dev/null
+++ b/src/digital-components/date-picker/date-picker.spec.js
@@ -0,0 +1,1348 @@
+import datePicker from "./date-picker";
+
+// Supporting Files
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import store from "@/store";
+
+// Constants
+const mockValuesForSetDate01 = {
+ overrideDate: "2023-12-01",
+ monthEnd: "2023-12-31",
+ initialViewWeeks: [
+ {
+ weekNum: 1,
+ weekStartDate: "2023-12-01",
+ weekEndDate: "2023-12-02",
+ },
+ {
+ weekNum: 2,
+ weekStartDate: "2023-12-03",
+ weekEndDate: "2023-12-09",
+ },
+ {
+ weekNum: 3,
+ weekStartDate: "2023-12-10",
+ weekEndDate: "2023-12-16",
+ },
+ {
+ weekNum: 4,
+ weekStartDate: "2023-12-17",
+ weekEndDate: "2023-12-23",
+ },
+ {
+ weekNum: 5,
+ weekStartDate: "2023-12-24",
+ weekEndDate: "2023-12-30",
+ },
+ ],
+ config: {
+ todayDate: "2023-12-01",
+ initialViewStartDate: "2023-12-01",
+ initialViewEndDate: "2023-12-30",
+ calendarViewDirection: "future",
+ initialShopTimeSlotsResponse: {
+ days: [
+ {
+ date: "2023-12-30",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20453*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ],
+ estimatedServiceMinutesMinimum: 90,
+ estimatedServiceMinutesMaximum: 120,
+ },
+ hideSomeDaysForInitialView: true,
+ hideSecondMonth: true,
+ preSelectedDate: null,
+ },
+ monthsData: [
+ {
+ monthLabel: "December",
+ monthIndex: 12,
+ monthString: "December-2023",
+ yearNum: 2023,
+ dates: [
+ {
+ dateNum: 1,
+ dayClasses: " current-day",
+ inputValue: "2023-12-01",
+ isSelectable: false,
+ },
+ {
+ dateNum: 2,
+ dayClasses: "",
+ inputValue: "2023-12-02",
+ isSelectable: false,
+ },
+ {
+ dateNum: 3,
+ dayClasses: " sunday",
+ inputValue: "2023-12-03",
+ isSelectable: false,
+ },
+ {
+ dateNum: 4,
+ dayClasses: "",
+ inputValue: "2023-12-04",
+ isSelectable: false,
+ },
+ {
+ dateNum: 5,
+ dayClasses: "",
+ inputValue: "2023-12-05",
+ isSelectable: false,
+ },
+ {
+ dateNum: 6,
+ dayClasses: "",
+ inputValue: "2023-12-06",
+ isSelectable: false,
+ },
+ {
+ dateNum: 7,
+ dayClasses: "",
+ inputValue: "2023-12-07",
+ isSelectable: false,
+ },
+ {
+ dateNum: 8,
+ dayClasses: "",
+ inputValue: "2023-12-08",
+ isSelectable: false,
+ },
+ {
+ dateNum: 9,
+ dayClasses: "",
+ inputValue: "2023-12-09",
+ isSelectable: false,
+ },
+ {
+ dateNum: 10,
+ dayClasses: " sunday",
+ inputValue: "2023-12-10",
+ isSelectable: false,
+ },
+ {
+ dateNum: 11,
+ dayClasses: "",
+ inputValue: "2023-12-11",
+ isSelectable: false,
+ },
+ {
+ dateNum: 12,
+ dayClasses: "",
+ inputValue: "2023-12-12",
+ isSelectable: false,
+ },
+ {
+ dateNum: 13,
+ dayClasses: "",
+ inputValue: "2023-12-13",
+ isSelectable: false,
+ },
+ {
+ dateNum: 14,
+ dayClasses: "",
+ inputValue: "2023-12-14",
+ isSelectable: false,
+ },
+ {
+ dateNum: 15,
+ dayClasses: "",
+ inputValue: "2023-12-15",
+ isSelectable: false,
+ },
+ {
+ dateNum: 16,
+ dayClasses: "",
+ inputValue: "2023-12-16",
+ isSelectable: false,
+ },
+ {
+ dateNum: 17,
+ dayClasses: " sunday",
+ inputValue: "2023-12-17",
+ isSelectable: false,
+ },
+ {
+ dateNum: 18,
+ dayClasses: "",
+ inputValue: "2023-12-18",
+ isSelectable: false,
+ },
+ {
+ dateNum: 19,
+ dayClasses: "",
+ inputValue: "2023-12-19",
+ isSelectable: false,
+ },
+ {
+ dateNum: 20,
+ dayClasses: "",
+ inputValue: "2023-12-20",
+ isSelectable: false,
+ },
+ {
+ dateNum: 21,
+ dayClasses: "",
+ inputValue: "2023-12-21",
+ isSelectable: false,
+ },
+ {
+ dateNum: 22,
+ dayClasses: "",
+ inputValue: "2023-12-22",
+ isSelectable: false,
+ },
+ {
+ dateNum: 23,
+ dayClasses: "",
+ inputValue: "2023-12-23",
+ isSelectable: false,
+ },
+ {
+ dateNum: 24,
+ dayClasses: " sunday",
+ inputValue: "2023-12-24",
+ isSelectable: false,
+ },
+ {
+ dateNum: 25,
+ dayClasses: "",
+ inputValue: "2023-12-25",
+ isSelectable: false,
+ },
+ {
+ dateNum: 26,
+ dayClasses: "",
+ inputValue: "2023-12-26",
+ isSelectable: false,
+ },
+ {
+ dateNum: 27,
+ dayClasses: "",
+ inputValue: "2023-12-27",
+ isSelectable: false,
+ },
+ {
+ dateNum: 28,
+ dayClasses: "",
+ inputValue: "2023-12-28",
+ isSelectable: false,
+ },
+ {
+ dateNum: 29,
+ dayClasses: "",
+ inputValue: "2023-12-29",
+ isSelectable: false,
+ },
+ {
+ dateNum: 30,
+ dayClasses: "",
+ inputValue: "2023-12-30",
+ isSelectable: true,
+ },
+ {
+ dateNum: 31,
+ dayClasses: " sunday day-hidden",
+ inputValue: "2023-12-31",
+ isSelectable: false,
+ },
+ ],
+ startDateDayIndex: 5,
+ monthClass: "",
+ isMonthThatHidesSomeDaysForInitialView: true,
+ },
+ {
+ monthLabel: "January",
+ monthIndex: 1,
+ monthString: "January-2024",
+ yearNum: 2024,
+ dates: [
+ {
+ dateNum: 1,
+ dayClasses: "",
+ inputValue: "2024-01-01",
+ isSelectable: false,
+ },
+ {
+ dateNum: 2,
+ dayClasses: "",
+ inputValue: "2024-01-02",
+ isSelectable: false,
+ },
+ {
+ dateNum: 30,
+ dayClasses: "",
+ inputValue: "2024-01-30",
+ isSelectable: false,
+ },
+ {
+ dateNum: 31,
+ dayClasses: "",
+ inputValue: "2024-01-31",
+ isSelectable: false,
+ },
+ ],
+ startDateDayIndex: 1,
+ monthClass: " month-hidden",
+ },
+ ],
+};
+
+const mockInitialData = {
+ todayDate: "2023-07-04",
+ initialViewStartDate: "2023-07-05",
+ initialViewEndDate: "2023-08-19",
+ calendarViewDirection: "future",
+ initialShopTimeSlotsResponse: {
+ days: [
+ {
+ date: "2023-07-25",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20295*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ {
+ id: "06747-01820-S-B*20295*730 AM",
+ startTime: "07:30",
+ endTime: "08:30",
+ offerPremium: false,
+ },
+ ],
+ },
+ {
+ date: "2023-07-26",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20296*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ],
+ estimatedServiceMinutesMinimum: 90,
+ estimatedServiceMinutesMaximum: 120,
+ },
+ hideSomeDaysForInitialView: true,
+ hideSecondMonth: false,
+ preSelectedDate: null,
+};
+
+const mockCallbackResponse = {
+ days: [
+ {
+ date: "2024-12-30",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20453*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ {
+ date: "2024-01-02",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20453*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ],
+ estimatedServiceMinutesMinimum: 90,
+ estimatedServiceMinutesMaximum: 120,
+};
+
+const mockPromiseResolve = (returnValue) =>
+ jest.fn(async () => Promise.resolve({ valid: returnValue }));
+
+describe("date-picker.vue", () => {
+ describe("initial setup", () => {
+ test("Expect initializeComponent to be run", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+ wrapper.vm.initializeComponent = jest.fn().mockImplementation();
+ wrapper.vm.initializeComponent(mockInitialData);
+
+ // Assert
+ expect(wrapper.vm.initializeComponent).toHaveBeenCalled();
+
+ wrapper.unmount();
+ });
+
+ test("When initializeComponent runs, expect will run setCalendarData method", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+ const spy = jest.spyOn(wrapper.vm, "setCalendarData");
+
+ wrapper.vm.$nextTick();
+
+ // Act
+ wrapper.vm.initializeComponent(mockInitialData);
+
+ // Assert
+ expect(spy).toHaveBeenCalled();
+
+ wrapper.unmount();
+ });
+
+ test("If prop customComponentId is supplied, expect it will be used for componentId in setup method", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ customComponentId: "dateQuestion",
+ },
+ });
+
+ // Act
+ const componentIdValue = wrapper.vm.componentId;
+
+ // Assert
+ expect(componentIdValue).toEqual("dateQuestion");
+
+ wrapper.unmount();
+ });
+
+ test("If prop customSelectableDatesCallback is not supplied, expect the default function will return empty array", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+
+ // Act
+ const callbackResponse = wrapper.vm.customSelectableDatesCallback(
+ "2023-07-24",
+ "2023-08-19",
+ "Inshop",
+ "006747"
+ );
+
+ // Assert
+ expect(callbackResponse).toEqual([]);
+
+ wrapper.unmount();
+ });
+
+ test("expect a date string created from today", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+ const todayDate = new Date();
+ const todayDateString =
+ todayDate.getFullYear() +
+ "-" +
+ ("0" + (todayDate.getMonth() + 1)).slice(-2) +
+ "-" +
+ ("0" + todayDate.getDate()).slice(-2);
+
+ // Assert
+ expect(wrapper.vm.todayString).toEqual(todayDateString);
+
+ wrapper.unmount();
+ });
+
+ test("expect a date string created from todayOverrideDateString", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-02",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.todayString).toEqual("2023-07-02");
+
+ wrapper.unmount();
+ });
+
+ test("expect computed todayDayIndex returns the correct day index", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-02",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.todayDayIndex).toEqual(0);
+
+ wrapper.unmount();
+ });
+
+ test("expect computed todayDateNum returns the correct date number", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-02",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.todayDateNum).toEqual(2);
+
+ wrapper.unmount();
+ });
+
+ test("expect computed currentWeekStartDateNum returns the correct date number when todayDayIndex is < todayDateNum", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.currentWeekStartDateNum).toEqual(2);
+
+ wrapper.unmount();
+ });
+
+ test("expect computed currentWeekStartDateNum returns 1 when todayDayIndex is >= todayDateNum", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-01",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.currentWeekStartDateNum).toEqual(1);
+
+ wrapper.unmount();
+ });
+
+ test("expect computed currentWeekEndDateNum returns correct value", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.currentWeekEndDateNum).toEqual(8);
+
+ wrapper.unmount();
+ });
+
+ test("expect computed calendarViewDirection returns 'past' when prop selectableDatesSetting is 'past'", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "past",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.calendarViewDirection).toEqual("past");
+
+ wrapper.unmount();
+ });
+
+ test("expect computed calendarViewDirection returns 'future' when prop selectableDatesSetting is 'custom'", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.calendarViewDirection).toEqual("future");
+
+ wrapper.unmount();
+ });
+
+ describe("when loadInitialData is run...", () => {
+ test("and this.todayString exists, expect it should have a todayDate matching today", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const todayDate = new Date();
+ const todayDateString =
+ todayDate.getFullYear() +
+ "-" +
+ ("0" + (todayDate.getMonth() + 1)).slice(-2) +
+ "-" +
+ ("0" + todayDate.getDate()).slice(-2);
+
+ // Act
+ const testResult = await wrapper.vm.loadInitialData({
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ preSelectedDate: null,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ todayDate: todayDateString,
+ });
+
+ wrapper.unmount();
+ });
+
+ test("and overrride date exists, expect it should have a todayDate matching the override", async () => {
+ // Arrange
+ const overrideDate = mockValuesForSetDate01.overrideDate;
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: overrideDate,
+ },
+ });
+
+ // Act
+ const localThis = {
+ todayString: null,
+ todayOverrideDateString: overrideDate,
+ getMonthEnd: () => mockValuesForSetDate01.monthEnd,
+ getInitialViewWeeks: () => mockValuesForSetDate01.initialViewWeeks,
+ };
+ const testResult = await datePicker.methods.loadInitialData.call(localThis, {
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ preSelectedDate: null,
+
+ todayOverrideDateString: overrideDate,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ todayDate: overrideDate,
+ });
+
+ wrapper.unmount();
+ });
+
+ test("with no this.todayString or overrride date, expect it should have a todayDate matching today", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const todayDate = new Date();
+ const todayDateString =
+ todayDate.getFullYear() +
+ "-" +
+ ("0" + (todayDate.getMonth() + 1)).slice(-2) +
+ "-" +
+ ("0" + todayDate.getDate()).slice(-2);
+
+ // Act
+ const localThis = {
+ todayString: null,
+ getMonthEnd: () => mockValuesForSetDate01.monthEnd,
+ getInitialViewWeeks: () => mockValuesForSetDate01.initialViewWeeks,
+ };
+
+ //Act
+ const testResult = await datePicker.methods.loadInitialData.call(localThis, {
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ preSelectedDate: null,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ todayDate: todayDateString,
+ });
+
+ wrapper.unmount();
+ });
+
+ test("and config.selectableDatesSetting is PAST, expect it should have a calendarViewDirection of PAST", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ // Act
+ const testResult = await wrapper.vm.loadInitialData({
+ selectableDatesSetting: "past",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ calendarViewDirection: "past",
+ });
+
+ wrapper.unmount();
+ });
+
+ test("and config.selectableDatesSetting is CUSTOM, expect it should have a calendarViewDirection of FUTURE", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ // Act
+ const testResult = await wrapper.vm.loadInitialData({
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ calendarViewDirection: "future",
+ });
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("when setCalendarData is run...", () => {
+ test("expect that data elements are updated properly", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+
+ // Act
+ await wrapper.vm.setCalendarData(mockValuesForSetDate01.config);
+
+ // Assert
+ expect(wrapper.vm.hideSomeDaysForInitialView).toBe(true);
+ expect(wrapper.vm.selectableDatesData[0]).toMatchObject({
+ date: "2023-12-30",
+ });
+ expect(wrapper.vm.selectableDatesData[0].timeSlots.length).toBeGreaterThan(0);
+ expect(wrapper.vm.months.length).toBe(7);
+ expect(wrapper.vm.months[0]).toMatchObject({
+ monthLabel: "December",
+ monthIndex: 12,
+ monthString: "December-2023",
+ yearNum: 2023,
+ startDateDayIndex: 5,
+ monthClass: "",
+ isMonthThatHidesSomeDaysForInitialView: true,
+ });
+
+ wrapper.unmount();
+ });
+
+ test("expect that this.months are reversed if direction is past", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "past",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ const modifiedConfig = { ...mockValuesForSetDate01.config };
+ modifiedConfig.calendarViewDirection = "past";
+
+ // Act
+ await wrapper.vm.setCalendarData(modifiedConfig);
+
+ // Assert
+ expect(wrapper.vm.months.length).toBe(37);
+ expect(wrapper.vm.months[0]).toMatchObject({
+ monthString: "December-2020",
+ startDateDayIndex: 2,
+ monthClass: " month-hidden last-available-month",
+ });
+
+ wrapper.unmount();
+ });
+
+ test("expect that if there's a pre-selected date that it will scroll to it", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ const modifiedConfig = { ...mockValuesForSetDate01.config };
+ modifiedConfig.preSelectedDate = "2023-12-25";
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+
+ // Act
+ await wrapper.vm.setCalendarData(modifiedConfig);
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.scrollToElement).toHaveBeenCalledWith("December-2023");
+
+ wrapper.unmount();
+ });
+
+ test("expect that if there's a pre-selected date within the last month available then the View More Dates button will be hidden", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ const modifiedConfig = { ...mockValuesForSetDate01.config };
+ modifiedConfig.preSelectedDate = "2024-06-11";
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+
+ // Act
+ await wrapper.vm.setCalendarData(modifiedConfig);
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.disableViewMoreDatesButton).toBe(true);
+
+ wrapper.unmount();
+ });
+
+ test("expect that this.months are reversed if direction is past", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "past",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ const modifiedConfig = { ...mockValuesForSetDate01.config };
+ modifiedConfig.calendarViewDirection = "past";
+
+ // Act
+ await wrapper.vm.setCalendarData(modifiedConfig);
+
+ // Assert
+ expect(wrapper.vm.months.length).toBe(37);
+ expect(wrapper.vm.months[0]).toMatchObject({
+ monthString: "December-2020",
+ startDateDayIndex: 2,
+ monthClass: " month-hidden last-available-month",
+ });
+
+ wrapper.unmount();
+ });
+
+ test("expect that if there's a pre-selected date that it will scroll to it", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ const modifiedConfig = { ...mockValuesForSetDate01.config };
+ modifiedConfig.preSelectedDate = "2023-12-25";
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+
+ // Act
+ await wrapper.vm.setCalendarData(modifiedConfig);
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.scrollToElement).toHaveBeenCalledWith("December-2023");
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("when getInitialViewWeeks is run...", () => {
+ test("expect that 5 weeks will be returned when no preselected date", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const todayString = "2023-02-01";
+
+ // Act
+ const testResult = wrapper.vm.getInitialViewWeeks(todayString, 5);
+
+ // Assert
+ expect(testResult.length).toBe(5);
+
+ wrapper.unmount();
+ });
+
+ test("expect that today will be in the start/end range of dates of the first week when no preselected date", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const todayString = "2023-02-01";
+
+ // Act
+ const testResult = wrapper.vm.getInitialViewWeeks(todayString, 5);
+
+ // Assert
+ expect(
+ testResult[0].weekStartDate <= todayString &&
+ todayString <= testResult[0].weekEndDate
+ ).toBe(true);
+
+ wrapper.unmount();
+ });
+
+ test("expect that single weeks that span 2 months will be split into separate shorter 'week' spans", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const todayString = "2023-02-15";
+
+ // Act
+ const testResult = wrapper.vm.getInitialViewWeeks(todayString, 5);
+
+ // Assert
+ expect(testResult.length).toBe(5);
+ expect(testResult[0]).toMatchObject({
+ weekStartDate: "2023-02-12",
+ });
+ expect(testResult[testResult.length - 1]).toMatchObject({
+ weekEndDate: "2023-03-11",
+ });
+
+ wrapper.unmount();
+ });
+
+ test("expect that if today is 7/31/23 and there's a preselected date of 10/1/23 that there will be 14 initial weeks returned", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const mockPreSelectedDate = "2023-10-01";
+
+ // Act
+ const testResult = wrapper.vm.getInitialViewWeeks(
+ "2023-07-31",
+ 5,
+ mockPreSelectedDate
+ );
+
+ // Assert
+ expect(testResult.length).toBe(14);
+
+ wrapper.unmount();
+ });
+
+ test("expect that if there's a preselected date that the last week end date will be the end of the month of the preselected date", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const mockPreSelectedDate = "2023-10-01";
+
+ // Act
+ const testResult = wrapper.vm.getInitialViewWeeks(
+ "2023-07-31",
+ 5,
+ mockPreSelectedDate
+ );
+
+ // Assert
+ expect(testResult[testResult.length - 1]).toMatchObject({
+ weekEndDate: "2023-10-31",
+ });
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("when there's a pre-selected date...", () => {
+ test("and loadInitialData runs, expect hideSomeDaysForInitialView and hideSecondMonth to be false", async () => {
+ // Arrange
+ // uses "2023-12-01" which would set both hideSomeDaysForInitialView and hideSecondMonth to true, unless there was a pre-selected date
+ const overrideDate = mockValuesForSetDate01.overrideDate;
+ const mockMonthEnd = mockValuesForSetDate01.monthEnd;
+ const mockInitialViewWeeks = mockValuesForSetDate01.initialViewWeeks;
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: overrideDate,
+ },
+ });
+
+ // Act
+ const localThis = {
+ todayString: null,
+ todayOverrideDateString: overrideDate,
+ getMonthEnd: () => mockMonthEnd,
+ getInitialViewWeeks: () => mockInitialViewWeeks,
+ };
+ const testResult = await datePicker.methods.loadInitialData.call(localThis, {
+ selectableDatesSetting: "custom",
+ initialViewRowsToShow: 5,
+ customSelectableDatesCallback: mockPromiseResolve,
+ preSelectedDate: "2024-01-01",
+ todayOverrideDateString: overrideDate,
+ });
+
+ // Assert
+ expect(testResult).toMatchObject({
+ hideSomeDaysForInitialView: false,
+ hideSecondMonth: false,
+ });
+
+ wrapper.unmount();
+ });
+ });
+ });
+
+ describe("showAnotherMonth method...", () => {
+ test("expect that when hideSomeDaysForInitialView is true that it scrolls to correct month", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ wrapper.vm.months = mockValuesForSetDate01.monthsData;
+ wrapper.vm.updateSelectableDates = jest.fn().mockImplementation();
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+ wrapper.vm.hideSomeDaysForInitialView = true;
+
+ // Act
+ await wrapper.vm.showAnotherMonth();
+
+ // Assert
+ expect(wrapper.vm.updateSelectableDates).toHaveBeenCalledWith(
+ "2023-12-31",
+ "2023-12-31"
+ );
+ expect(wrapper.vm.scrollToElement).toHaveBeenCalledWith("December-2023");
+
+ wrapper.unmount();
+ });
+
+ test("expect that when hideSomeDaysForInitialView is false and direction is FUTURE that it scrolls to correct month", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ wrapper.vm.months = [...mockValuesForSetDate01.monthsData]; // copy array w/o reference to original
+ wrapper.vm.updateSelectableDates = jest.fn().mockImplementation();
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+ wrapper.vm.hideSomeDaysForInitialView = false;
+
+ // Act
+ await wrapper.vm.showAnotherMonth();
+
+ // Assert
+ expect(wrapper.vm.updateSelectableDates).toHaveBeenCalledWith(
+ "2024-01-01",
+ "2024-01-31"
+ );
+ expect(wrapper.vm.scrollToElement).toHaveBeenCalledWith("January-2024");
+
+ wrapper.unmount();
+ });
+
+ test("expect that when hideSomeDaysForInitialView is false and direction is PAST that it scrolls to correct month", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "past",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ // Force correct state for this test. // TODO - figure out why original array is getting mutated here, making next line necessary
+ mockValuesForSetDate01.monthsData[1].monthClass = " month-hidden";
+
+ wrapper.vm.months = [...mockValuesForSetDate01.monthsData]; // copy array w/o reference to original
+ wrapper.vm.updateSelectableDates = jest.fn().mockImplementation();
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+ wrapper.vm.hideSomeDaysForInitialView = false;
+
+ // Act
+ await wrapper.vm.showAnotherMonth();
+
+ // Assert
+ expect(wrapper.vm.updateSelectableDates).toHaveBeenCalledWith(
+ "2024-01-01",
+ "2024-01-31"
+ );
+ expect(wrapper.vm.scrollToElement).toHaveBeenCalledWith("January-2024");
+
+ wrapper.unmount();
+ });
+
+ test("expect that when the month to scroll to is the last available month that it will disable the View More Dates button", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+ wrapper.vm.months = [...mockValuesForSetDate01.monthsData]; // copy array w/o reference to original
+ wrapper.vm.updateSelectableDates = jest.fn().mockImplementation();
+ wrapper.vm.scrollToElement = jest.fn().mockImplementation();
+ wrapper.vm.disableViewMoreDatesButton = false;
+ mockValuesForSetDate01.monthsData[1].monthClass = " month-hidden last-available-month"; // Force correct state for this test.
+
+ // Act
+ await wrapper.vm.showAnotherMonth();
+
+ // Assert
+ expect(wrapper.vm.disableViewMoreDatesButton).toBe(true);
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("updateSelectableDates method...", () => {
+ test("expect that new dates from callback are added to selectableDatesData", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ customSelectableDatesCallback: jest.fn(() => mockCallbackResponse),
+ },
+ });
+ wrapper.vm.selectableDatesData = [
+ {
+ date: "2023-12-30",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20453*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ];
+ wrapper.vm.months = mockValuesForSetDate01.monthsData;
+
+ // Act
+ await wrapper.vm.updateSelectableDates("2024-01-01", "2024-01-05");
+ const isFoundInArray = wrapper.vm.selectableDatesData.find((obj) => {
+ return obj.date === "2024-01-02";
+ });
+
+ // Assert
+ expect(isFoundInArray).not.toBeUndefined();
+
+ wrapper.unmount();
+ });
+
+ test("expect that isSelectable flag on selectable dates is set to true", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ customSelectableDatesCallback: jest.fn(() => mockCallbackResponse),
+ },
+ });
+ wrapper.vm.selectableDatesData = [
+ {
+ date: "2023-12-30",
+ timeSlots: [
+ {
+ id: "06747-01820-S-B*20453*7 AM",
+ startTime: "07:00",
+ endTime: "08:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ];
+ wrapper.vm.months = mockValuesForSetDate01.monthsData;
+
+ // Act
+ await wrapper.vm.updateSelectableDates("2024-01-01", "2024-01-05");
+ const targetMonth = wrapper.vm.months.find((month) => {
+ return month.monthString === "January-2024";
+ });
+ const dateInArray = targetMonth.dates.find((date) => {
+ return date.inputValue === "2024-01-02";
+ });
+
+ // Assert
+ expect(dateInArray).toMatchObject({
+ isSelectable: true,
+ });
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("scrollToElement method...", () => {
+ test("expect that new dates from callback are added to selectableDatesData", () => {
+ // Arrange
+ const container = document.createElement("div");
+ container.classList.add("page-container-grouped-styles");
+ const targetElement = document.createElement("div");
+ targetElement.setAttribute("id", "January-2024");
+ container.appendChild(targetElement);
+ document.body.appendChild(container);
+ window.requestAnimationFrame = jest.fn();
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: mockValuesForSetDate01.overrideDate,
+ },
+ });
+
+ // Act
+ wrapper.vm.scrollToElement("January-2024");
+
+ // Assert
+ expect(window.requestAnimationFrame).toBeCalled();
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("If user selects a date...", () => {
+ test("expect it will emit update:modelValue", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+ const dateToSelect = "2023-07-07";
+
+ // Act
+ wrapper.setValue({ selectedDate: dateToSelect });
+
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
+ { selectedDate: "2023-07-07" },
+ ]);
+
+ wrapper.unmount();
+ });
+
+ test("expect watched modelValue will be triggered", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+ const dateToSelect = "2023-07-07";
+ wrapper.vm.resetField = jest.fn();
+
+ // Act
+ wrapper.vm.$options.watch.modelValue.call(wrapper.vm, dateToSelect);
+
+ // Assert
+ expect(wrapper.vm.resetField).toBeCalled();
+ expect(wrapper.vm.resetField).toBeCalledWith({ value: dateToSelect });
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("If fireDateSelectedEvent runs... ", () => {
+ test("expect it will emit date-clicked on mouse clicks ", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+
+ // Act
+ wrapper.vm.fireDateSelectedEvent({});
+ const flattenedEmitted = JSON.stringify(wrapper.emitted());
+
+ // Assert
+ expect(wrapper.emitted()).toHaveProperty("date-clicked");
+ expect(flattenedEmitted.includes("date-clicked")).toBeTruthy;
+
+ wrapper.unmount();
+ });
+
+ test("expect it will NOT emit date-clicked on keyboard arrow navigation ", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ },
+ });
+
+ // Act
+ wrapper.vm.fireDateSelectedEvent({ screenX: 0, screenY: 0 });
+ const flattenedEmitted = JSON.stringify(wrapper.emitted());
+
+ // Assert
+ expect(wrapper.emitted()).not.toHaveProperty("date-clicked");
+ expect(flattenedEmitted.includes("date-clicked")).toBe(false);
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("If user triggers a validation error...", () => {
+ test("expect that watched errorMessage will be triggered", () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ propsData: {
+ selectableDatesSetting: "custom",
+ todayOverrideDateString: "2023-07-05",
+ },
+ });
+ wrapper.vm.scrollToElement = jest.fn();
+
+ // Act
+ wrapper.vm.$options.watch.errorMessage.call(wrapper.vm, "anything");
+
+ // Assert
+ expect(wrapper.vm.scrollToElement).toBeCalled();
+ expect(wrapper.vm.scrollToElement).toBeCalledWith("date-of-month-error");
+
+ wrapper.unmount();
+ });
+ });
+});
+
+function setupMocks(mountOptionsMockData = {}) {
+ store.getters = {
+ order: {
+ serviceLocation: { appointmentType: "Inshop", provider: { providerNumber: "12345" } },
+ },
+ };
+ const initialMountOptionsMockData = {
+ store: {
+ getters: store.getters,
+ },
+ };
+ const mountOptions = getMountOptions(
+ Object.assign(initialMountOptionsMockData, mountOptionsMockData)
+ );
+
+ const wrapper = shallowMount(datePicker, mountOptions);
+
+ return { wrapper };
+}
diff --git a/src/digital-components/date-picker/date-picker.spec.js1 b/src/digital-components/date-picker/date-picker.spec.js1
deleted file mode 100644
index fd2747d83..000000000
--- a/src/digital-components/date-picker/date-picker.spec.js1
+++ /dev/null
@@ -1,477 +0,0 @@
-import datePicker from "./date-picker";
-
-// Supporting Files
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-
-describe("date-picker.vue", () => {
- describe("initial setup", () => {
- test("Creates a date object from today", async () => {
- // Arrange
- const { wrapper } = await setupMocks({
- propsData: {
- selectableDatesSetting: "custom"
- },
- });
-
- wrapper.vm.loadInitialData = jest.fn().mockImplementation(
- () =>
- new Promise((resolve, reject) => {
- resolve({
- data: [responseValue],
- });
- })
- );
-
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.loadInitialData).toHaveBeenCalled();
-
- // console.log("wrapper.vm.today: ", wrapper.vm.today)
-
- // // Act
- // const testResult = wrapper.vm.today instanceof Date;
- // console.log("testResult: ", testResult)
-
- // // Assert
- // expect(testResult).toEqual(true);
-
- wrapper.unmount();
- });
- });
- // describe("formatNumberToSetDigits", () => {
- // const testScenarios = [
- // [0, 3, "000"],
- // [8, 2, "08"],
- // [345, 2, "345"],
- // [4567, 0, "4567"],
- // ];
- // test.each(testScenarios)(
- // "when num is %s and digits is %s, formatNumberToSetDigits should return %s",
- // async (num, digits, expectedReturn) => {
- // // Arrange
- // const { wrapper } = setupMocks({});
-
- // // Act
- // const fnReturn = wrapper.vm.formatNumberToSetDigits(num, digits);
-
- // // Assert
- // expect(fnReturn).toEqual(expectedReturn);
- // }
- // );
- // });
- // describe("formatDate", () => {
- // test("Can format a date as MM/dd/yyyy", () => {
- // // Arrange
- // const { wrapper } = setupMocks({});
- // const testDate = new Date("01-26-2023");
-
- // // Act
- // const testResult = wrapper.vm.formatDate(testDate);
-
- // // Assert
- // expect(testResult).toEqual("01/26/2023");
-
- // wrapper.unmount();
- // });
-
- // // test("Can get correct initialFirstDate from today", () => {
- // // // Arrange
- // // const { wrapper } = setupMocks({
- // // propsData: {
- // // todayDate: "Thu Jan 26 2023",
- // // },
- // // });
-
- // // // Act
- // // const testResult = wrapper.vm.initialFirstDate;
- // // const testResultAsDateString = testResult.toDateString();
-
- // // // Assert
- // // expect(testResultAsDateString).toEqual("Sun Jan 22 2023");
-
- // // wrapper.unmount();
- // // });
- // });
- // describe("calendarData", () => {
- // test("should return an array", async () => {
- // // Arrange
- // const { wrapper } = setupMocks({});
-
- // // Act
- // const testResult = await wrapper.vm.calendarData;
-
- // // Assert
- // expect(Array.isArray(testResult)).toBe(true);
-
- // wrapper.unmount();
- // });
- // describe("each month should have keys monthLabel, yearNum, dates, firstDateDayIndex", () => {
- // const testScenarios = [
- // ["monthLabel", true, "string"],
- // ["yearNum", true, "number"],
- // ["dates", true, "object"],
- // ["firstDateDayIndex", true, "number"],
- // ["monthClass", true, "string"],
- // ];
-
- // test.each(testScenarios)(
- // "test for %s key should return %s and be type %s",
- // async (label, test, type) => {
- // // Arrange
- // const { wrapper } = setupMocks({});
- // const containsMonthLabel = (obj) => Object.hasOwn(obj, label);
- // const isCorrectType = (obj) => typeof obj[label] === type;
- // const isTruthyOrZero = (obj) => (obj[label] || obj[label] === 0 ? true : false);
-
- // // Act
- // const calendarData = await wrapper.vm.calendarData;
- // // console.log("calendarData: ", calendarData);
-
- // // Assert
- // expect(calendarData.every(containsMonthLabel)).toBe(true);
- // expect(calendarData.every(isCorrectType)).toBe(true);
- // expect(calendarData.every(isTruthyOrZero)).toBe(true);
-
- // wrapper.unmount();
- // }
- // );
- // });
-
- // describe("the current month's week which includes today", () => {
- // const testScenarios = [
- // ["2022-02-05T03:00:00", 1, 2, true],
- // ["2024-02-05T03:00:00", 4, 0, true],
- // ["2020-01-15T03:00:00", 12, 0, true],
- // ];
-
- // test.each(testScenarios)(
- // "the first date of the week including the date %s should be the date number %s and be day index %s",
- // async (todayDateString, startDate, dayOfWeekIndex) => {
- // // Arrange
- // const { wrapper } = setupMocks({
- // propsData: {
- // todayOverrideDateString: todayDateString,
- // },
- // });
-
- // // Act
- // const calendarData = await wrapper.vm.calendarData;
- // const currentMonthIndex = calendarData.findIndex((month) => {
- // console.log("month: ", month);
- // return month.monthClass === "currentMonth";
- // });
- // console.log("calendarData ", calendarData);
- // console.log("currentMonthIndex ", currentMonthIndex);
-
- // // Assert
- // expect(calendarData[currentMonthIndex].dates[0].dateNum === startDate).toBe(
- // true
- // );
- // expect(
- // calendarData[currentMonthIndex].dates[0].firstDateDayIndex ===
- // dayOfWeekIndex
- // ).toBe(true);
-
- // wrapper.unmount();
- // }
- // );
- // });
-
- // test("the current month's dates array should start with the first day of the week which includes today", async () => {
- // // Arrange
- // const { wrapper } = setupMocks({});
- // const hasAFirstInDates = (obj) => obj?.dates[0].dateNum === 1;
-
- // // Act
- // const calendarData = await wrapper.vm.calendarData;
- // const currentMonthIndex = calendarData.findIndex((month) => {
- // return month.monthClass === "currentMonth";
- // });
-
- // // Assert
- // expect(calendarData[currentMonthIndex].dates[0].dateNum === 1).toBe(true);
-
- // wrapper.unmount();
- // });
-
- // test("for each month (other than current month), the dates array should have the 1st of the month", async () => {
- // // Arrange
- // const { wrapper } = setupMocks({});
- // const hasAFirstInDates = (obj) => obj?.dates[0].dateNum === 1;
-
- // // Act
- // const calendarData = await wrapper.vm.calendarData;
-
- // // Assert
- // expect(calendarData.every(hasAFirstInDates)).toBe(true);
-
- // wrapper.unmount();
- // });
-
- // describe("for the current month in calendarData, the dates array should have correct days of month", () => {
- // const testScenarios = [
- // ["2022-02-05T03:00:00", 28, true],
- // ["2024-02-05T03:00:00", 29, true],
- // ["2020-01-15T03:00:00", 31, true],
- // ];
-
- // test.each(testScenarios)(
- // "the current month including the date %s should have %s days in its dates array",
- // async (dateString, noOfDays) => {
- // // Arrange
- // const { wrapper } = setupMocks({
- // propsData: {
- // todayOverrideDateString: dateString,
- // },
- // });
-
- // // Act
- // const calendarData = await wrapper.vm.calendarData;
- // const currentMonthIndex = calendarData.findIndex((month) => {
- // return month.monthClass === "currentMonth";
- // });
-
- // // Assert
- // expect(calendarData[currentMonthIndex].dates.length === noOfDays).toBe(true);
-
- // wrapper.unmount();
- // }
- // );
-
- // // test.each(testScenarios)(
- // // "the date %s should have %s days in dates array",
- // // async (dateString, noOfDays) => {
- // // // Arrange
- // // const { wrapper } = setupMocks({
- // // propsData: {
- // // todayOverrideDateString: dateString,
- // // },
- // // });
- // // const hasCorrectNumberOfDates = (obj) => obj?.dates.length === noOfDays;
-
- // // // Act
- // // const calendarData = await wrapper.vm.calendarData;
-
- // // // Assert
- // // expect(calendarData.every(hasCorrectNumberOfDates)).toBe(true);
-
- // // wrapper.unmount();
- // // }
- // // );
- // });
-
- // // describe("for each object in array, the dates array should have correct days of month", () => {
- // // const testScenarios = [
- // // ["2022-02-05T03:00:00", 28, true],
- // // ["2024-02-05T03:00:00", 29, true],
- // // ["2020-01-15T03:00:00", 31, true],
- // // ];
-
- // // test.each(testScenarios)(
- // // "the date %s should have %s days in dates array",
- // // async (dateString, noOfDays) => {
- // // // Arrange
- // // const { wrapper } = setupMocks({
- // // propsData: {
- // // todayOverrideDateString: dateString,
- // // },
- // // });
- // // const hasCorrectNumberOfDates = (obj) => obj?.dates.length === noOfDays;
-
- // // // Act
- // // const calendarData = await wrapper.vm.calendarData;
-
- // // // Assert
- // // expect(calendarData.every(hasCorrectNumberOfDates)).toBe(true);
-
- // // wrapper.unmount();
- // // }
- // // );
- // // });
-
- // // test.only("each object in array should have a monthLabel", () => {
- // // // Arrange
- // // const { wrapper } = setupMocks({});
- // // // const testTodayDate = new Date("01-26-2023");
-
- // // // Act
- // // const testResult = wrapper.vm.calendarData;
- // // const containsMonthLabel = (month) => Object.hasOwn(month, 'monthLabel');
-
- // // // Assert
- // // expect(testResult.every(containsMonthLabel)).toBe(true);
-
- // // });
-
- // // test.only("array should have a month object with same month as today", () => {
- // // // Arrange
- // // const { wrapper } = setupMocks({});
- // // // const testTodayDate = new Date("01-26-2023");
-
- // // // Act
- // // // const testResult = wrapper.vm.calendarData;
- // // console.log("wrapper.vm.calendarData: ", wrapper.vm.calendarData)
-
- // // // Assert
- // // // expect(wrapper.vm.calendarData).toEqual("something");
- // // // expect(wrapper.vm.calendarDataOld).toEqual("something");
-
- // // expect(wrapper.vm.calendarData[1]).toMatchObject({
- // // "dates": [
- // // {
- // // "dateNum": 1
- // // },
- // // {
- // // "dateNum": 2
- // // },
- // // {
- // // "dateNum": 3
- // // },
- // // {
- // // "dateNum": 4
- // // },
- // // {
- // // "dateNum": 5
- // // },
- // // {
- // // "dateNum": 6
- // // },
- // // {
- // // "dateNum": 7
- // // },
- // // {
- // // "dateNum": 8
- // // },
- // // {
- // // "dateNum": 9
- // // },
- // // {
- // // "dateNum": 10
- // // },
- // // {
- // // "dateNum": 11
- // // },
- // // {
- // // "dateNum": 12
- // // },
- // // {
- // // "dateNum": 13
- // // },
- // // {
- // // "dateNum": 14
- // // },
- // // {
- // // "dateNum": 15
- // // },
- // // {
- // // "dateNum": 16
- // // },
- // // {
- // // "dateNum": 17
- // // },
- // // {
- // // "dateNum": 18
- // // },
- // // {
- // // "dateNum": 19
- // // },
- // // {
- // // "dateNum": 20
- // // },
- // // {
- // // "dateNum": 21
- // // },
- // // {
- // // "dateNum": 22
- // // },
- // // {
- // // "dateNum": 23
- // // },
- // // {
- // // "dateNum": 24
- // // },
- // // {
- // // "dateNum": 25
- // // },
- // // {
- // // "dateNum": 26
- // // },
- // // {
- // // "dateNum": 27
- // // },
- // // {
- // // "dateNum": 28
- // // },
- // // {
- // // "dateNum": 29
- // // },
- // // {
- // // "dateNum": 30
- // // },
- // // {
- // // "dateNum": 31
- // // }
- // // ],
- // // "monthLabel": "January",
- // // "yearNum": 2023
- // // });
-
- // // wrapper.unmount();
- // // });
- // });
-});
-
-function setupMocks(mountOptionsMockData = {}) {
- const initialMountOptionsMockData = {
- // router: {
- // navigate: jest.fn(),
- // navigateWithSaving: jest.fn(),
- // navigateWithoutSaving: jest.fn(),
- // },
- // actionList: [
- // // {
- // // actionName: storeActions.SAVE_PART_QUESTION_ANSWERS,
- // // data: {},
- // // },
- // // {
- // // actionName: storeActions.GET_PARTS,
- // // data: {},
- // // },
- // ],
- // store: {
- // // getters: store.getters,
- // // commit: store.commit,
- // },
- };
-
- const mountOptions = getMountOptions(
- Object.assign(initialMountOptionsMockData, mountOptionsMockData)
- );
-
- // console.log("mountOptions: ", mountOptions)
-
- const wrapper = shallowMount(datePicker, mountOptions);
-
- return { wrapper };
-}
diff --git a/src/digital-components/date-picker/date-picker.vue b/src/digital-components/date-picker/date-picker.vue
index bd1ce8fe2..0683a9180 100644
--- a/src/digital-components/date-picker/date-picker.vue
+++ b/src/digital-components/date-picker/date-picker.vue
@@ -174,9 +174,8 @@ export default {
return this.todayDateNum + (6 - this.todayDayIndex);
},
calendarViewDirection() {
- if (this.selectableDatesSetting === "past") return "past";
if (this.selectableDatesSetting === "custom") return "future";
- return "none";
+ return "past";
},
selectedDate: {
get() {
@@ -428,7 +427,7 @@ export default {
} else if (direction === "past") {
// first 0, then -1
for (let i = 0; i >= 0 - monthsBeforeToLoadOffset; i--) {
- months.unshift(this.getMonthData(i, options));
+ months.unshift(await this.getMonthData(i, options));
}
} else {
// TODO - IF A CALENDAR WITH BOTH PAST AND FUTURE WAS EVER NEEDED
@@ -610,7 +609,7 @@ export default {
// find the first day-hidden to become the next api call start date
monthStartDateNum =
monthToShow.dates.find(({ dayClasses }) => dayClasses.includes("day-hidden"))
- .dateNum - 1; // TRY 2
+ .dateNum - 1;
} else {
if (this.calendarViewDirection === "future") {
monthToShow = this.months.find((month) =>
@@ -646,11 +645,12 @@ export default {
this.$store.getters.order.serviceLocation.appointmentType,
this.$store.getters.order.serviceLocation.provider.providerNumber
);
+
moreSelectableDates.days.forEach((selectableDate) => {
const index = this.selectableDatesData.findIndex(
(dateObj) => dateObj.date === selectableDate.date
);
- if (index === -1) this.selectableDatesData.push(selectableDate.date);
+ if (index === -1) this.selectableDatesData.push(selectableDate);
this.months.forEach((month) => {
// TODO: avoid checking all calendar dates; maybe only ones between monthStart and monthEnd as defined above?
month.dates.forEach((date) => {
diff --git a/src/digital-components/phone-number-question/phone-number-question.vue b/src/digital-components/phone-number-question/phone-number-question.vue
index f3fdc6cd6..86dfc3f04 100644
--- a/src/digital-components/phone-number-question/phone-number-question.vue
+++ b/src/digital-components/phone-number-question/phone-number-question.vue
@@ -8,7 +8,7 @@
:mask="mask"
:isRequired="isRequired"
:validationRules="validationRulesForTextBoxQuestion"
- cmsWidgetName="PhoneNumberQuestionWidget" />
+ :cmsWidgetName="cmsWidgetName" />
diff --git a/src/fmg-components/vehicle-banner/vehicle-banner.spec.js b/src/fmg-components/vehicle-banner/vehicle-banner.spec.js
index b4d723e18..1a9222299 100644
--- a/src/fmg-components/vehicle-banner/vehicle-banner.spec.js
+++ b/src/fmg-components/vehicle-banner/vehicle-banner.spec.js
@@ -18,6 +18,7 @@ describe("vehicleBanner", () => {
const { wrapper } = setupMocks({
displayGenericVehicleImageProp: true,
imageUrlValue: "NULL",
+ displayUnmatchedVehicleIconProp: true,
});
// Assert
@@ -87,7 +88,12 @@ describe("vehicleBanner", () => {
);
});
-function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryValue = "CAR" }) {
+function setupMocks({
+ displayGenericVehicleImageProp,
+ displayUnmatchedVehicleIconProp,
+ imageUrlValue,
+ categoryValue = "CAR",
+}) {
const mockGetCmsContent = jest.fn();
mockGetCmsContent((cmsWidget, field) => {
return field;
@@ -108,7 +114,10 @@ function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryVal
});
//Mock props
- mountOptions.propsData = { displayGenericVehicleImage: displayGenericVehicleImageProp };
+ mountOptions.propsData = {
+ displayGenericVehicleImage: displayGenericVehicleImageProp,
+ displayUnmatchedVehicleIconProp: displayUnmatchedVehicleIconProp,
+ };
mountOptions.mixins = [mockMixin];
const wrapper = shallowMount(vehicleBanner, mountOptions);
diff --git a/src/fmg-components/vehicle-banner/vehicle-banner.vue b/src/fmg-components/vehicle-banner/vehicle-banner.vue
index 8f7be0179..8bff4e9e2 100644
--- a/src/fmg-components/vehicle-banner/vehicle-banner.vue
+++ b/src/fmg-components/vehicle-banner/vehicle-banner.vue
@@ -13,16 +13,34 @@ export default {
required: true,
},
cmsWidgetName: String,
+ displayVehicleImage: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ displayUnmatchedVehicleIcon: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ vehicleCategory: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
vehicleImageToDisplay() {
+ if (this.displayVehicleImage !== null) {
+ return this.displayVehicleImage;
+ }
if (this.displayGenericVehicleImage) {
return this.genericVehicleImage;
}
-
if (
this.$store.getters.vehicle.imageUrl === null ||
- this.$store.getters.vehicle.imageUrl === "NULL"
+ this.$store.getters.vehicle.imageUrl === "NULL" ||
+ this.displayUnmatchedVehicleIcon
) {
return this.getUnmatchedVehicleIcon();
}
@@ -50,7 +68,8 @@ export default {
},
methods: {
getUnmatchedVehicleIcon() {
- switch (this.$store.getters.vehicle.category) {
+ const category = this.vehicleCategory ?? this.$store.getters.vehicle.category;
+ switch (category) {
case this.vehicleCategories.CAR:
return this.carUnmatchedVehicleIcon;
case this.vehicleCategories.SUV:
diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js
index 913fbcb1b..fe6a16591 100644
--- a/src/helpers/heritage-integration/navigation-helper.js
+++ b/src/helpers/heritage-integration/navigation-helper.js
@@ -31,7 +31,8 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita
// Return that page, so that it can navigate like normal.
if (
toRoute.query[queryStrings.FMG_PAGE] !== undefined &&
- toRoute.query[queryStrings.FMG_PAGE] !== fmgPageValues.QUOTE &&
+ toRoute.query[queryStrings.FMG_PAGE] !== fmgPageValues.SERVICE_LOCATION &&
+ toRoute.query[queryStrings.FMG_PAGE] !== fmgPageValues.SCHEDULE &&
!isVinRelatedPage(toRoute)
) {
return overrideYmmsDirectionIfNeeded(toRoute);
@@ -102,9 +103,6 @@ async function getLatestPageForRedirection() {
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
// This also works if a user has a 'fmg' start_type query string but no current order.
// That shouldn't happen, but it's possible.
- const vehicleMakeComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MAKE);
- const vehicleModelComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MODEL);
- const vehicleStyleComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_STYLE);
const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);
const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
@@ -115,21 +113,21 @@ async function getLatestPageForRedirection() {
fmgPageValues.CAPABILITY_QUESTIONS
);
const quoteComponent = await getLazyLoadedComponent(fmgPageValues.QUOTE);
+ const serviceLocationComponent = await getLazyLoadedComponent(fmgPageValues.SERVICE_LOCATION);
+ const scheduleComponent = await getLazyLoadedComponent(fmgPageValues.SCHEDULE);
const skipVin = await skipVinLookup();
- if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
- return fmgPageValues.VEHICLE_YEAR;
- } else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) {
- return fmgPageValues.VEHICLE_MAKE;
- } else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) {
- return fmgPageValues.VEHICLE_MODEL;
- } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
- return fmgPageValues.VEHICLE_STYLE;
+ if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
+ return fmgPageValues.VEHICLE;
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.VEHICLE_DAMAGE;
} else {
- if (quoteComponent.methods.arePagePrerequisitesValid()) {
+ if (scheduleComponent.methods.arePagePrerequisitesValid()) {
+ return fmgPageValues.SCHEDULE;
+ } else if (serviceLocationComponent.methods.arePagePrerequisitesValid()) {
+ return fmgPageValues.SERVICE_LOCATION;
+ } else if (quoteComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.QUOTE;
} else if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.CAPABILITY_QUESTIONS;
@@ -163,10 +161,7 @@ function overrideYmmsDirectionIfNeeded(toRoute) {
if (store.getters.payment.insuranceCoverage.isVerified) {
switch (fmgPageValue) {
- case fmgPageValues.VEHICLE_YEAR:
- case fmgPageValues.VEHICLE_MAKE:
- case fmgPageValues.VEHICLE_MODEL:
- case fmgPageValues.VEHICLE_STYLE: {
+ case fmgPageValues.VEHICLE: {
return fmgPageValues.VEHICLE_DAMAGE;
}
default: {
diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js
index d08ce92ec..cb0664f78 100644
--- a/src/helpers/heritage-integration/navigation-helper.spec.js
+++ b/src/helpers/heritage-integration/navigation-helper.spec.js
@@ -20,7 +20,7 @@ jest.mock("@/router/dynamic-routing/component-loader.js", () => ({
}));
describe("getPageToRouteExistingOrderTo", () => {
- test("should return vehicle-year", async () => {
+ test("should return vehicle", async () => {
// Arrange
const toRoute = {
query: {},
@@ -31,75 +31,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: false,
- });
-
- // Act
- const result = await getPageToRouteExistingOrderTo(toRoute, false);
-
- //Assert
- expect(result).toBe(fmgPageValues.VEHICLE_YEAR);
- });
-
- test("should return vehicle-make", async () => {
- // Arrange
- const toRoute = {
- query: {},
- };
-
- store.commit(storeMutations.UPDATE_IS_REPAIR, false);
- store.commit(storeMutations.UPDATE_MAKE, "acura");
-
- // Mock out the lazy load calls for all components.
- mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: false,
- });
-
- // Act
- const result = await getPageToRouteExistingOrderTo(toRoute, false);
-
- //Assert
- expect(result).toBe(fmgPageValues.VEHICLE_MAKE);
- });
-
- test("should return vehicle-model", async () => {
- // Arrange
- const toRoute = {
- query: {},
- };
-
- store.commit(storeMutations.UPDATE_IS_REPAIR, false);
- store.commit(storeMutations.UPDATE_MAKE, "acura");
-
- // Mock out the lazy load calls for all components.
- mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: false,
- });
-
- // Act
- const result = await getPageToRouteExistingOrderTo(toRoute, false);
-
- //Assert
- expect(result).toBe(fmgPageValues.VEHICLE_MODEL);
- });
-
- test("should return vehicle-style", async () => {
- // Arrange
- const toRoute = {
- query: {},
- };
-
- store.commit(storeMutations.UPDATE_IS_REPAIR, false);
- store.commit(storeMutations.UPDATE_MAKE, "acura");
-
- // Mock out the lazy load calls for all components.
- mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: false,
});
@@ -107,7 +39,7 @@ describe("getPageToRouteExistingOrderTo", () => {
const result = await getPageToRouteExistingOrderTo(toRoute, false);
//Assert
- expect(result).toBe(fmgPageValues.VEHICLE_STYLE);
+ expect(result).toBe(fmgPageValues.VEHICLE);
});
test("should return vehicle-damage", async () => {
@@ -121,9 +53,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: false,
});
@@ -156,9 +86,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
@@ -186,9 +114,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
@@ -216,9 +142,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: true,
@@ -246,9 +170,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
@@ -276,9 +198,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
@@ -306,9 +226,7 @@ describe("getPageToRouteExistingOrderTo", () => {
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
- [fmgPageValues.VEHICLE_MAKE]: true,
- [fmgPageValues.VEHICLE_MODEL]: true,
- [fmgPageValues.VEHICLE_STYLE]: true,
+ [fmgPageValues.VEHICLE]: true,
[fmgPageValues.VEHICLE_DAMAGE]: true,
[fmgPageValues.ESTIMATE]: true,
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js
index 010c39ec9..01f5a5d67 100644
--- a/src/helpers/heritage-integration/order-helper.js
+++ b/src/helpers/heritage-integration/order-helper.js
@@ -114,6 +114,7 @@ async function saveSessionHelper() {
storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
{
referralNumber: savedSessionInfo.data.referralNumber?.toString(),
+ referralSequenceNumber: savedSessionInfo.data.referralSequenceNumber,
referralCorrelationId: savedSessionInfo.data.referralCorrelationId,
referralDate: savedSessionInfo.data.referralDate,
parentAccountNumber: savedSessionInfo.data.parentAccountNumber?.toString(),
diff --git a/src/helpers/querystring-helper.js b/src/helpers/querystring-helper.js
new file mode 100644
index 000000000..38583b1ae
--- /dev/null
+++ b/src/helpers/querystring-helper.js
@@ -0,0 +1,10 @@
+export function getQuerystringParameter(key) {
+ const queryString = window.location.search;
+ const urlParams = new URLSearchParams(queryString);
+ const lowerCaseParams = new URLSearchParams();
+ for (const [name, value] of urlParams) {
+ lowerCaseParams.append(name.toLowerCase(), value);
+ }
+
+ return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null;
+}
diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js
index 2c4b44950..63847588b 100644
--- a/src/layouts/address-lookup/address-lookup.spec.js
+++ b/src/layouts/address-lookup/address-lookup.spec.js
@@ -681,7 +681,6 @@ function setupMocks({
},
],
router: {
- navigate: jest.fn(),
navigate: jest.fn(),
navigateWithSaving: jest.fn(),
navigateWithoutSaving: jest.fn(),
diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue
index fe3b00320..48ab0dd08 100644
--- a/src/layouts/address-lookup/address-lookup.vue
+++ b/src/layouts/address-lookup/address-lookup.vue
@@ -323,10 +323,6 @@ export default {
registrationInfo: {
firstName: this.customerQuestions.firstName,
lastName: this.customerQuestions.lastName,
- address: this.customerQuestions.addressQuestions.streetAddress,
- city: this.customerQuestions.addressQuestions.city,
- state: resultMap.serviceZipValidationResponse.state,
- zipCode: this.customerQuestions.addressQuestions.zipCode,
},
},
false
diff --git a/src/layouts/customer-details/customer-details.vue b/src/layouts/customer-details/customer-details.vue
index be533117f..55e1b01b8 100644
--- a/src/layouts/customer-details/customer-details.vue
+++ b/src/layouts/customer-details/customer-details.vue
@@ -25,14 +25,14 @@
validationRules="email-address-required|email-address-format" />
+ v-model="isSmsOptIn" />
-
+
diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue
index 49ff8ff26..326215243 100644
--- a/src/layouts/license-plate-lookup/license-plate-lookup.vue
+++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue
@@ -292,8 +292,6 @@ export default {
vehicleInfo: Object.assign(vinLookup.data.vehicle, { vin: vinLookup.data.vin }),
registrationInfo: {
licensePlate: this.licensePlate,
- state: resultMap.registrationZipValidationResponse.state,
- zipCode: this.registrationZipCode,
},
},
false
diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js
index 6895b5d0b..b4a3df9fb 100644
--- a/src/layouts/quote/quote.spec.js
+++ b/src/layouts/quote/quote.spec.js
@@ -263,6 +263,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: null,
},
+ serviceLocation: {
+ state: null,
+ },
},
};
wrapper.vm.$route = { query: { isInsurance: "true" } };
@@ -290,6 +293,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: null,
},
+ serviceLocation: {
+ state: null,
+ },
},
};
wrapper.vm.$route = { query: { isInsurance: "false" } };
@@ -317,6 +323,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: true,
},
+ serviceLocation: {
+ state: null,
+ },
},
};
// Ensure that query param isn't overriding selection
@@ -345,6 +354,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: false,
},
+ serviceLocation: {
+ state: null,
+ },
},
};
// Ensure that query param isn't overriding selection
@@ -374,6 +386,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: null, // Ensure that previous selection isn't overriding selection
},
+ serviceLocation: {
+ state: null,
+ },
},
};
mockTierOnePrice = 200;
@@ -404,6 +419,9 @@ describe("quote.vue", () => {
payment: {
isInsurance: null, // Ensure that previous selection isn't overriding selection
},
+ serviceLocation: {
+ state: null,
+ },
},
};
mockTierOnePrice = 505;
@@ -421,6 +439,33 @@ describe("quote.vue", () => {
//Assert
expect(wrapper.vm.isInsuranceSelected).toBe(true);
});
+ test("Should default to insurence if user Service zip is from certain States", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ store.getters = {
+ order: {
+ lineItems: {
+ glassParts: ["item", "item2"],
+ },
+ payment: {
+ isInsurance: null,
+ },
+ serviceLocation: {
+ state: "AZ",
+ },
+ },
+ };
+ wrapper.vm.$route = { query: null };
+ //Act
+ await quote.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "quote" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+ //Assert
+ expect(wrapper.vm.isInsuranceSelected).toBe(true);
+ });
});
function setupMocks({ customMountOptions }) {
diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue
index b17b0f3ac..72d519028 100644
--- a/src/layouts/quote/quote.vue
+++ b/src/layouts/quote/quote.vue
@@ -67,7 +67,7 @@ import { errorMessages } from "@/constants/error-messages";
import { Form, defineRule } from "vee-validate";
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import { applicationConfig } from "@/constants/application-config";
-
+import { payWithInsuranceStates } from "@/constants/pay-with-insurance-states";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
export default {
@@ -154,11 +154,18 @@ export default {
);
},
getDefaultIsInsuranceSelectedValue(availableLineItems) {
+ const serviceLocationState = store.getters.order.serviceLocation.state;
// Override if coming back from QuoteDetails. Remove override after Quote release
const isInsuranceOverrideValue = this.$route.query?.isInsurance;
const defaultIsInsuranceSelectedValue = this.$store.getters.order.payment.isInsurance;
- if (isInsuranceOverrideValue != null) {
+ //Default to Insurance Tab if user Service zip is from certain States
+ if (
+ serviceLocationState != null &&
+ payWithInsuranceStates.find((item) => item === serviceLocationState)
+ )
+ return true;
+ else if (isInsuranceOverrideValue != null) {
return isInsuranceOverrideValue == "true";
} else if (defaultIsInsuranceSelectedValue != null) {
return defaultIsInsuranceSelectedValue;
diff --git a/src/layouts/quote/service-package-question/service-package-question.spec.js b/src/layouts/quote/service-package-question/service-package-question.spec.js
index af04ff36a..dc0d2005c 100644
--- a/src/layouts/quote/service-package-question/service-package-question.spec.js
+++ b/src/layouts/quote/service-package-question/service-package-question.spec.js
@@ -135,64 +135,9 @@ describe("service-package-question.vue", () => {
expectedModifiedAnswers[packageNameKey].tierThree
);
});
- it("should not select a default package if ANY glass part or supporting item has no prices", async () => {
+ it("should not select a default package if isInsurance is null", async () => {
// Note, only the first WSREPAIR item has a 0 for laborAmount, this is enough to not try and select a default package
- const wrapper = setupMocks({
- mountOptionsMockData: {
- store: {
- getters: {
- lineItems: {
- glassParts: [
- {
- partNumber: "FW02627GBYNOEE",
- description: "solar, 3rd visor band",
- color: "Green Tint, Blue Shade",
- partType: "WINDSHIELD",
- canSafeliteRecalibrate: false,
- requiresRecalibration: false,
- requiresCapabilityQuestions: false,
- recalibrationType: null,
- childParts: null,
- laborAmount: 5.0,
- },
- ],
- supportingItems: [
- {
- partNumber: "SUPPLIES-REPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- ],
- },
- order: {
- damage: {
- isRepair: false,
- glassToReplace: [{ glassLocation: "Windshield" }],
- },
- },
- },
- },
- },
- });
+ const wrapper = setupMocks({});
// Act
wrapper.setProps({ availableLineItems: null });
@@ -202,59 +147,24 @@ describe("service-package-question.vue", () => {
// Assert
expect(wrapper.vm.selectedPackageName).toBe(null);
});
- it("should select a default package if ALL glass parts and supporting items have prices", async () => {
+ it("should select a default package if isInsurance is NOT null", async () => {
const wrapper = setupMocks({
mountOptionsMockData: {
store: {
getters: {
- lineItems: {
- glassParts: [
- {
- partNumber: "FW02627GBYNOEE",
- description: "solar, 3rd visor band",
- color: "Green Tint, Blue Shade",
- partType: "WINDSHIELD",
- canSafeliteRecalibrate: false,
- requiresRecalibration: false,
- requiresCapabilityQuestions: false,
- recalibrationType: null,
- childParts: null,
- laborAmount: 5.0,
- },
- ],
- supportingItems: [
- {
- partNumber: "SUPPLIES-REPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- {
- partNumber: "WSREPAIR",
- description: null,
- partType: "REPAIR FEE",
- laborAmount: 5.0,
- },
- ],
- },
order: {
damage: {
isRepair: false,
glassToReplace: [{ glassLocation: "Windshield" }],
},
},
+ lineItems: {
+ vaps: [],
+ },
+ hasAnyNonWindshieldGlassParts: false,
+ payment: {
+ isInsurance: false,
+ },
},
},
},
@@ -329,6 +239,9 @@ describe("service-package-question.vue", () => {
glassToReplace: [{ glassLocation: "Windshield" }],
},
},
+ payment: {
+ isInsurance: false,
+ },
},
},
},
@@ -758,6 +671,9 @@ function setupMocks({ mountOptionsMockData, props = mockProps }) {
},
},
hasAnyNonWindshieldGlassParts: false,
+ payment: {
+ isInsurance: null,
+ },
},
},
};
diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue
index 51598631b..e3a4a499a 100644
--- a/src/layouts/quote/service-package-question/service-package-question.vue
+++ b/src/layouts/quote/service-package-question/service-package-question.vue
@@ -49,7 +49,7 @@ export default {
},
watch: {
availableLineItems() {
- if (this.allGlassPartsAndSupportingItemsHavePrices(this.$store.getters.lineItems)) {
+ if (this.$store.getters.payment.isInsurance != null) {
this.selectDefaultPackage();
}
},
@@ -196,30 +196,6 @@ export default {
vapsFromStore
);
},
- allGlassPartsAndSupportingItemsHavePrices(lineItems) {
- if (lineItems?.glassParts) {
- for (let i = 0; i < lineItems.glassParts.length; i++) {
- if (this.priceIsNullOrZero(lineItems.glassParts[i])) {
- return false;
- }
- }
- }
- if (lineItems?.supportingItems) {
- for (let i = 0; i < lineItems.supportingItems.length; i++) {
- if (this.priceIsNullOrZero(lineItems.supportingItems[i])) {
- return false;
- }
- }
- }
- return true;
- },
- priceIsNullOrZero(lineItem) {
- return (
- (lineItem.kitPrice == null || lineItem.kitPrice == 0) &&
- (lineItem.laborAmount == null || lineItem.laborAmount == 0) &&
- (lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
- );
- },
getVapsLineItemsForSelectedPackage(packageName) {
const packageContentTypes = getPackageContents(
this.glassToReplace,
diff --git a/src/layouts/review/review-block/review-block.vue b/src/layouts/review/review-block/review-block.vue
index 67e639da9..497aa3634 100644
--- a/src/layouts/review/review-block/review-block.vue
+++ b/src/layouts/review/review-block/review-block.vue
@@ -3,6 +3,7 @@
{
+ beforeEach(() => {
+ cmsContent = {};
+ });
+
+ describe("Submit", () => {
+ test("Should push to store if a field has changed", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ wrapper.vm.onModalOpened();
+
+ wrapper.vm.firstName = testConstants.newValues.firstName;
+
+ await wrapper.vm.setContactDetails();
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
+ expect(wrapper.vm.closeModal).toHaveBeenCalled();
+ });
+
+ test("Should not push to store if no fields have changed", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ wrapper.vm.onModalOpened();
+
+ await wrapper.vm.setContactDetails();
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.dispatchStoreAction).not.toHaveBeenCalled();
+ expect(wrapper.vm.closeModal).toHaveBeenCalled();
+ });
+ });
+
+ describe("Default values", () => {
+ test("Should populate on open", () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ wrapper.vm.onModalOpened();
+
+ // Assert
+ expect(wrapper.vm.firstName).toBe(testConstants.previousCustomerValues.firstName);
+ expect(wrapper.vm.lastName).toBe(testConstants.previousCustomerValues.lastName);
+ expect(wrapper.vm.emailAddress).toBe(testConstants.previousCustomerValues.emailAddress);
+ expect(wrapper.vm.phoneNumber).toBe(testConstants.previousCustomerValues.phoneNumber);
+ expect(wrapper.vm.isSmsOptIn).toBe(testConstants.previousCustomerValues.isSmsOptIn);
+ });
+
+ test("Should replace old values on open", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ wrapper.vm.firstName = testConstants.newValues.firstName;
+ wrapper.vm.lastName = testConstants.newValues.lastName;
+ wrapper.vm.emailAddress = testConstants.newValues.emailAddress;
+ wrapper.vm.phoneNumber = testConstants.newValues.phoneNumber;
+ wrapper.vm.isSmsOptIn = testConstants.newValues.isSmsOptIn;
+
+ wrapper.vm.onModalOpened();
+
+ // Assert
+ expect(wrapper.vm.firstName).toBe(testConstants.previousCustomerValues.firstName);
+ expect(wrapper.vm.lastName).toBe(testConstants.previousCustomerValues.lastName);
+ expect(wrapper.vm.emailAddress).toBe(testConstants.previousCustomerValues.emailAddress);
+ expect(wrapper.vm.phoneNumber).toBe(testConstants.previousCustomerValues.phoneNumber);
+ expect(wrapper.vm.isSmsOptIn).toBe(testConstants.previousCustomerValues.isSmsOptIn);
+ });
+ });
+});
+
+function generateDefaultProps() {
+ return {
+ previousCustomerValues: {
+ firstName: testConstants.previousCustomerValues.firstName,
+ lastName: testConstants.previousCustomerValues.lastName,
+ emailAddress: testConstants.previousCustomerValues.emailAddress,
+ phoneNumber: testConstants.previousCustomerValues.phoneNumber,
+ isSmsOptIn: testConstants.previousCustomerValues.isSmsOptIn,
+ },
+ };
+}
+
+function setupMocks(customMountOptions) {
+ const mountOptions = getMountOptions(customMountOptions);
+
+ const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn((widgetName, cmsFieldName) => {
+ return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
+ }),
+ },
+ };
+
+ mountOptions.global.mixins = [mockMixin];
+
+ const wrapper = shallowMount(customerDetailsModalQuestion, mountOptions);
+ wrapper.vm.setCmsContent = jest.fn();
+ wrapper.vm.openModal = jest.fn();
+ wrapper.vm.closeModal = jest.fn();
+ wrapper.vm.dispatchStoreAction = jest.fn();
+ return { wrapper };
+}
diff --git a/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue b/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue
new file mode 100644
index 000000000..0b08abee7
--- /dev/null
+++ b/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.vue
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
diff --git a/src/layouts/review/review-sections/customer-review/customer-review.spec.js b/src/layouts/review/review-sections/customer-review/customer-review.spec.js
new file mode 100644
index 000000000..1bcbbe83b
--- /dev/null
+++ b/src/layouts/review/review-sections/customer-review/customer-review.spec.js
@@ -0,0 +1,159 @@
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+
+import customerReview from "@/layouts/review/review-sections/customer-review/customer-review";
+
+const testConstants = {
+ cms: {
+ header: {
+ text: "Header",
+ },
+ sms: {
+ template: "Test {custom:smsOptInJoiner}",
+ expected: {
+ ifTrue: "Test in to",
+ ifFalse: "Test out of",
+ },
+ },
+ },
+ customer: {
+ firstName: "First",
+ lastName: "Last",
+ phoneNumber: "111-111-1111",
+ emailAddress: "builddigitaltest@safelite.com",
+ isSmsOptIn: false,
+ },
+ displayContent: {
+ fullName: "First Last",
+ phoneNumber: "111-111-1111",
+ emailAddress: "builddigitaltest@safelite.com",
+ smsOptIn: "Test out of",
+ },
+};
+
+let cmsContent;
+
+describe("Customer Review Block", () => {
+ beforeEach(() => {
+ cmsContent = {
+ CustomerWidget: {
+ HeaderText: testConstants.cms.header.text,
+ SubheaderText: testConstants.cms.sms.template,
+ },
+ };
+ });
+
+ test("Should display header text from cms", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.header).toEqual(testConstants.cms.header.text);
+ });
+
+ describe("SMS Opt In Text", () => {
+ test("Should render correctly when opt in is true:", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+ props.customer.isSmsOptIn = true;
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifTrue);
+ });
+ test("Should render correctly when opt in is false:", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+ props.customer.isSmsOptIn = false;
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifFalse);
+ });
+ test("Should render correctly when opt in is null:", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+ props.customer.isSmsOptIn = null;
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.expected.ifFalse);
+ });
+ });
+
+ test("Should render correct display content", async () => {
+ // Arrange
+ let props = generateDefaultProps();
+
+ const { wrapper } = setupMocks({
+ propsData: props,
+ });
+
+ // Act
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.displayContent).toEqual([
+ testConstants.displayContent.fullName,
+ testConstants.displayContent.emailAddress,
+ testConstants.displayContent.phoneNumber,
+ testConstants.displayContent.smsOptIn,
+ ]);
+ });
+});
+
+function generateDefaultProps() {
+ return {
+ cmsWidgetName: "CustomerWidget",
+ customer: {
+ firstName: testConstants.customer.firstName,
+ lastName: testConstants.customer.lastName,
+ phoneNumber: testConstants.customer.phoneNumber,
+ emailAddress: testConstants.customer.emailAddress,
+ isSmsOptIn: testConstants.customer.isSmsOptIn,
+ },
+ };
+}
+
+function setupMocks(customMountOptions) {
+ const mountOptions = getMountOptions(customMountOptions);
+
+ const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn((widgetName, cmsFieldName) => {
+ return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
+ }),
+ },
+ };
+
+ mountOptions.global.mixins = [mockMixin];
+
+ const wrapper = shallowMount(customerReview, mountOptions);
+ wrapper.vm.setCmsContent = jest.fn();
+ return { wrapper };
+}
diff --git a/src/layouts/review/review-sections/customer-review/customer-review.vue b/src/layouts/review/review-sections/customer-review/customer-review.vue
new file mode 100644
index 000000000..d8777d9e4
--- /dev/null
+++ b/src/layouts/review/review-sections/customer-review/customer-review.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
diff --git a/src/layouts/review/review-sections/schedule-review/schedule-review.vue b/src/layouts/review/review-sections/schedule-review/schedule-review.vue
new file mode 100644
index 000000000..b95ae5b88
--- /dev/null
+++ b/src/layouts/review/review-sections/schedule-review/schedule-review.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
diff --git a/src/layouts/review/review-sections/service-location-review/service-location-review.vue b/src/layouts/review/review-sections/service-location-review/service-location-review.vue
index db4f8188a..0da8361c3 100644
--- a/src/layouts/review/review-sections/service-location-review/service-location-review.vue
+++ b/src/layouts/review/review-sections/service-location-review/service-location-review.vue
@@ -10,7 +10,7 @@ import reviewBlock from "@/layouts/review/review-block/review-block";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
export default {
- name: "service-package-review",
+ name: "service-location-review",
props: {
cmsWidgetName: String,
serviceLocation: Object,
diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue
index 59320bce9..fe14e8f7e 100644
--- a/src/layouts/review/review.vue
+++ b/src/layouts/review/review.vue
@@ -10,13 +10,13 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/schedule/helpers/schedule-helper.js b/src/layouts/schedule/helpers/schedule-helper.js
index 82c756b5b..0f595b435 100644
--- a/src/layouts/schedule/helpers/schedule-helper.js
+++ b/src/layouts/schedule/helpers/schedule-helper.js
@@ -45,3 +45,33 @@ export function sumDateString(dateString, daysToAdd) {
date.setDate(date.getDate() + daysToAdd);
return convertDateToDateString(date);
}
+
+export function militaryToTwelveHourTime(timeString) {
+ // Expected input: "HH:MM"
+ if (typeof timeString !== "string") return;
+ let hours = parseInt(timeString.split(":")[0]);
+ const minutes = timeString.split(":")[1];
+ const meridianNotation = hours > 11 ? "PM" : "AM";
+
+ if (hours > 12) {
+ hours -= 12;
+ }
+
+ return `${hours}:${minutes} ${meridianNotation}`;
+}
+
+export function getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
+ const isLongAppointment = durationMaximum >= 120;
+ const isDurationRange = durationMinimum !== durationMaximum;
+
+ const adjustedMinimum = isLongAppointment ? durationMinimum / 60 : durationMinimum;
+ const adjustedMaximum = isLongAppointment ? durationMaximum / 60 : durationMaximum;
+
+ const durationText = isDurationRange
+ ? `${adjustedMinimum} - ${adjustedMaximum}`
+ : adjustedMinimum;
+
+ const unitText = isLongAppointment ? "hours" : "minutes";
+
+ return `${durationText} ${unitText}`;
+}
diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js
index 2c4bafc33..b47036c10 100644
--- a/src/layouts/schedule/schedule.spec.js
+++ b/src/layouts/schedule/schedule.spec.js
@@ -1,15 +1,77 @@
+// Components
+import schedule from "@/layouts/schedule/schedule.vue";
+
+// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import { applicationConfig } from "@/constants/application-config";
-import { storeActions } from "@/constants/store-actions";
-import schedule from "@/layouts/schedule/schedule.vue";
import store from "@/store";
-import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
+import router from "@/router";
import { nextTick } from "vue";
+import baseMixin from "../../mixins/base-mixin";
-jest.mock("@/store", () => ({
- commit: jest.fn(),
- dispatch: jest.fn(),
+// Mock basemixin
+jest.mock("@/mixins/base-mixin.js", () => ({
+ methods: {
+ dispatchStoreAction: jest.fn().mockImplementation((storeAction) => {
+ if (storeAction === "getShopTimeSlots") {
+ return {
+ 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,
+ },
+ ],
+ },
+ ],
+ },
+ };
+ }
+ if (storeAction === "getMobilePremiumFee") {
+ return Promise.resolve({
+ data: {
+ partNumber: "EARLY BIRD",
+ description: null,
+ partType: "EARLY BIRD",
+ laborAmount: 0,
+ sellingPrice: 14.99,
+ kitPrice: 0,
+ },
+ });
+ }
+ 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,
+ },
+ ]);
+ }
+ }),
+ },
}));
// Mock fetchCmsContentForPage
@@ -18,50 +80,402 @@ jest.mock("@/helpers/cms-content-helper", () => ({
splitCopyOnCMSPlaceHolder: jest.fn(() => ["A", "B"]),
}));
-jest.mock(
- "@/store",
- () => {
- return {};
- },
- { virtual: true }
-);
-
-store.getters = {
- order: {
- schedule: {
- date: "2020-01-01",
+beforeEach(() => {
+ jest.restoreAllMocks();
+ jest.clearAllMocks();
+ store.getters = {
+ order: {
+ schedule: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: "000",
+ },
+ lineItems: {
+ glassParts: [
+ {
+ partNumber: "ABC123",
+ },
+ ],
+ supportingItems: [],
+ },
+ serviceLocation: {
+ appointmentType: "Inshop",
+ zipCode: "12345",
+ zipCodeCtu: "01234",
+ provider: {
+ providerNumber: "123",
+ },
+ },
+ damage: {
+ isRepair: false,
+ },
+ referralNumber: "1234567",
+ },
+ payment: {
+ isInsurance: true,
},
lineItems: {
glassParts: [],
supportingItems: [],
},
- serviceLocation: {
- appointmentType: "Inshop",
- },
- },
- lineItems: {
- glassParts: [],
- supportingItems: [],
- },
-};
+ };
+});
+afterEach(() => {
+ store.getters = {};
+ jest.restoreAllMocks();
+ jest.clearAllMocks();
+});
-describe("schedule.vue", () => {
- test("Should navigateWithoutSaving", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- customMountOptions: {
- router: {
- navigateWithSaving: jest.fn(),
- },
- route: { schedule },
- },
+describe("schedule.vue...", () => {
+ describe("initial load", () => {
+ test("should pass arePagePrerequisitesValid with a mobile order and no providerNumber", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ store.getters.order.serviceLocation.appointmentType = "Mobile";
+ store.getters.order.serviceLocation.provider = null;
+
+ //Act
+ const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+
+ //Assert
+ expect(arePagePrerequisitesValid).toBe(true);
+ });
+ test("should pass arePagePrerequisitesValid with a inshop order and providerNumber", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+
+ //Assert
+ expect(arePagePrerequisitesValid).toBe(true);
+ });
+ test("should fail arePagePrerequisitesValid with a replace with no glass parts", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ store.getters.order.lineItems.glassParts = [];
+
+ //Act
+ const arePagePrerequisitesValid2 = await wrapper.vm.arePagePrerequisitesValid();
+
+ //Assert
+ expect(arePagePrerequisitesValid2).toBe(false);
+ });
+ test("should fail arePagePrerequisitesValid without isInsurance", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ store.getters.payment.isInsurance = null;
+
+ //Act
+ const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+
+ //Assert
+ expect(arePagePrerequisitesValid).toBe(false);
});
+ test("should return newShopTimeSlots when getAvailableDatesMethod is called", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+
+ //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 day ranges of 34 or less when getAvailableDatesMethod is called with large date ranges", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+
+ //Act
+ await wrapper.vm.getAvailableDates.call(
+ wrapper.vm,
+ "2023-01-01",
+ "2023-03-31",
+ "Inshop",
+ "123"
+ );
+
+ //Assert
+ expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledTimes(3);
+ expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(
+ "getShopTimeSlots",
+ expect.anything(),
+ expect.anything()
+ );
+ });
+
+ describe("beforeRouteEnter function... ", () => {
+ test("should call next() and call all functions within next", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+ wrapper.vm.updateFooterButtonText = jest.fn();
+ const nextFunction = jest.fn((c) => {
+ c(wrapper.vm);
+ });
+
+ //Act
+ await schedule.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "schedule" } },
+ undefined,
+ nextFunction
+ );
+
+ //Assert
+ expect(nextFunction).toHaveBeenCalled();
+ expect(wrapper.vm.setCmsContent).toHaveBeenCalledWith("content");
+ expect(wrapper.vm.$refs.datePicker.initializeComponent).toHaveBeenCalledWith(
+ expect.objectContaining({
+ calendarViewDirection: "future",
+ })
+ );
+ expect(wrapper.vm.$refs.locationAlerts.initializeComponent).toHaveBeenCalled();
+ expect(wrapper.vm.selectableDatesData).toStrictEqual(
+ expect.objectContaining({
+ days: expect.any(Array),
+ estimatedServiceMinutesMaximum: expect.any(Number),
+ estimatedServiceMinutesMinimum: expect.any(Number),
+ })
+ );
+ expect(wrapper.vm.mobilePremiumAppointmentFee).toStrictEqual(
+ expect.objectContaining({
+ partNumber: expect.any(String),
+ })
+ );
+ expect(wrapper.vm.updateFooterButtonText).toHaveBeenCalled();
+ });
+ });
+
+ describe("computed properties...", () => {
+ test("timeSlotsForSelectedDate should return timeslots if selected date is available", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [
+ {
+ date: "2022-11-11",
+ timeSlots: [
+ {
+ id: "1820I-01820-M-I*20425*AM",
+ startTime: "08:00",
+ endTime: "12:00",
+ offerPremium: true,
+ },
+ {
+ id: "1820I-01820-M-I*20425*PM",
+ startTime: "12:00",
+ endTime: "17:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ],
+ };
+ wrapper.setData({
+ selectedDate: "2022-11-11",
+ });
+
+ //Act
+ const testValue = wrapper.vm.timeSlotsForSelectedDate;
+
+ //Assert
+ expect(testValue).toStrictEqual(
+ expect.objectContaining({
+ date: "2022-11-11",
+ })
+ );
+ });
+
+ test("timeSlotsForSelectedDate should be null if no date has been selected", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [
+ {
+ date: "2022-11-11",
+ timeSlots: [
+ {
+ id: "1820I-01820-M-I*20425*AM",
+ startTime: "08:00",
+ endTime: "12:00",
+ offerPremium: true,
+ },
+ {
+ id: "1820I-01820-M-I*20425*PM",
+ startTime: "12:00",
+ endTime: "17:00",
+ offerPremium: false,
+ },
+ ],
+ },
+ ],
+ };
+ wrapper.setData({
+ selectedDate: undefined,
+ });
+
+ //Act
+ const testValue = wrapper.vm.timeSlotsForSelectedDate;
+
+ //Assert
+ expect(testValue).toBe(null);
+ });
+ });
+ });
+
+ describe("schedule page methods...", () => {
+ test("getServiceZipCtuCodeFromStore should return zipCodeCtu", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+
+ //Act
+ const testValue = wrapper.vm.getServiceZipCtuCodeFromStore();
+
+ //Assert
+ expect(testValue).toStrictEqual("01234");
+ });
+
+ test("openInshopTimeSlotsModal should trigger openModal method", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+
+ //Act
+ wrapper.vm.openInshopTimeSlotsModal();
+
+ //Assert
+ 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", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+ wrapper.setData({
+ selectedDate: "1980-05-05",
+ });
+ wrapper.setData({
+ selectedTimeSlot: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: null,
+ },
+ });
+
+ //Act
+ wrapper.vm.timeSlotModalClosed();
+
+ //Assert
+ expect(wrapper.vm.selectedDate).toBe(null);
+ });
+
+ test("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ 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("getDisplayTextForMilitaryTime should return the correctly formatted string", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.selectableDatesData = {
+ days: [],
+ };
+ wrapper.vm.$router.navigateWithoutSaving = jest.fn();
+ wrapper.vm.$route = "testRoute";
+
+ //Act
+ wrapper.vm.backButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
+ "CLICKED_BACK",
+ "testRoute"
+ );
+ });
+ });
+
+ test("forwardButtonAction should call route method navigateWithoutSaving", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
wrapper.vm.dispatchStoreAction = jest.fn(() => {
return {
data: [],
};
});
+ wrapper.vm.$router.navigateWithSaving = jest.fn(() => {
+ return {};
+ });
//Act
await wrapper.vm.forwardButtonAction();
@@ -69,136 +483,123 @@ describe("schedule.vue", () => {
//Assert
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
});
- test("should pass arePagePrerequisitesValid with a mobile order and no providerNumber", () => {
+
+ test("for mobile appts, updateSupportingItems should call store action to save supporting items", async () => {
//Arrange
+ store.getters.order.serviceLocation.appointmentType = "Mobile";
+ store.getters.lineItems.supportingItems = [
+ {
+ partNumber: "EARLY BIRD",
+ description: null,
+ partType: "EARLY BIRD",
+ laborAmount: 0,
+ sellingPrice: 0,
+ kitPrice: 0,
+ },
+ ];
const { wrapper } = setupMocks({});
- store.getters = {
- order: {
- schedule: {
- date: "2020-01-01",
- },
- serviceLocation: {
- zipCode: "12345",
- zipCodeCtu: "value",
- appointmentType: "Mobile",
- },
- damage: {
- isRepair: true,
- },
- referralNumber: "1234567",
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ wrapper.vm.mobilePremiumAppointmentFee = 14.99;
+ wrapper.setData({
+ selectedTimeSlot: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: null,
+ isPremiumAppointment: true,
},
- payment: {
- isInsurance: true,
- },
- lineItems: {
- supportingItems: [],
- },
- };
+ });
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+ //Act
+ await wrapper.vm.updateSupportingItems();
- expect(arePagePrerequisitesValid).toBe(true);
+ //Assert
+ expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
+ "saveSupportingItemsSuppressingStateResetting",
+ expect.arrayContaining([
+ expect.objectContaining({
+ partType: "EARLY BIRD",
+ }),
+ ]),
+ expect.anything()
+ );
});
- test("should pass arePagePrerequisitesValid with a inshop order and providerNumber", () => {
+
+ test("for Inshop appts, updateSupportingItems should call store action to save supporting items WITHOUT the EARLY BIRD supporting item", async () => {
//Arrange
+ store.getters.order.serviceLocation.appointmentType = "Inshop";
+ store.getters.lineItems.supportingItems = [
+ {
+ partNumber: "EARLY BIRD",
+ description: null,
+ partType: "EARLY BIRD",
+ laborAmount: 0,
+ sellingPrice: 0,
+ kitPrice: 0,
+ },
+ ];
const { wrapper } = setupMocks({});
- store.getters = {
- order: {
- schedule: {
- date: "2020-01-01",
- },
- serviceLocation: {
- zipCode: "12345",
- zipCodeCtu: "value",
- appointmentType: "Inshop",
- provider: {
- providerNumber: "5",
- },
- },
- damage: {
- isRepair: true,
- },
- referralNumber: "1234567",
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ wrapper.vm.mobilePremiumAppointmentFee = 14.99;
+ wrapper.setData({
+ selectedTimeSlot: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: null,
+ isPremiumAppointment: true,
},
- payment: {
- isInsurance: true,
- },
- lineItems: {
- supportingItems: [],
- },
- };
+ });
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+ //Act
+ await wrapper.vm.updateSupportingItems();
- expect(arePagePrerequisitesValid).toBe(true);
+ //Assert
+ expect(wrapper.vm.dispatchStoreAction).toBeCalledWith(
+ "saveSupportingItemsSuppressingStateResetting",
+ expect.not.arrayContaining([
+ expect.objectContaining({
+ partType: "EARLY BIRD",
+ }),
+ ]),
+ expect.anything()
+ );
});
- test("should fail arePagePrerequisitesValid with a replace with no glass parts", () => {
+
+ test("if no EARLY BIRD supporting item, then updateSupportingItems should NOT call store action", async () => {
//Arrange
+ store.getters.order.serviceLocation.appointmentType = "Mobile";
+ store.getters.lineItems.supportingItems = [];
const { wrapper } = setupMocks({});
- store.getters = {
- order: {
- schedule: {
- date: "2020-01-01",
- },
- serviceLocation: {
- zipCode: "12345",
- zipCodeCtu: "value",
- appointmentType: "Inshop",
- provider: {
- providerNumber: "5",
- },
- },
- damage: {
- isRepair: false,
- },
- referralNumber: "1234567",
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ wrapper.vm.mobilePremiumAppointmentFee = 14.99;
+ wrapper.setData({
+ selectedTimeSlot: {
+ date: "2019-01-01",
+ startTime: "09:00",
+ endTime: "10:00",
+ routeCode: null,
+ isPremiumAppointment: false,
},
- payment: {
- isInsurance: true,
- },
- lineItems: {
- supportingItems: [],
- glassParts: [],
- },
- };
+ });
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+ //Act
+ await wrapper.vm.updateSupportingItems();
- expect(arePagePrerequisitesValid).toBe(false);
- });
- test("should fail arePagePrerequisitesValid without isInsurance", () => {
- //Arrange
- const { wrapper } = setupMocks({});
- store.getters = {
- order: {
- schedule: {
- date: "2020-01-01",
- },
- serviceLocation: {
- zipCode: "12345",
- zipCodeCtu: "value",
- appointmentType: "Inshop",
- provider: {
- providerNumber: "5",
- },
- },
- damage: {
- isRepair: true,
- },
- referralNumber: "1234567",
- },
- payment: {
- isInsurance: null,
- },
- lineItems: {
- supportingItems: [],
- glassParts: [],
- },
- };
-
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
-
- expect(arePagePrerequisitesValid).toBe(false);
+ //Assert
+ expect(wrapper.vm.dispatchStoreAction).not.toBeCalled();
});
});
@@ -210,6 +611,7 @@ function setupMocks({ customMountOptions }) {
});
mountOptions.global.mocks["$store"] = store;
+ mountOptions.global.mocks["$router"] = router;
mountOptions["attachTo"] = document.body;
mountOptions.mixins = [
{
@@ -223,6 +625,12 @@ function setupMocks({ customMountOptions }) {
];
const wrapper = shallowMount(schedule, mountOptions);
+
wrapper.vm.setCmsContent = jest.fn();
+ wrapper.vm.$refs.datePicker.initializeComponent = jest.fn();
+ wrapper.vm.$refs.locationAlerts.initializeComponent = jest.fn();
+ wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
+ wrapper.vm.$refs.timeSlotModalQuestion.openModal = jest.fn();
+
return { wrapper };
}
diff --git a/src/layouts/schedule/schedule.spec.js1 b/src/layouts/schedule/schedule.spec.js1
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue
index 5bebe26fb..00b3e796b 100644
--- a/src/layouts/schedule/schedule.vue
+++ b/src/layouts/schedule/schedule.vue
@@ -320,6 +320,7 @@ export default {
);
return newShopTimeSlots;
},
+ getAvailableDates,
getServiceZipCtuCodeFromStore() {
return store.getters.order.serviceLocation.zipCodeCtu;
},
@@ -338,12 +339,6 @@ export default {
getSupportingItems() {
return store.getters.lineItems.supportingItems;
},
- isMobilePremiumFeeOnOrderInVuex() {
- const supportingItemsFromVuex = store.getters.lineItems.supportingItems;
- return !!supportingItemsFromVuex.filter(
- (lineItem) => lineItem.partType === PREMIUM_FEE_PART_TYPE
- ).length;
- },
timeSlotModalClosed() {
// Clear the selectedDate if no timeSlot has been selected
if (this.selectedTimeSlot.routeCode == null) {
@@ -459,6 +454,7 @@ export default {
startTime: null,
endTime: null,
jobMaxMinutes: null,
+ jobMinMinutes: null,
};
}
},
diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js
index 43d997892..93f8cfe01 100644
--- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js
+++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.spec.js
@@ -16,6 +16,7 @@ describe("time-slot-modal-list-button-question.vue", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const expectedEmit = [
[
{
@@ -24,6 +25,7 @@ describe("time-slot-modal-list-button-question.vue", () => {
startTime: startTime,
endTime: endTime,
jobMaxMinutes: jobMaxMinutes.toString(),
+ jobMinMinutes: jobMinMinutes.toString(),
},
],
];
@@ -32,6 +34,7 @@ describe("time-slot-modal-list-button-question.vue", () => {
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -163,11 +166,13 @@ describe("time-slot-modal-list-button-question.vue Supplemental information", ()
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -201,11 +206,13 @@ describe("time-slot-modal-list-button-question.vue Disclaimer", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -288,11 +295,13 @@ describe("time-slot-modal-list-button-question.vue Duration", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -434,11 +443,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -470,11 +481,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -506,11 +519,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00 AM";
const endTime = "8:30 AM";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -542,11 +557,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00";
const endTime = "8:30";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
@@ -578,11 +595,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00";
const endTime = "8:30";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
premiumAppointmentFee: {
partType: PREMIUM_FEE_PART_TYPE,
},
@@ -622,11 +641,13 @@ describe("time-slot-modal-list-button-question.vue Available Timeslots", () => {
const startTime = "8:00";
const endTime = "8:30";
const jobMaxMinutes = 100;
+ const jobMinMinutes = 50;
const { wrapper } = setupMocks({
customMountOptions: {
propsData: {
estimatedServiceMinutesMaximum: jobMaxMinutes,
+ estimatedServiceMinutesMinimum: jobMinMinutes,
dateAndTimeSlotData: {
date: date,
timeSlots: [
diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
index 724facf6c..cce2c0503 100644
--- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
+++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue
@@ -47,7 +47,11 @@ import buttonQuestion from "@/digital-components/button-question/button-question
import timeSlotModalListButton from "./time-slot-modal-list-button/time-slot-modal-list-button";
// Helpers
-import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
+import {
+ convertDateStringToDate,
+ militaryToTwelveHourTime,
+ getDisplayTextForDurationLength,
+} from "@/layouts/schedule/helpers/schedule-helper";
import { deepClone } from "@/helpers/object-helper";
// Validation - TODO: Move this somewhere more global?
@@ -88,6 +92,7 @@ export default {
startTime: null,
endTime: null,
jobMaxMinutes: null,
+ jobMinMinutes: null,
}),
},
cmsWidgetName: String,
@@ -263,7 +268,7 @@ export default {
cmsWidgetFieldMappings.DURATION
);
- const inshopDurationTime = this.getDisplayTextForDurationLength(
+ const inshopDurationTime = getDisplayTextForDurationLength(
this.estimatedServiceMinutesMinimum,
this.estimatedServiceMinutesMaximum
);
@@ -346,33 +351,6 @@ export default {
this.$emit("update:modelValue", this.selectedValue);
this.closeModal();
},
- getDisplayTextForMilitaryTime(militaryTimeInput) {
- // Expected input: "HH:MM"
- let hours = parseInt(militaryTimeInput.split(":")[0]);
- const minutes = militaryTimeInput.split(":")[1];
- const meridianNotation = hours > 11 ? "PM" : "AM";
-
- if (hours > 12) {
- hours -= 12;
- }
-
- return `${hours}:${minutes} ${meridianNotation}`;
- },
- getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
- const isLongAppointment = durationMaximum >= 120;
- const isDurationRange = durationMinimum !== durationMaximum;
-
- const adjustedMinimum = isLongAppointment ? durationMinimum / 60 : durationMinimum;
- const adjustedMaximum = isLongAppointment ? durationMaximum / 60 : durationMaximum;
-
- const durationText = isDurationRange
- ? `${adjustedMinimum} - ${adjustedMaximum}`
- : adjustedMinimum;
-
- const unitText = isLongAppointment ? "hours" : "minutes";
-
- return `${durationText} ${unitText}`;
- },
getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
selectedTimeSlotId,
isSameDayRelevant = false
@@ -387,7 +365,7 @@ export default {
},
getAvailableTimeSlotsForInshop(timeSlotsForSelectedDate) {
return timeSlotsForSelectedDate.map((timeSlot) => {
- const readableTime = this.getDisplayTextForMilitaryTime(timeSlot.startTime);
+ const readableTime = militaryToTwelveHourTime(timeSlot.startTime);
return {
value: timeSlot.id,
buttonLabel: readableTime,
@@ -415,9 +393,9 @@ export default {
},
getAvailableTimeSlotsForMobile(timeSlotsForSelectedDate) {
const availableTimeSlots = timeSlotsForSelectedDate.map((timeSlot) => {
- const readableTime = `${this.getDisplayTextForMilitaryTime(
+ const readableTime = `${militaryToTwelveHourTime(
timeSlot.startTime
- )} - ${this.getDisplayTextForMilitaryTime(timeSlot.endTime)}`;
+ )} - ${militaryToTwelveHourTime(timeSlot.endTime)}`;
return {
value: timeSlot.id,
buttonLabel: readableTime,
@@ -472,6 +450,7 @@ export default {
startTime: timeSlot.startTime,
endTime: timeSlot.endTime,
jobMaxMinutes: this.estimatedServiceMinutesMaximum.toString(),
+ jobMinMinutes: this.estimatedServiceMinutesMinimum.toString(),
};
}
@@ -481,6 +460,7 @@ export default {
endTime: null,
routeCode: null,
jobMaxMinutes: null,
+ jobMinMinutes: null,
};
},
},
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 30e144310..b26b5e31c 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -52,7 +52,6 @@ jest.mock("@/store", () => ({
damage: {
glassToReplace: [],
},
- order: { serviceLocation: { zipCode: "11111" } },
},
}));
@@ -134,7 +133,6 @@ describe("vehicle-damage.vue", () => {
getters: {
vehicle: {},
payment: { insuranceCoverage: { isVerified: false } },
- order: { serviceLocation: { zipCode: "11111" } },
},
},
},
@@ -177,7 +175,7 @@ describe("vehicle-damage.vue", () => {
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(
storeActions.GET_DAMAGE_OPTIONS,
- { carId: "C00000000", zipCode: "11111" }
+ { carId: "C00000000" }
);
});
@@ -243,7 +241,6 @@ describe("vehicle-damage.vue", () => {
getters: {
vehicle: {},
payment: { insuranceCoverage: { isVerified: false } },
- order: { serviceLocation: { zipCode: "11111" } },
},
},
},
@@ -273,7 +270,7 @@ describe("vehicle-damage.vue", () => {
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(
storeActions.GET_DAMAGE_OPTIONS,
- { carId: "C00000000", zipCode: "11111" }
+ { carId: "C00000000" }
);
});
});
@@ -526,7 +523,6 @@ describe("vehicle-damage.vue", () => {
eventBusItem: jest.fn(),
damage: { glassToReplace: [{ glassLocation: damageLocation }] },
isRepair: true,
- order: { serviceLocation: { zipCode: "11111" } },
};
var glassSelections = wrapper.vm.getDamageLocationsFromStore();
@@ -604,7 +600,6 @@ describe("vehicle-damage.vue", () => {
isRepair: isRepair,
numberOfChips: 2,
},
- order: { serviceLocation: { zipCode: "11111" } },
};
var windshieldSelections = wrapper.vm.getWindshieldOptionsFromStore();
@@ -641,7 +636,6 @@ describe("vehicle-damage.vue", () => {
glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
},
isRepair: true,
- order: { serviceLocation: { zipCode: "11111" } },
};
var glassSelections = wrapper.vm.getDriverSideReplaceOptionsFromStore();
@@ -678,7 +672,6 @@ describe("vehicle-damage.vue", () => {
glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
},
isRepair: true,
- order: { serviceLocation: { zipCode: "11111" } },
};
var glassSelections = wrapper.vm.getPassengerSideReplaceOptionsFromStore();
@@ -713,7 +706,6 @@ describe("vehicle-damage.vue", () => {
glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
},
isRepair: true,
- order: { serviceLocation: { zipCode: "11111" } },
};
var glassSelections = wrapper.vm.getRearReplaceOptionsFromStore();
@@ -746,7 +738,6 @@ describe("vehicle-damage.vue", () => {
getters: {
vehicle: {},
payment: { insuranceCoverage: { isVerified: true } },
- order: { serviceLocation: { zipCode: "11111" } },
},
},
},
@@ -787,7 +778,6 @@ function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCo
isVerified: false,
},
},
- order: { serviceLocation: { zipCode: "11111" } },
},
},
};
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index 6ea4fe81d..c03fabda1 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -81,7 +81,6 @@ import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
-import { queryStrings } from "@/constants/query-strings";
// DEFINE VALIDATION RULES
defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED));
@@ -90,20 +89,10 @@ export default {
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
- const queryString = window.location.search;
- const urlParams = new URLSearchParams(queryString);
- const lowerCaseParams = new URLSearchParams();
- for (const [name, value] of urlParams) {
- lowerCaseParams.append(name.toLowerCase(), value);
- }
-
- const zip = lowerCaseParams.get(queryStrings.ZIP_CODE)
- ? lowerCaseParams.get(queryStrings.ZIP_CODE)
- : store.getters.order.serviceLocation.zipCode;
const damageOptionsPromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_DAMAGE_OPTIONS,
- { carId: store.getters.vehicle.carId, zipCode: zip }
+ { carId: store.getters.vehicle.carId }
);
// Settle promises and get results
@@ -146,7 +135,6 @@ export default {
},
selectedWindshieldOptions: this.getWindshieldOptionsFromStore(),
selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore(),
- serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode,
};
},
mounted() {
@@ -169,18 +157,6 @@ export default {
true
);
}
- if (this.serviceZipCode) {
- this.pushEventToGA(
- this.GaCategories.FUNNEL_ENTRY,
- this.GaActions.ZIP_CODE_PROVIDED,
- this.serviceZipCode,
- true
- );
- }
- },
-
- getZipFromStore() {
- return this.$store.getters.order.serviceLocation.zipCode;
},
backButtonAction() {
diff --git a/src/layouts/vehicle-make/make-question/make-question.spec.js b/src/layouts/vehicle-make/make-question/make-question.spec.js
deleted file mode 100644
index 7025c118c..000000000
--- a/src/layouts/vehicle-make/make-question/make-question.spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import store from "@/store";
-jest.mock(
- "@/store",
- () => {
- return {};
- },
- { virtual: true }
-);
-
-describe("make-question.vue", () => {
- test("Selected make is emitted upon selection.", async () => {
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: "honda" });
- const makeToSelect = "ford";
-
- //Act
- wrapper.setValue({ selectedMake: makeToSelect });
- await wrapper.vm.$nextTick();
-
- //Assert
- expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedMake: "ford" }]);
- });
-});
-
-describe("make-question.vue", () => {
- test("Data from store api are used as radio question answers.", async () => {
- //Arrange
- const { wrapper, cmsContent } = setupMocks({
- dataFromStoreApi: ["honda", "ford", "dodge"],
- });
-
- //Act
- const initialData = makeQuestion.methods.loadInitialData.call(wrapper.vm);
- makeQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
-
- //Assert
- const buttonQuestionComponent = await wrapper.findComponent({
- name: "buttonQuestion",
- });
- expect(buttonQuestionComponent.attributes("answers")).toBe("honda,ford,dodge");
- });
-});
-
-function setupMocks({
- modelValueProp = "1900",
- cmsQuestionText = "CMS text goes here",
- dataFromStoreApi = [],
-}) {
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- store.getters = { vehicle: { year: 2019 } };
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- getters: store.getters,
- },
- });
-
- //Mock props
- const mockMixin = {
- methods: {
- getCmsContent: jest.fn(),
- },
- };
- mountOptions.propsData = {
- modelValue: modelValueProp,
- };
- mountOptions.mixins = [mockMixin];
- const wrapper = shallowMount(makeQuestion, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- QuestionText: cmsQuestionText,
- };
- return { wrapper, cmsContent };
-}
diff --git a/src/layouts/vehicle-make/make-question/make-question.vue b/src/layouts/vehicle-make/make-question/make-question.vue
deleted file mode 100644
index 2d3551c53..000000000
--- a/src/layouts/vehicle-make/make-question/make-question.vue
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js
deleted file mode 100644
index 3b169a9b9..000000000
--- a/src/layouts/vehicle-make/vehicle-make.spec.js
+++ /dev/null
@@ -1,228 +0,0 @@
-// Supporting Files
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { nextTick } from "vue";
-import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
-import baseMixin from "@/mixins/base-mixin.js";
-import store from "@/store";
-
-// Components
-import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
-import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
-
-jest.mock("@/store", () => ({
- commit: jest.fn(),
- dispatch: jest.fn(),
- // getters: jest.fn().mockImplementation(() => ({
- // vehicle: {
- // year: 2019,
- // },
- // })),
-}));
-
-// Mock fetchCmsContentForPage
-jest.mock("@/helpers/cms-content-helper", () => ({
- fetchCmsContentForPage: jest.fn(),
-}));
-
-// Mock our module for promises.
-jest.mock("@/helpers/layout-helper.js", () => ({
- settleAllPromises: jest.fn(),
-}));
-
-describe("vehicle-make.vue", () => {
- test("Make question component is initized with api data", async (done) => {
- //Arrange
- const makeQuestionInitialData = ["honda", "ford", "dodge"];
- const { wrapper, apiPromise } = setupMocks({
- makeQuestionInitialData: makeQuestionInitialData,
- });
-
- //Act
- vehicleMake.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-make" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- //Assert
- apiPromise.finally(() => {
- expect(makeQuestion.methods.initializeComponent).toHaveBeenCalledWith(
- makeQuestionInitialData
- );
- done();
- });
- });
-});
-
-describe("vehicle-make.vue", () => {
- test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
- //Arrange
- const { wrapper, apiPromise } = setupMocks({
- pageHeaderWidgetHeaderText: "Select a make to get started",
- mountOptionsMockData: {
- router: {
- navigate: jest.fn(),
- navigateWithoutSaving: jest.fn(),
- },
- },
- });
-
- //Act
- vehicleMake.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-make" } },
- undefined,
- (c) => c(wrapper.vm)
- );
- wrapper.vm.backButtonAction();
- await nextTick();
-
- //Assert
- apiPromise.finally(() => {
- expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
- done();
- });
- });
-});
-
-describe("vehicle-make.vue", () => {
- describe("arePagePrerequisitesValue", () => {
- test("Year set, arePagePrerequisitesValid should be true", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- vehicleData: {
- year: 2019,
- },
- });
-
- //Act
- vehicleMake.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-make" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
-
- //Assert
- expect(arePagePrerequisitesValid).toBe(true);
- });
-
- test("Year not set, arePagePrerequisitesValid should be false", async () => {
- //Arrange
- store.getters.vehicle.year = jest.fn().mockReturnValueOnce(undefined);
- const { wrapper } = setupMocks({});
-
- //Act
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
-
- //Assert
- expect(arePagePrerequisitesValid).toBe(false);
- });
- });
-
- test("selectedMake changes => save make in store", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- mountOptionsMockData: {
- router: {
- navigate: jest.fn(),
- navigateWithSaving: jest.fn(),
- },
- },
- });
-
- // Act
- await wrapper.setData({
- selectedMake: "Make",
- });
- await wrapper.vm.$nextTick();
-
- // Assert
- expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledTimes(1);
- expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith(
- "saveVehicleMake",
- "Make",
- false
- );
- });
-
- test("selectedMake changes => navigate with saving", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- mountOptionsMockData: {
- router: {
- navigate: jest.fn(),
- navigateWithSaving: jest.fn(),
- },
- route: {
- fmgPage: "test",
- },
- },
- });
-
- // Act
- await wrapper.setData({
- selectedMake: "Make",
- });
-
- // Assert
- expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
- expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(
- "SELECTED_MAKE",
- expect.anything()
- );
- });
-});
-
-function setupMocks({
- vehicleMakeQuestionCmsContent = {},
- makeQuestionInitialData = {},
- pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {},
- vehicleData = {},
-}) {
- //Mock api responses
- const apiResponses = {
- cmsContent: {
- FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
- VehicleMakeQuestion: vehicleMakeQuestionCmsContent,
- VehicleBannerWidget: {
- GenericVehicleImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
- },
- FunnelHeaderWidget: {
- LogoImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
- },
- },
- makeQuestionInitialData: makeQuestionInitialData,
- };
-
- const apiPromise = Promise.resolve(apiResponses);
-
- store.getters = {
- vehicle: vehicleData,
- };
-
- fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
- settleAllPromises.mockImplementation(() => apiPromise);
-
- //Mock make question methods
- makeQuestion.methods = {
- loadInitialData: jest.fn(),
- initializeComponent: jest.fn(),
- };
-
- const mountOptions = getMountOptions(mountOptionsMockData);
- const wrapper = shallowMount(vehicleMake, mountOptions);
- const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" });
- makeQuestionWrapper.vm.initializeComponent = makeQuestion.methods.initializeComponent;
- wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
-
- return { wrapper, apiPromise };
-}
diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue
deleted file mode 100644
index a50440e35..000000000
--- a/src/layouts/vehicle-make/vehicle-make.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-model/model-question/model-question.spec.js b/src/layouts/vehicle-model/model-question/model-question.spec.js
deleted file mode 100644
index 16ca638d9..000000000
--- a/src/layouts/vehicle-model/model-question/model-question.spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import store from "@/store";
-jest.mock(
- "@/store",
- () => {
- return {};
- },
- { virtual: true }
-);
-
-describe("model-question.vue", () => {
- test("Selected model is emitted upon selection.", async () => {
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: "Accord" });
- const modelToSelect = "Civic";
-
- //Act
- wrapper.setValue({ selectedModel: modelToSelect });
- await wrapper.vm.$nextTick();
-
- //Assert
- expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedModel: "Civic" }]);
- });
-});
-
-describe("model-question.vue", () => {
- test("Data from store api are used as radio question answers.", async () => {
- //Arrange
- const { wrapper, cmsContent } = setupMocks({
- dataFromStoreApi: ["accord", "civic", "insight"],
- });
-
- //Act
- const initialData = modelQuestion.methods.loadInitialData.call(wrapper.vm);
- modelQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
-
- //Assert
- const buttonQuestionComponent = await wrapper.findComponent({
- name: "buttonQuestion",
- });
- expect(buttonQuestionComponent.attributes("answers")).toBe("accord,civic,insight");
- });
-});
-
-function setupMocks({
- modelValueProp = "1900",
- cmsQuestionText = "CMS text goes here",
- dataFromStoreApi = [],
-}) {
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- store.getters = { vehicle: { year: 2019, make: "honda" } };
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- getters: store.getters,
- },
- });
-
- //Mock props
- const mockMixin = {
- methods: {
- getCmsContent: jest.fn(),
- },
- };
- mountOptions.propsData = {
- modelValue: modelValueProp,
- };
- mountOptions.mixins = [mockMixin];
- const wrapper = shallowMount(modelQuestion, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- QuestionText: cmsQuestionText,
- };
- return { wrapper, cmsContent };
-}
diff --git a/src/layouts/vehicle-model/model-question/model-question.vue b/src/layouts/vehicle-model/model-question/model-question.vue
deleted file mode 100644
index 5ca926abc..000000000
--- a/src/layouts/vehicle-model/model-question/model-question.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js
deleted file mode 100644
index 33b74482d..000000000
--- a/src/layouts/vehicle-model/vehicle-model.spec.js
+++ /dev/null
@@ -1,147 +0,0 @@
-// Components
-import vehicleModel from "@/layouts/vehicle-model/vehicle-model.vue";
-import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
-
-// Supporting files
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import { nextTick } from "vue";
-import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
-import baseMixin from "@/mixins/base-mixin.js";
-
-// Mock our module for promises.
-jest.mock("@/helpers/layout-helper.js", () => ({
- settleAllPromises: jest.fn(),
-}));
-
-// Mock fetchCmsContentForPage
-jest.mock("@/helpers/cms-content-helper", () => ({
- fetchCmsContentForPage: jest.fn(),
-}));
-
-// Mock Store
-jest.mock("@/store", () => ({
- commit: jest.fn(),
- dispatch: jest.fn(),
- getters: {
- vehicle: {
- make: "Acura",
- },
- },
-}));
-
-describe("vehicle-model.vue", () => {
- test("Model question component is initized with api data", async (done) => {
- //Arange
- const modelQuestionInitialData = ["accord", "civic", "insight"];
- const { wrapper, apiPromise } = setupMocks({
- modelQuestionInitialData: modelQuestionInitialData,
- });
- //Act
- vehicleModel.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-model" } },
- undefined,
- (c) => c(wrapper.vm)
- );
- //Assert
- apiPromise.finally(() => {
- expect(modelQuestion.methods.initializeComponent).toHaveBeenCalledWith(
- modelQuestionInitialData
- );
- done();
- });
- });
-});
-
-describe("vehicle-model.vue", () => {
- test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
- //Arrange
- const { wrapper, apiPromise } = setupMocks({
- pageHeaderWidgetHeaderText: "Select a model to get started",
- mountOptionsMockData: {
- router: {
- navigate: jest.fn(),
- navigateWithoutSaving: jest.fn(),
- },
- },
- });
- //Act
- vehicleModel.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-model" } },
- undefined,
- (c) => c(wrapper.vm)
- );
- wrapper.vm.backButtonAction();
- await nextTick();
- //Assert
- apiPromise.finally(() => {
- expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
- done();
- });
- });
-});
-describe("vehicle-model.vue", () => {
- test("Make set, arePagePrerequisitesValid should be true ", async () => {
- //Arrange
- const { wrapper } = setupMocks({});
-
- //Act
- vehicleModel.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-model" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
- await nextTick();
-
- //Assert
- expect(arePagePrerequisitesValid).toBe(true);
- });
-});
-
-function setupMocks({
- buttonQuestionContent = {},
- modelQuestionInitialData = {},
- pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {},
-}) {
- //Mock api responses
- const apiResponses = {
- cmsContent: {
- FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
- VehicleModelQuestion: buttonQuestionContent,
- VehicleBannerWidget: {
- GenericVehicleImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
- },
- FunnelHeaderWidget: {
- LogoImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
- },
- },
- modelQuestionInitialData: modelQuestionInitialData,
- };
- const apiPromise = Promise.resolve(apiResponses);
-
- settleAllPromises.mockImplementation(() => apiPromise);
- fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
-
- //Mock model question methods
- modelQuestion.methods = {
- loadInitialData: jest.fn(),
- initializeComponent: jest.fn(),
- };
- const mountOptions = getMountOptions(mountOptionsMockData);
- const wrapper = shallowMount(vehicleModel, mountOptions);
- wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
-
- const modelQuestionWrapper = wrapper.findComponent({ name: "modelQuestion" });
- modelQuestionWrapper.vm.initializeComponent = modelQuestion.methods.initializeComponent;
-
- return { wrapper, apiPromise };
-}
diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue
deleted file mode 100644
index d15c170c6..000000000
--- a/src/layouts/vehicle-model/vehicle-model.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-style/style-question/style-question.spec.js b/src/layouts/vehicle-style/style-question/style-question.spec.js
deleted file mode 100644
index c02301316..000000000
--- a/src/layouts/vehicle-style/style-question/style-question.spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import store from "@/store";
-jest.mock(
- "@/store",
- () => {
- return {};
- },
- { virtual: true }
-);
-
-describe("style-question.vue", () => {
- test("Selected style is emitted upon selection.", async () => {
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: "2 Door" });
- const styleToSelect = "4 Door";
-
- //Act
- wrapper.setValue({ selectedStyle: styleToSelect });
- await wrapper.vm.$nextTick();
-
- //Assert
- expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedStyle: "4 Door" }]);
- });
-});
-
-describe("style-question.vue", () => {
- test("Data from store api are used as radio question answers.", async () => {
- //Arrange
- const { wrapper, cmsContent } = setupMocks({
- dataFromStoreApi: ["2 Door", "4 Door"],
- });
-
- //Act
- const initialData = styleQuestion.methods.loadInitialData.call(wrapper.vm);
- styleQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
-
- //Assert
- const buttonQuestionComponent = await wrapper.findComponent({
- name: "buttonQuestion",
- });
- expect(buttonQuestionComponent.attributes("answers")).toBe("2 Door,4 Door");
- });
-});
-
-function setupMocks({
- modelValueProp = "1900",
- cmsQuestionText = "CMS text goes here",
- dataFromStoreApi = [],
-}) {
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- store.getters = { vehicle: { year: 2019, make: "honda", model: "civc" } };
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- getters: store.getters,
- },
- });
-
- //Mock props
- const mockMixin = {
- methods: {
- getCmsContent: jest.fn(),
- },
- };
- mountOptions.propsData = {
- modelValue: modelValueProp,
- };
- mountOptions.mixins = [mockMixin];
- const wrapper = shallowMount(styleQuestion, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- QuestionText: cmsQuestionText,
- };
- return { wrapper, cmsContent };
-}
diff --git a/src/layouts/vehicle-style/style-question/style-question.vue b/src/layouts/vehicle-style/style-question/style-question.vue
deleted file mode 100644
index 0bfd00f7c..000000000
--- a/src/layouts/vehicle-style/style-question/style-question.vue
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-style/vehicle-style.spec.js b/src/layouts/vehicle-style/vehicle-style.spec.js
deleted file mode 100644
index f7dacb6b4..000000000
--- a/src/layouts/vehicle-style/vehicle-style.spec.js
+++ /dev/null
@@ -1,256 +0,0 @@
-// Components
-import vehicleStyle from "@/layouts/vehicle-style/vehicle-style.vue";
-import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
-
-// Supporting files
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { nextTick } from "vue";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import { storeActions } from "@/constants/store-actions";
-import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
-import baseMixin from "@/mixins/base-mixin.js";
-import router from "@/router";
-import store from "@/store";
-import { storeMutations } from "@/constants/store-mutations";
-
-// Mock our module for promises.
-jest.mock("@/helpers/layout-helper.js", () => ({
- settleAllPromises: jest.fn(),
-}));
-
-// Mock fetchCmsContentForPage
-jest.mock("@/helpers/cms-content-helper", () => ({
- fetchCmsContentForPage: jest.fn(),
-}));
-
-// Mock fetchCmsContentForPage
-jest.mock("@/router", () => ({
- overrideNavigation: jest.fn(),
-}));
-
-describe("vehicle-style.vue", () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- test("Style question component is initized with api data", async (done) => {
- //Arrange
- const styleQuestionInitialData = ["2 Door", "4 Door"];
- const { wrapper, apiPromise } = setupMocks({
- styleQuestionInitialData: styleQuestionInitialData,
- });
-
- //Act
- vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- //Assert
- apiPromise.finally(() => {
- expect(styleQuestion.methods.initializeComponent).toHaveBeenCalledWith(
- styleQuestionInitialData
- );
- done();
- });
- });
-
- test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
- //Arrange
- const { wrapper, apiPromise } = setupMocks({
- pageHeaderWidgetHeaderText: "Select a style to get started",
- mountOptionsMockData: {
- router: {
- navigate: jest.fn(),
- navigateWithSaving: jest.fn(),
- navigateWithoutSaving: jest.fn(),
- },
- },
- });
-
- //Act
- vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
- wrapper.vm.backButtonAction();
- await nextTick();
-
- //Assert
- apiPromise.finally(() => {
- expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
- done();
- });
- });
-
- test("setVehicle triggers a dispatchStoreAction commit", async (done) => {
- //Arrange
- const { wrapper, apiPromise } = setupMocks({
- pageHeaderWidgetHeaderText: "Select a style to get started",
- mountOptionsMockData: {
- actionList: [
- {
- actionName: storeActions.SET_VEHICLE,
- data: "mockData",
- },
- ],
- },
- });
-
- //Act
- vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
- wrapper.vm.setVehicle();
- await nextTick();
-
- //Assert
- apiPromise.finally(() => {
- expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
- done();
- });
- });
-
- test("Model set, arePagePrerequisitesValid should be true ", async () => {
- //Arrange
- const { wrapper } = setupMocks({});
-
- //Act
- vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
- await nextTick();
-
- //Assert
- expect(arePagePrerequisitesValid).toBe(true);
- });
-
- test("there is only one vehicle style => autoselect and move to vehicle damage", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- styleQuestionInitialData: ["2 door sedan"],
- });
-
- // Act
- await vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- // Assert
- expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
- expect(router.overrideNavigation).toHaveBeenCalled();
- });
-
- test("there is only one vehicle style and vehicle-damage was visited => don't autoselect or move to vehicle damage", async () => {
- //Arrange
- const { wrapper } = setupMocks({
- styleQuestionInitialData: ["2 door sedan"],
- mountOptionsMockData: {
- store: {
- getters: {
- applicationUser: {
- pageData: {
- "part-questions": null,
- "vehicle-make": {},
- "vehicle-model": {},
- "vehicle-style": {},
- "vehicle-damage": {},
- },
- },
- },
- },
- },
- });
-
- // Act
- await vehicleStyle.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-style" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- // Assert
- expect(store.commit).not.toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
- expect(router.overrideNavigation).not.toHaveBeenCalled();
- });
-});
-
-function setupMocks({
- vehicleStyleQuestionCmsContent = {},
- styleQuestionInitialData = {},
- pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {},
-}) {
- //Mock api responses
- const apiResponses = {
- cmsContent: {
- FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
- VehicleStyleQuestion: vehicleStyleQuestionCmsContent,
- VehicleBannerWidget: {
- GenericVehicleImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
- },
- FunnelHeaderWidget: {
- LogoImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
- },
- },
- styleQuestionInitialData: styleQuestionInitialData,
- };
-
- const apiPromise = Promise.resolve(apiResponses);
-
- settleAllPromises.mockImplementation(() => apiPromise);
- fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
-
- //Mock style question methods
- styleQuestion.methods = {
- loadInitialData: jest.fn(),
- initializeComponent: jest.fn(),
- };
-
- store.commit = jest.fn();
- store.dispatch = jest.fn();
- store.getters = mountOptionsMockData.store?.getters ?? {
- vehicle: {
- model: "TL",
- },
- applicationUser: {
- pageData: {
- "part-questions": null,
- "vehicle-make": {},
- "vehicle-model": {},
- "vehicle-style": {},
- },
- },
- };
-
- const mountOptions = getMountOptions({
- ...mountOptionsMockData,
- store,
- });
- const wrapper = shallowMount(vehicleStyle, mountOptions);
- wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
-
- const styleQuestionWrapper = wrapper.findComponent({ name: "styleQuestion" });
- styleQuestionWrapper.vm.initializeComponent = styleQuestion.methods.initializeComponent;
-
- return { wrapper, apiPromise };
-}
diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue
deleted file mode 100644
index 2d2a4a534..000000000
--- a/src/layouts/vehicle-style/vehicle-style.vue
+++ /dev/null
@@ -1,137 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-year/vehicle-year.spec.js b/src/layouts/vehicle-year/vehicle-year.spec.js
deleted file mode 100644
index ad024f131..000000000
--- a/src/layouts/vehicle-year/vehicle-year.spec.js
+++ /dev/null
@@ -1,122 +0,0 @@
-import { shallowMount, flushPromises } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { nextTick } from "vue";
-import { storeMutations } from "@/constants/store-mutations";
-import { storeActions } from "@/constants/store-actions";
-import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
-import baseMixin from "@/mixins/base-mixin.js";
-
-import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
-import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
-
-import store from "@/store";
-
-jest.mock("@/store", () => ({
- commit: jest.fn(),
- dispatch: jest.fn(),
- getters: {
- applicationUser: {
- experiments: [],
- },
- },
-}));
-
-// Mock our module for promises.
-jest.mock("@/helpers/layout-helper.js", () => ({
- settleAllPromises: jest.fn(),
-}));
-
-// Mock fetchCmsContentForPage
-jest.mock("@/helpers/cms-content-helper", () => ({
- fetchCmsContentForPage: jest.fn(),
-}));
-
-describe("vehicle-year.vue", () => {
- test("Year question component is initized with api data", async (done) => {
- //Arrange
- const yearQuestionInitialData = ["2023", "2022", "2021"];
- const { wrapper, apiPromise } = setupMocks({
- yearQuestionInitialData: yearQuestionInitialData,
- });
-
- //Act
- vehicleYear.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-year" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- //Assert
- apiPromise.finally(() => {
- expect(yearQuestion.methods.initializeComponent).toHaveBeenCalledWith(
- yearQuestionInitialData
- );
- done();
- });
- });
-});
-
-describe("vehicle-year.vue", () => {
- test("arePagePrerequisitesValid should be true ", async () => {
- //Arrange
- const { wrapper } = setupMocks({});
-
- //Act
- vehicleYear.beforeRouteEnter.call(
- wrapper.vm,
- { query: { fmgPage: "vehicle-make" } },
- undefined,
- (c) => c(wrapper.vm)
- );
-
- let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
- await nextTick();
-
- //Assert
- expect(arePagePrerequisitesValid).toBe(true);
- });
-});
-
-function setupMocks({
- vehicleYearQuestionCmsContent = {},
- yearQuestionInitialData = {},
- pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {},
-}) {
- //Mock api responses
- const apiResponses = {
- cmsContent: {
- FunnelSubHeaderWidget: { HeaderText: pageHeaderWidgetHeaderText },
- VehicleYearQuestion: vehicleYearQuestionCmsContent,
- VehicleBannerWidget: {
- GenericVehicleImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
- },
- FunnelHeaderWidget: {
- LogoImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
- },
- },
- yearQuestionInitialData: yearQuestionInitialData,
- };
- const apiPromise = Promise.resolve(apiResponses);
-
- settleAllPromises.mockImplementation(() => apiPromise);
- fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
-
- //Mock year question methods
- yearQuestion.methods = {
- loadInitialData: jest.fn(),
- initializeComponent: jest.fn(),
- };
-
- const mountOptions = getMountOptions(mountOptionsMockData);
- const wrapper = shallowMount(vehicleYear, mountOptions);
- const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" });
- yearQuestionWrapper.vm.initializeComponent = yearQuestion.methods.initializeComponent;
- wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
-
- return { wrapper, apiPromise };
-}
diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue
deleted file mode 100644
index 5b166151a..000000000
--- a/src/layouts/vehicle-year/vehicle-year.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle-year/year-question/year-question.spec.js b/src/layouts/vehicle-year/year-question/year-question.spec.js
deleted file mode 100644
index f6a1e5e71..000000000
--- a/src/layouts/vehicle-year/year-question/year-question.spec.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
-import { shallowMount } from "@vue/test-utils";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import store from "@/store";
-jest.mock(
- "@/store",
- () => {
- return {};
- },
- { virtual: true }
-);
-
-describe("year-question.vue", () => {
- test("Selected year is emitted upon selection.", async () => {
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: "2020" });
- const yearToSelect = "2021";
-
- //Act
- wrapper.setValue({ modelValue: yearToSelect });
- await wrapper.vm.$nextTick();
-
- //Assert
- expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "2021" }]);
- });
-});
-
-describe("year-question.vue", () => {
- test("Data from store api are used as radio question answers.", async () => {
- //Arrange
- const { wrapper, cmsContent } = setupMocks({
- dataFromStoreApi: ["2023", "2022", "2021"],
- });
-
- //Act
- const initialData = yearQuestion.methods.loadInitialData.call(wrapper.vm);
- yearQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
-
- //Assert
- const buttonQuestionComponent = await wrapper.findComponent({
- name: "buttonQuestion",
- });
- expect(buttonQuestionComponent.attributes("answers")).toBe("2023,2022,2021");
- });
-});
-
-function setupMocks({
- modelValueProp = "1900",
- cmsQuestionText = "CMS text goes here",
- dataFromStoreApi = [],
-}) {
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- },
- });
-
- //Mock props
- const mockMixin = {
- methods: {
- getCmsContent: jest.fn(),
- },
- };
- mountOptions.propsData = {
- modelValue: modelValueProp,
- };
- mountOptions.mixins = [mockMixin];
-
- const wrapper = shallowMount(yearQuestion, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- QuestionText: cmsQuestionText,
- };
- return { wrapper, cmsContent };
-}
diff --git a/src/layouts/vehicle-year/year-question/year-question.vue b/src/layouts/vehicle-year/year-question/year-question.vue
deleted file mode 100644
index 6d8110216..000000000
--- a/src/layouts/vehicle-year/year-question/year-question.vue
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/vehicle/vehicle.spec.js b/src/layouts/vehicle/vehicle.spec.js
index 210281423..56b46292d 100644
--- a/src/layouts/vehicle/vehicle.spec.js
+++ b/src/layouts/vehicle/vehicle.spec.js
@@ -1,19 +1,17 @@
// Components
import vehicle from "@/layouts/vehicle/vehicle.vue";
-// Supporting files
+// Supporting Files
+import { shallowMount } from "@vue/test-utils";
import { nextTick } from "vue";
-import { mount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+
+// Mock our module for promises.
+jest.mock("@/helpers/layout-helper.js", () => ({
+ settleAllPromises: jest.fn(),
+}));
describe("vehicle.vue", () => {
- test('"Continue" button is enabled after YMMS is selected.', async () => {
- const { wrapper } = setupMocks();
-
- const continueButton = wrapper.get('[data-test-id="funnel-footer-main-button"]');
-
- expect(continueButton.attributes()["aria-disabled"]).toBe("false");
- });
-
test("arePagePrerequisitesValid should be true ", async () => {
//Arrange
const { wrapper } = setupMocks();
@@ -26,66 +24,33 @@ describe("vehicle.vue", () => {
expect(arePagePrerequisitesValid).toBe(true);
});
});
+describe("vehicle.vue", () => {
+ describe("navigation", () => {
+ test("if the continue button is clicked, navigate forward", async () => {
+ // Arrange
+ const { wrapper } = setupMocks();
-describe("navigation", () => {
- test("forwardButtonAction should trigger navigateForward", async () => {
- // Arrange
- const { wrapper } = setupMocks();
- wrapper.vm.navigateForward = jest.fn();
+ // Act
+ await wrapper.vm.forwardButtonAction();
- // Act
- await wrapper.vm.forwardButtonAction();
-
- //Assert
- expect(wrapper.vm.navigateForward).toHaveBeenCalled();
+ // Assert
+ expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
+ });
});
});
-const FunnelFooterWidgetMockData = {
- ForwardButtonText: "Continue",
-};
-
function setupMocks() {
- const mockRoute = {
- query: {
- fmgPage: "vehicle",
- },
- };
-
- const mockRouter = {
- navigate: jest.fn(),
- };
-
- const wrapper = mount(vehicle, {
- global: {
- mixins: [
- {
- methods: {
- getCmsContent: jest.fn((cmsWidgetName, fieldName) => {
- if (cmsWidgetName === "FunnelFooterWidget") {
- if (fieldName === "ForwardButtonText") {
- return FunnelFooterWidgetMockData.ForwardButtonText;
- }
- }
- return "";
- }),
- getFooterInfoBoxHeight: jest.fn(() => 80),
- },
- },
- ],
-
- mocks: {
- $route: mockRoute,
- $router: mockRouter,
+ const wrapper = shallowMount(
+ vehicle,
+ getMountOptions({
+ router: {
+ navigate: jest.fn(),
+ navigate: jest.fn(),
+ navigateWithSaving: jest.fn(),
+ navigateWithoutSaving: jest.fn(),
},
+ })
+ );
- stubs: {
- FunnelHeader: true,
- FunnelSubHeader: true,
- VehicleBanner: true,
- },
- },
- });
-
- return { mockRoute, mockRouter, wrapper };
+ return { wrapper };
}
diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue
index 24ae0d215..37e813bed 100644
--- a/src/layouts/vehicle/vehicle.vue
+++ b/src/layouts/vehicle/vehicle.vue
@@ -58,6 +58,9 @@
@@ -109,18 +112,20 @@ export default {
selectedMake: this.selectedMakefromStore(),
selectedModel: this.selectedModelfromStore(),
selectedStyle: this.selectedStylefromStore(),
+ carId: null,
+ category: null,
+ imageUrl: null,
+ imageVifNumber: null,
+ imageVifColor: null,
yearOptions: [],
makeOptions: [],
modelOptions: [],
styleOptions: [],
+ displayGeneric: this.displayGenericFromStore(),
+ unmatchedVehicleIcon: false,
};
},
- props: {
- cmsWidgetName: String,
- validationRules: String,
- },
-
async beforeRouteEnter(to, from, next) {
// Call APIs
@@ -244,7 +249,8 @@ export default {
const result = await this.getModelOptions(this.selectedYear, make);
this.modelOptions = result?.data;
if (this.selectedMakefromStore() !== make) {
- this.selectedModel = null;
+ if (this.modelOptions.length === 1) this.selectedModel = this.modelOptions[0];
+ else this.selectedModel = null;
this.selectedStyle = null;
}
} else {
@@ -260,36 +266,60 @@ export default {
);
this.styleOptions = result?.data;
if (this.selectedModelfromStore() !== model) {
- this.selectedStyle = null;
+ if (this.styleOptions.length === 1) this.selectedStyle = this.styleOptions[0];
+ else this.selectedStyle = null;
}
} else {
this.styleOptions = [];
}
},
- selectedStyle(style) {
- this.setVehicle(this.selectedYear, this.selectedMake, this.selectedModel, style);
+ async selectedStyle(style) {
+ if (style) {
+ const result = await this.getVehicle(
+ this.selectedYear,
+ this.selectedMake,
+ this.selectedModel,
+ style
+ );
+ this.carId = result?.data.carId;
+ this.category = result?.data.category;
+ this.imageUrl = result?.data.imageUrl;
+ this.imageVifNumber = result?.data.imageVifNumber;
+ this.imageVifColor = result?.data.imageVifColor;
+ if (this.imageUrl == null) {
+ this.displayGeneric = false;
+ this.unmatchedVehicleIcon = true;
+ } else this.unmatchedVehicleIcon = false;
+ } else {
+ this.imageUrl = null;
+ this.displayGeneric = true;
+ }
},
},
methods: {
- setVehicle(year, make, model, style) {
- return this.dispatchStoreAction(this.storeActions.SET_VEHICLE, {
+ getVehicle(year, make, model, style) {
+ return this.dispatchStoreAction(this.storeActions.GET_VEHICLE, {
year: year,
make: make,
model: model,
style: style,
});
},
-
+ displayGenericFromStore() {
+ if (store.getters.vehicle.imageUrl !== null) return false;
+ else if (
+ store.getters.vehicle.imageUrl === null &&
+ store.getters.vehicle.carId !== null
+ )
+ return false;
+ else return true;
+ },
arePagePrerequisitesValid() {
return true;
},
async forwardButtonAction() {
- return this.navigateForward();
- },
-
- navigateForward() {
this.dispatchStoreAction(
storeActions.SAVE_VEHICLE,
{
@@ -297,12 +327,16 @@ export default {
make: this.selectedMake,
model: this.selectedModel,
style: this.selectedStyle,
+ carId: this.carId,
+ category: this.category,
+ imageUrl: this.imageUrl,
+ imageVifNumber: this.imageVifNumber,
+ imageVifColor: this.imageVifColor,
},
false
);
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
},
-
initializeYearComponent(initialData) {
this.yearOptions = initialData;
},
@@ -345,12 +379,6 @@ export default {
},
},
- computed: {
- displayGeneric() {
- return !this.selectedStyle;
- },
- },
-
components: {
funnelHeader,
funnelFooter,
diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js
index 88b4772f8..37615f68b 100644
--- a/src/mixins/analytics-mixin.js
+++ b/src/mixins/analytics-mixin.js
@@ -38,6 +38,8 @@ export default {
event: pageEvent,
shouldUseSessionId: false,
experimentsForUser: store.getters.applicationUser.experiments,
+ referralSequenceNumber: store.getters.order.referralSequenceNumber,
+ parentAccountNumber: store.getters.order.payment.parentAccountNumber,
};
baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
@@ -57,6 +59,8 @@ export default {
value: value,
shouldUseSessionId: false,
experimentsForUser: store.getters.applicationUser.experiments,
+ referralSequenceNumber: store.getters.order.referralSequenceNumber,
+ parentAccountNumber: store.getters.order.payment.parentAccountNumber,
};
baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
diff --git a/src/router/index.js b/src/router/index.js
index 6d812f847..e8fbf4d26 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -31,11 +31,6 @@ import { applicationConfig } from "../constants/application-config";
import review from "@/layouts/review/review";
import paymentMethod from "@/layouts/payment-method/payment-method";
const routes = [
- {
- path: "/review", // This is a temporary route for testing.
- name: "review",
- component: review,
- },
{
path: "/payment-method", // This is a temporary route for testing.
name: "payment-method",
diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js
index fc8841c13..ba931f77d 100644
--- a/src/router/router-constants/fmgPage-values.js
+++ b/src/router/router-constants/fmgPage-values.js
@@ -1,8 +1,4 @@
const fmgPageValues = {
- VEHICLE_YEAR: "vehicle-year",
- VEHICLE_MAKE: "vehicle-make",
- VEHICLE_MODEL: "vehicle-model",
- VEHICLE_STYLE: "vehicle-style",
VEHICLE: "vehicle",
VEHICLE_DAMAGE: "vehicle-damage",
ADDRESS_LOOKUP: "address-lookup",
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index ae1c880ae..bf89f4f3f 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -12,12 +12,6 @@ const navigationScenarios = {
CLICKED_FORWARD: "CLICKED_FORWARD",
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
- // YMMS
- SELECTED_YEAR: "SELECTED_YEAR",
- SELECTED_MODEL: "SELECTED_MODEL",
- SELECTED_MAKE: "SELECTED_MAKE",
- SELECTED_STYLE: "SELECTED_STYLE",
-
// Vin selection
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN",
@@ -51,6 +45,7 @@ const navigationScenarios = {
CLICKED_DAMAGE_EDIT: "CLICKED_DAMAGE_EDIT",
CLICKED_SERVICE_PACKAGE_EDIT: "CLICKED_SERVICE_PACKAGE_EDIT",
CLICKED_SERVICE_LOCATION_EDIT: "CLICKED_SERVICE_LOCATION_EDIT",
+ CLICKED_SCHEDULE_EDIT: "CLICKED_SCHEDULE_EDIT",
};
export { navigationScenarios };
diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js
index 017e1372a..b90806e94 100644
--- a/src/router/router-constants/routing-table.js
+++ b/src/router/router-constants/routing-table.js
@@ -13,54 +13,7 @@ const routingTable = function (store) {
},
],
},
- {
- fmgPageValue: fmgPageValues.VEHICLE_YEAR,
- maps: [
- {
- scenario: navigationScenarios.SELECTED_YEAR,
- destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE,
- },
- ],
- },
- {
- fmgPageValue: fmgPageValues.VEHICLE_MAKE,
- maps: [
- {
- scenario: navigationScenarios.SELECTED_MAKE,
- destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL,
- },
- {
- scenario: navigationScenarios.CLICKED_BACK,
- destinationFmgPageValue: fmgPageValues.VEHICLE_YEAR,
- },
- ],
- },
- {
- fmgPageValue: fmgPageValues.VEHICLE_MODEL,
- maps: [
- {
- scenario: navigationScenarios.SELECTED_MODEL,
- destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
- },
- {
- scenario: navigationScenarios.CLICKED_BACK,
- destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE,
- },
- ],
- },
- {
- fmgPageValue: fmgPageValues.VEHICLE_STYLE,
- maps: [
- {
- scenario: navigationScenarios.SELECTED_STYLE,
- destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
- },
- {
- scenario: navigationScenarios.CLICKED_BACK,
- destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL,
- },
- ],
- },
+
{
fmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
maps: [
@@ -484,6 +437,10 @@ const routingTable = function (store) {
scenario: navigationScenarios.CLICKED_SERVICE_LOCATION_EDIT,
destinationFmgPageValue: fmgPageValues.SERVICE_LOCATION,
},
+ {
+ scenario: navigationScenarios.CLICKED_SCHEDULE_EDIT,
+ destinationFmgPageValue: fmgPageValues.SCHEDULE,
+ },
],
},
];
diff --git a/src/store/index.js b/src/store/index.js
index 2d5a2e898..022db132c 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -13,7 +13,14 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
import { deepEqual } from "@/helpers/object-helper";
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
+import { getQuerystringParameter } from "@/helpers/querystring-helper";
+import { queryStrings } from "@/constants/query-strings";
import { partTypeStrings } from "@/constants/part-type-strings";
+import {
+ convertDateStringToDate,
+ militaryToTwelveHourTime,
+ getDisplayTextForDurationLength,
+} from "@/layouts/schedule/helpers/schedule-helper";
// Export State
const getDefaultState = () => {
@@ -32,12 +39,6 @@ const getDefaultState = () => {
imageColor: null,
registration: {
licensePlate: null,
- address: null,
- city: null,
- state: null,
- zipCode: null,
- firstName: null,
- lastName: null,
},
},
serviceLocation: {
@@ -66,7 +67,7 @@ const getDefaultState = () => {
lastName: null,
emailAddress: null,
phoneNumber: null,
- isSmsOptin: null,
+ isSmsOptIn: null,
},
damage: {
isRepair: null,
@@ -96,8 +97,10 @@ const getDefaultState = () => {
endTime: null,
routeCode: null,
jobMaxMinutes: null,
+ jobMinMinutes: null,
},
referralNumber: null,
+ referralSequenceNumber: null,
referralDate: null,
referralCorrelationId: null,
eon: null,
@@ -190,6 +193,9 @@ export const mutations = {
updateReferralNumber(state, referralNumber) {
state.order.referralNumber = referralNumber;
},
+ updateReferralSequenceNumber(state, referralSequenceNumber) {
+ state.order.referralSequenceNumber = referralSequenceNumber;
+ },
updateReferralDate(state, referralDate) {
state.order.referralDate = referralDate;
},
@@ -205,27 +211,6 @@ export const mutations = {
updateInsuranceVerifiedStatus(state, isVerified) {
state.order.payment.insuranceCoverage.isVerified = isVerified;
},
- updateRegistrationLicensePlate(state, licensePlate) {
- state.order.vehicle.registration.licensePlate = licensePlate;
- },
- updateRegistrationAddress(state, registrationAddress) {
- state.order.vehicle.registration.address = registrationAddress;
- },
- updateRegistrationCity(state, registrationCity) {
- state.order.vehicle.registration.city = registrationCity;
- },
- updateRegistrationState(state, registrationState) {
- state.order.vehicle.registration.state = registrationState;
- },
- updateRegistrationZipCode(state, registrationZipCode) {
- state.order.vehicle.registration.zipCode = registrationZipCode;
- },
- updateRegistrationFirstName(state, firstName) {
- state.order.vehicle.registration.firstName = firstName;
- },
- updateRegistrationLastName(state, lastName) {
- state.order.vehicle.registration.lastName = lastName;
- },
updateCustomerEmailAddress(state, customerEmailAddress) {
state.order.customer.emailAddress = customerEmailAddress;
},
@@ -283,6 +268,7 @@ export const mutations = {
state.order.schedule.endTime = scheduleInfo.endTime;
state.order.schedule.routeCode = scheduleInfo.routeCode;
state.order.schedule.jobMaxMinutes = scheduleInfo.jobMaxMinutes;
+ state.order.schedule.jobMinMinutes = scheduleInfo.jobMinMinutes;
}
},
updateCustomerDetails(state, customerDetails) {
@@ -291,7 +277,7 @@ export const mutations = {
state.order.customer.lastName = customerDetails.lastName;
state.order.customer.emailAddress = customerDetails.emailAddress;
state.order.customer.phoneNumber = customerDetails.phoneNumber;
- state.order.customer.isSmsOptin = customerDetails.isSmsOptin;
+ state.order.customer.isSmsOptIn = customerDetails.isSmsOptIn;
}
},
@@ -345,12 +331,8 @@ export const mutations = {
},
resetRegistrationState(state) {
state.order.vehicle.registration.licensePlate = null;
- state.order.vehicle.registration.address = null;
- state.order.vehicle.registration.city = null;
- state.order.vehicle.registration.state = null;
- state.order.vehicle.registration.zipCode = null;
- state.order.vehicle.registration.firstName = null;
- state.order.vehicle.registration.lastName = null;
+ state.order.customer.firstName = null;
+ state.order.customer.lastName = null;
},
resetGlassPartsState(state) {
state.order.lineItems.glassParts = null;
@@ -368,6 +350,7 @@ export const mutations = {
state.order.schedule.endTime = null;
state.order.schedule.routeCode = null;
state.order.schedule.jobMaxMinutes = null;
+ state.order.schedule.jobMinMinutes = null;
//premium appointment fee used on schedule page also needs reset when schedule is reset
const supportingItems = state.order.lineItems.supportingItems;
@@ -411,6 +394,7 @@ export const mutations = {
// Misc Mutations
updateStateWithOrderInformation(state, sessionInformation) {
state.order.referralNumber = sessionInformation.order.referralNumber;
+ state.order.referralSequenceNumber = sessionInformation.order.referralSequenceNumber;
state.order.referralDate = sessionInformation.order.referralDate;
state.order.referralCorrelationId = sessionInformation.order.referralCorrelationId;
state.order.eon = sessionInformation.order.eon;
@@ -492,8 +476,8 @@ export const mutations = {
state.order.customer.emailAddress = sessionInformation.order.customer.emailAddress;
state.order.customer.firstName = sessionInformation.order.customer.firstName;
state.order.customer.lastName = sessionInformation.order.customer.lastName;
- state.order.customer.phoneNumber = sessionInformation.order.customer.phoneNumber;
- state.order.customer.isSmsOptin = sessionInformation.order.customer.isSmsOptin;
+ state.order.customer.phoneNumber = sessionInformation.order.customer.servicePhoneNumber;
+ state.order.customer.isSmsOptIn = sessionInformation.order.customer.isSmsOptIn;
state.order.existingPromoCode = sessionInformation.order.existingPromoCode;
state.applicationUser.experiments = sessionInformation.applicationUser.experiments;
@@ -506,6 +490,7 @@ export const mutations = {
state.order.schedule.endTime = sessionInformation.order.schedule?.endTime;
state.order.schedule.routeCode = sessionInformation.order.schedule?.routeCode;
state.order.schedule.jobMaxMinutes = sessionInformation.order.schedule?.jobMaxMinutes;
+ state.order.schedule.jobMinMinutes = sessionInformation.order.schedule?.jobMinMinutes;
},
updateExperiments(state, experiments) {
state.applicationUser.experiments = experiments;
@@ -540,6 +525,9 @@ export const getters = {
isMobileAppointment: (state) => {
return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
},
+ isDropOffAppointment: (state) => {
+ return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF;
+ },
isRecalibrationOnOrder: (state) => {
return getHasRecalibrationPart(state);
},
@@ -548,6 +536,30 @@ export const getters = {
(vap) => vap.partType.toUpperCase() === partTypeStrings.REAR_WIPER.toUpperCase()
);
},
+ scheduleDisplayText: (state) => {
+ const dateModel = convertDateStringToDate(state.order.schedule.date);
+ const readableDate = dateModel?.toLocaleDateString("en-us", {
+ weekday: "long",
+ month: "long",
+ day: "numeric",
+ year: "numeric",
+ });
+
+ const readableStartTime = militaryToTwelveHourTime(state.order.schedule.startTime);
+ const readableEndTime = militaryToTwelveHourTime(state.order.schedule.endTime);
+
+ const readableDuration = getDisplayTextForDurationLength(
+ state.order.schedule.jobMinMinutes,
+ state.order.schedule.jobMaxMinutes
+ );
+
+ return {
+ date: readableDate,
+ startTime: readableStartTime,
+ endTime: readableEndTime,
+ duration: readableDuration,
+ };
+ },
lineItems: (state) => state.order.lineItems,
pageData: (state) => (page) => {
return state.applicationUser.pageData[page];
@@ -739,7 +751,7 @@ export const actions = {
});
},
- setVehicle(context, { year, make, model, style }) {
+ getVehicle(context, { year, make, model, style }) {
return globalMethods
.callHttpClient({
methods: endpoints.GetVehicle.method,
@@ -747,27 +759,17 @@ export const actions = {
payload: {},
})
.then((response) => {
- context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, response.data.imageUrl);
- context.commit(
- storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER,
- response.data.imageVifNumber
- );
- context.commit(
- storeMutations.UPDATE_VEHICLE_IMAGE_COLOR,
- response.data.imageVifColor
- );
return response;
});
},
- getDamageOptions(context, { carId, zipCode }) {
+ getDamageOptions(context, { carId }) {
return globalMethods.callHttpClient({
methods: endpoints.GetDamageOptions.method,
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
payload: {},
- additionalSuccessEventDataHandler: (response) => "QueryStringZip: " + zipCode,
+ additionalSuccessEventDataHandler: (response) =>
+ "QueryStringZip: " + getQuerystringParameter(queryStrings.ZIP_CODE),
});
},
@@ -883,6 +885,7 @@ export const actions = {
context,
{
referralNumber,
+ referralSequenceNumber,
referralDate,
referralCorrelationId,
eon,
@@ -892,6 +895,7 @@ export const actions = {
}
) {
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
+ context.commit(storeMutations.UPDATE_REFERRAL_SEQUENCE_NUMBER, referralSequenceNumber);
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
context.commit(storeMutations.UPDATE_EON, eon);
@@ -911,6 +915,8 @@ export const actions = {
event,
shouldUseSessionId,
experimentsForUser,
+ referralSequenceNumber,
+ parentAccountNumber,
}
) {
var payload = {
@@ -923,6 +929,8 @@ export const actions = {
event: event,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
+ referralSequenceNumber: referralSequenceNumber,
+ parentAccountNumber: parentAccountNumber,
};
return globalMethods
@@ -955,6 +963,8 @@ export const actions = {
value,
shouldUseSessionId,
experimentsForUser,
+ referralSequenceNumber,
+ parentAccountNumber,
}
) {
var payload = {
@@ -969,6 +979,8 @@ export const actions = {
value: value,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
+ referralSequenceNumber: referralSequenceNumber,
+ parentAccountNumber: parentAccountNumber,
};
return globalMethods
@@ -1417,8 +1429,8 @@ export const actions = {
emailAddress: order.customer.emailAddress,
firstName: order.customer.firstName,
lastName: order.customer.lastName,
- isSmsOptin: order.customer.isSmsOptin,
- phoneNumber: order.customer.phoneNumber,
+ isSmsOptIn: order.customer.isSmsOptIn,
+ servicePhoneNumber: order.customer.phoneNumber,
},
damage: {
numberOfChips: damage.numberOfChips,
@@ -1438,7 +1450,7 @@ export const actions = {
InsuranceCoverage: {
isVerified: order.payment.insuranceCoverage.isVerified ?? false,
},
- isInsurance: order.payment.isInsurance ?? false,
+ isInsurance: order.payment.isInsurance,
parentAccountNumber: order.payment.parentAccountNumber,
},
serviceLocation: {
@@ -1469,12 +1481,13 @@ export const actions = {
endTime: order.schedule?.endTime,
routeCode: order.schedule?.routeCode,
jobMaxMinutes: order.schedule?.jobMaxMinutes,
+ jobMinMinutes: order.schedule?.jobMinMinutes,
},
existingPromoCode: null,
referralCorrelationId: order.referralCorrelationId,
referralDate: order.referralDate,
- referralNumber: order.referralNumber?.toString(), // TODO It'd be nice to save these as strings in the first place
- referralSequenceNumber: order.referralNumber?.toString(), // TODO Pass the referralSequence number once insurance flow creates it
+ referralNumber: order.referralNumber?.toString(),
+ referralSequenceNumber: order.referralSequenceNumber,
eon: order.eon,
},
},
@@ -1542,92 +1555,12 @@ export const actions = {
// Business domain actions
// Vehicle
- saveVehicleYear(context, year) {
- //Reset dependent state when changing
- if (context.state.order.vehicle.year !== year) {
- context.commit(storeMutations.UPDATE_MAKE, null);
- context.commit(storeMutations.UPDATE_MODEL, null);
- context.commit(storeMutations.UPDATE_STYLE, null);
- context.commit(storeMutations.UPDATE_CAR_ID, null);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
-
- context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
-
- //Save new values
- context.commit(storeMutations.UPDATE_YEAR, year);
- }
- },
-
- saveVehicleMake(context, make) {
- //Reset dependent state when changing
- if (context.state.order.vehicle.make !== make) {
- context.commit(storeMutations.UPDATE_MODEL, null);
- context.commit(storeMutations.UPDATE_STYLE, null);
- context.commit(storeMutations.UPDATE_CAR_ID, null);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
-
- context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
-
- //Save new values
- context.commit(storeMutations.UPDATE_MAKE, make);
- }
- },
-
- saveVehicleModel(context, model) {
- //Reset dependent state when changing
- if (context.state.order.vehicle.model !== model) {
- context.commit(storeMutations.UPDATE_STYLE, null);
- context.commit(storeMutations.UPDATE_CAR_ID, null);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
-
- context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
-
- //Save new values
- context.commit(storeMutations.UPDATE_MODEL, model);
- }
- },
-
- saveVehicleStyle(context, style) {
- //Reset dependent state when changing
- if (context.state.order.vehicle.style !== style) {
- context.commit(storeMutations.UPDATE_CAR_ID, null);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
-
- context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
-
- //Save new values
- context.commit(storeMutations.UPDATE_STYLE, style);
- }
- },
-
- saveVehicle(context, { year, make, model, style }) {
+ saveVehicle(
+ context,
+ { year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor }
+ ) {
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
- context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
if (context.state.order.vehicle.year !== year) {
context.commit(storeMutations.UPDATE_YEAR, year);
@@ -1641,6 +1574,11 @@ export const actions = {
if (context.state.order.vehicle.style !== style) {
context.commit(storeMutations.UPDATE_STYLE, style);
}
+ context.commit(storeMutations.UPDATE_CAR_ID, carId);
+ context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category);
+ context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
+ context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
+ context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
},
saveVehicleDamage(
@@ -1728,12 +1666,8 @@ export const actions = {
) {
//Reset dependent state when changing
if (
- registrationInfo?.address !== context.state.order.vehicle.registration?.address ||
- registrationInfo?.city !== context.state.order.vehicle.registration?.city ||
- registrationInfo?.state !== context.state.order.vehicle.registration?.state ||
- registrationInfo?.zipCode !== context.state.order.vehicle.registration?.zipCode ||
- registrationInfo?.firstName !== context.state.order.vehicle.registration?.firstName ||
- registrationInfo?.lastName !== context.state.order.vehicle.registration?.lastName
+ registrationInfo?.firstName !== context.state.order.customer?.firstName ||
+ registrationInfo?.lastName !== context.state.order.customer?.lastName
) {
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
@@ -2064,12 +1998,6 @@ export const actions = {
return true;
default:
}
- if (
- context.state.order.vehicle.make.toLowerCase() === "ford" &&
- context.state.order.vehicle.year >= 2018
- ) {
- return true;
- }
if (
context.state.order.vehicle.make.toLowerCase() === "bmw" &&
context.state.order.vehicle.year <= 2017
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index 08aa406c9..ded194ba8 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -335,6 +335,28 @@ describe("Mutations", () => {
expect(storeState.order.serviceLocation.state).toEqual("OH");
expect(storeState.order.serviceLocation.zipCodeCtu).toEqual("01820");
});
+
+ it("updateCustomerDetails, should set customer details in state", () => {
+ // Arrange
+ const storeState = state;
+ const customerDetails = {
+ firstName: "foo",
+ lastName: "bar",
+ emailAddress: "foo@bar.com",
+ phoneNumber: "555-555-5555",
+ isSmsOptIn: true,
+ };
+
+ // Act
+ mutations.updateCustomerDetails(storeState, customerDetails);
+
+ // Assert
+ expect(state.order.customer.firstName).toEqual("foo");
+ expect(state.order.customer.lastName).toEqual("bar");
+ expect(state.order.customer.emailAddress).toEqual("foo@bar.com");
+ expect(state.order.customer.phoneNumber).toEqual("555-555-5555");
+ expect(state.order.customer.isSmsOptIn).toEqual(true);
+ });
});
describe("Actions", () => {
@@ -484,12 +506,9 @@ describe("Actions", () => {
expect(response.data).toEqual({ style: "4 DOOR SEDAN" });
});
- it("setVehicle action, should get vehicle data and set carId and vehicle category", async () => {
+ it("getVehicle action, should get vehicle data ", async () => {
// Arrange
const context = state;
- const commit = jest.fn();
-
- context.commit = commit;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
@@ -497,10 +516,8 @@ describe("Actions", () => {
});
// Assert
- const response = await actions.setVehicle(context, "C00000000");
+ const response = await actions.getVehicle(context, "C00000000");
- expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, "C00000000");
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, "CAR");
expect(response.data).toEqual({ carId: "C00000000", category: "CAR" });
});
@@ -802,6 +819,7 @@ describe("Actions", () => {
// Act
actions.updateStoreWithSaveSessionResponse(context, {
referralNumber: "123",
+ referralSequenceNumber: 123,
referralDate: new Date().toUTCString(),
referralCorrelationId: "xxx-xxx-xxx",
parentAccountNumber: "167132",
@@ -943,7 +961,7 @@ describe("Actions", () => {
);
});
- it("saveServiceZipCodeInfo, should call mutation and save zip code to state", () => {
+ it("saveServiceZipCodeInfo, should call mutation", () => {
// Arrange
const context = state;
const commit = jest.fn();
@@ -958,7 +976,6 @@ describe("Actions", () => {
// Assert
expect(commit).toBeCalledWith(storeMutations.UPDATE_SERVICE_LOCATION, serviceZipCodeInfo);
- expect(state.order.serviceLocation.zipCode).toEqual("43212");
});
it("saveServiceZipCodeInfo, should reset if zip code is different", () => {
@@ -1027,7 +1044,7 @@ describe("Actions", () => {
);
});
- it("saveServiceLocation, should call mutation and save service address to state", () => {
+ it("saveServiceLocation, should call mutation", () => {
// Arrange
const context = state;
const commit = jest.fn();
@@ -1046,11 +1063,6 @@ describe("Actions", () => {
// Assert
expect(commit).toBeCalledWith(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocation);
- expect(state.order.serviceLocation.address).toEqual("123 Test Lane");
- expect(state.order.serviceLocation.city).toEqual("Columbus");
- expect(state.order.serviceLocation.zipCode).toEqual("43212");
- expect(state.order.serviceLocation.state).toEqual("OH");
- expect(state.order.serviceLocation.zipCodeCtu).toEqual("01820");
});
it("saveServiceLocation, should reset if zipcode is different", () => {
@@ -1297,6 +1309,27 @@ describe("Actions", () => {
expect(commit).not.toHaveBeenCalledWith(storeMutations.RESET_SCHEDULE);
});
+ it("saveCustomerDetails, should call mutation", () => {
+ // Arrange
+ const context = state;
+ const commit = jest.fn();
+ context.commit = commit;
+
+ const customerDetails = {
+ firstName: "foo",
+ lastName: "bar",
+ emailAddress: "foo@bar.com",
+ phoneNumber: "555-555-5555",
+ isSmsOptIn: true,
+ };
+
+ // Act
+ actions.saveCustomerDetails(context, customerDetails);
+
+ // Assert
+ expect(commit).toBeCalledWith(storeMutations.UPDATE_CUSTOMER_DETAILS, customerDetails);
+ });
+
it("saveGlassParts, should call mutation", () => {
// Arrange
const context = {
@@ -1519,7 +1552,7 @@ describe("Actions", () => {
isCarIdDifferent: true,
isSelectedGlassAvailableForVehicle: false,
vehicleInfo: { carId: "C010101", vin: "XXXXX" },
- registrationInfo: { zipCode: "80020", address: "123 Marys Ave" },
+ registrationInfo: { firstName: "abc", lastName: "123" },
serviceLocationInfo: { state: "CO" },
customerEmail: "test@safelite.com",
};
@@ -1540,168 +1573,6 @@ describe("Actions", () => {
expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo);
});
- it("saveVehicleYear, should wipe out vehicle info if year changes", () => {
- // Arrange
- const context = state;
-
- context.state = {
- order: {
- vehicle: {
- year: "2015",
- },
- },
- };
-
- const commit = jest.fn();
- const dispatch = jest.fn();
-
- context.commit = commit;
- context.dispatch = dispatch;
-
- // Act
- actions.saveVehicleYear(context, "2016");
-
- // Assert
- expect(dispatch).toHaveBeenNthCalledWith(
- 1,
- storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
- );
- expect(dispatch).toHaveBeenNthCalledWith(
- 2,
- storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
- );
-
- expect(commit).toBeCalledWith(storeMutations.UPDATE_MAKE, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
- });
-
- it("saveVehicleMake, should wipe out vehicle info if make changes", () => {
- // Arrange
- const context = state;
-
- context.state = {
- order: {
- vehicle: {
- make: "Honda",
- },
- },
- };
-
- const commit = jest.fn();
- const dispatch = jest.fn();
-
- context.commit = commit;
- context.dispatch = dispatch;
-
- // Act
- actions.saveVehicleMake(context, "Toyota");
-
- // Assert
- expect(dispatch).toHaveBeenNthCalledWith(
- 1,
- storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
- );
- expect(dispatch).toHaveBeenNthCalledWith(
- 2,
- storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
- );
-
- expect(commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
- });
-
- it("saveVehicle model, should wipe out vehicle info if model changes", () => {
- // Arrange
- const context = state;
-
- context.state = {
- order: {
- vehicle: {
- model: "Civic",
- },
- },
- };
-
- const commit = jest.fn();
- const dispatch = jest.fn();
-
- context.commit = commit;
- context.dispatch = dispatch;
-
- // Act
- actions.saveVehicleModel(context, "Accord");
-
- // Assert
- expect(dispatch).toHaveBeenNthCalledWith(
- 1,
- storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
- );
- expect(dispatch).toHaveBeenNthCalledWith(
- 2,
- storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
- );
-
- expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
- });
-
- it("saveVehicleStyle, should wipe out vehicle info if style changes", () => {
- // Arrange
- const context = state;
-
- context.state = {
- order: {
- vehicle: {
- style: "Sedan",
- },
- },
- };
-
- const commit = jest.fn();
- const dispatch = jest.fn();
-
- context.commit = commit;
- context.dispatch = dispatch;
-
- // Act
- actions.saveVehicleStyle(context, "SUV");
-
- // Assert
- expect(dispatch).toHaveBeenNthCalledWith(
- 1,
- storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
- );
- expect(dispatch).toHaveBeenNthCalledWith(
- 2,
- storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
- );
-
- expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
- expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
- });
-
it("saveVehicle, should save vehicle info", () => {
// Arrange
const context = state;
@@ -1729,6 +1600,8 @@ describe("Actions", () => {
make: "Honda",
model: "Civic",
style: "Sedan",
+ carId: "C00000000",
+ category: "CAR",
};
actions.saveVehicle(context, payload);
@@ -1753,6 +1626,8 @@ describe("Actions", () => {
if (context.state.order.vehicle.style !== payload.style) {
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, payload.style);
}
+ context.commit(storeMutations.UPDATE_CAR_ID, payload.carId);
+ context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.category);
});
it("saveVehicleDamage, should wipe out damage if different", () => {
@@ -3291,8 +3166,6 @@ describe("Getters", () => {
describe("isVinOptionalVehicle", () => {
const testVehicles = [
["2017", "acura", false],
- ["2017", "ford", false],
- ["2018", "ford", true],
["2018", "bmw", false],
["2017", "bmw", true],
["2016", "bmw", true],