diff --git a/jest.config.js b/jest.config.js
index 34a45f34a..633a99e67 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -17,7 +17,6 @@ module.exports = {
"!src/ux-components/text-link/**/*.vue",
"!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-mutations.js b/src/constants/store-mutations.js
index 2c249750d..fd568ead7 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -23,13 +23,6 @@ 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",
@@ -43,6 +36,7 @@ const storeMutations = {
// 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/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 3354db13c..8bff4e9e2 100644
--- a/src/fmg-components/vehicle-banner/vehicle-banner.vue
+++ b/src/fmg-components/vehicle-banner/vehicle-banner.vue
@@ -18,6 +18,16 @@ export default {
required: false,
default: null,
},
+ displayUnmatchedVehicleIcon: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ vehicleCategory: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
vehicleImageToDisplay() {
@@ -29,7 +39,8 @@ export default {
}
if (
this.$store.getters.vehicle.imageUrl === null ||
- this.$store.getters.vehicle.imageUrl === "NULL"
+ this.$store.getters.vehicle.imageUrl === "NULL" ||
+ this.displayUnmatchedVehicleIcon
) {
return this.getUnmatchedVehicleIcon();
}
@@ -57,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 d522a5e6d..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);
@@ -112,6 +113,8 @@ 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();
@@ -120,7 +123,11 @@ async function getLatestPageForRedirection() {
} 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;
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 e91317ca9..55e1b01b8 100644
--- a/src/layouts/customer-details/customer-details.vue
+++ b/src/layouts/customer-details/customer-details.vue
@@ -25,7 +25,7 @@
validationRules="email-address-required|email-address-format" />
diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue
index 97b684d0f..dff601165 100644
--- a/src/layouts/estimate/estimate.vue
+++ b/src/layouts/estimate/estimate.vue
@@ -7,10 +7,7 @@
-
+
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-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js b/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js
new file mode 100644
index 000000000..a8e0a6f7b
--- /dev/null
+++ b/src/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question.spec.js
@@ -0,0 +1,150 @@
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+
+import customerDetailsModalQuestion from "@/layouts/review/review-sections/customer-review/customer-details-modal-question/customer-details-modal-question";
+
+const testConstants = {
+ previousCustomerValues: {
+ firstName: "First",
+ lastName: "Last",
+ emailAddress: "builddigitaltest@safelite.com",
+ phoneNumber: "111-111-1111",
+ isSmsOptIn: false,
+ },
+ newValues: {
+ firstName: "New First",
+ lastName: "New Last",
+ emailAddress: "builddigitaltest2@safelite.com",
+ phoneNumber: "222-222-2222",
+ isSmsOptIn: true,
+ },
+};
+
+let cmsContent;
+
+describe("Customer Details Modal", () => {
+ 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.vue b/src/layouts/review/review.vue
index fce6e4f59..fe14e8f7e 100644
--- a/src/layouts/review/review.vue
+++ b/src/layouts/review/review.vue
@@ -76,12 +76,23 @@
cmsWidgetName="ScheduleWidget"
:appointmentType="appointmentType"
@edit-clicked="editSchedule" />
+
+
+
+
+
+
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 6a42b7a92..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) {
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/vehicle.vue b/src/layouts/vehicle/vehicle.vue
index 13001e2fd..37e813bed 100644
--- a/src/layouts/vehicle/vehicle.vue
+++ b/src/layouts/vehicle/vehicle.vue
@@ -58,7 +58,9 @@
@@ -110,17 +112,17 @@ export default {
selectedMake: this.selectedMakefromStore(),
selectedModel: this.selectedModelfromStore(),
selectedStyle: this.selectedStylefromStore(),
- vehicle: {
- carId: null,
- category: null,
- imageUrl: null,
- imageVifNumber: null,
- imageVifColor: null,
- },
+ carId: null,
+ category: null,
+ imageUrl: null,
+ imageVifNumber: null,
+ imageVifColor: null,
yearOptions: [],
makeOptions: [],
modelOptions: [],
styleOptions: [],
+ displayGeneric: this.displayGenericFromStore(),
+ unmatchedVehicleIcon: false,
};
},
@@ -279,7 +281,18 @@ export default {
this.selectedModel,
style
);
- this.vehicle = result?.data;
+ 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;
}
},
},
@@ -293,6 +306,15 @@ export default {
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;
},
@@ -305,7 +327,11 @@ export default {
make: this.selectedMake,
model: this.selectedModel,
style: this.selectedStyle,
- vehicle: this.vehicle,
+ carId: this.carId,
+ category: this.category,
+ imageUrl: this.imageUrl,
+ imageVifNumber: this.imageVifNumber,
+ imageVifColor: this.imageVifColor,
},
false
);
@@ -353,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/store/index.js b/src/store/index.js
index 35b4c266e..022db132c 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -13,6 +13,8 @@ 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,
@@ -37,12 +39,6 @@ const getDefaultState = () => {
imageColor: null,
registration: {
licensePlate: null,
- address: null,
- city: null,
- state: null,
- zipCode: null,
- firstName: null,
- lastName: null,
},
},
serviceLocation: {
@@ -104,6 +100,7 @@ const getDefaultState = () => {
jobMinMinutes: null,
},
referralNumber: null,
+ referralSequenceNumber: null,
referralDate: null,
referralCorrelationId: null,
eon: null,
@@ -196,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;
},
@@ -211,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;
},
@@ -352,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;
@@ -419,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;
@@ -500,7 +476,7 @@ 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.phoneNumber = sessionInformation.order.customer.servicePhoneNumber;
state.order.customer.isSmsOptIn = sessionInformation.order.customer.isSmsOptIn;
state.order.existingPromoCode = sessionInformation.order.existingPromoCode;
@@ -787,12 +763,13 @@ export const actions = {
});
},
- 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),
});
},
@@ -908,6 +885,7 @@ export const actions = {
context,
{
referralNumber,
+ referralSequenceNumber,
referralDate,
referralCorrelationId,
eon,
@@ -917,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);
@@ -936,6 +915,8 @@ export const actions = {
event,
shouldUseSessionId,
experimentsForUser,
+ referralSequenceNumber,
+ parentAccountNumber,
}
) {
var payload = {
@@ -948,6 +929,8 @@ export const actions = {
event: event,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
+ referralSequenceNumber: referralSequenceNumber,
+ parentAccountNumber: parentAccountNumber,
};
return globalMethods
@@ -980,6 +963,8 @@ export const actions = {
value,
shouldUseSessionId,
experimentsForUser,
+ referralSequenceNumber,
+ parentAccountNumber,
}
) {
var payload = {
@@ -994,6 +979,8 @@ export const actions = {
value: value,
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
+ referralSequenceNumber: referralSequenceNumber,
+ parentAccountNumber: parentAccountNumber,
};
return globalMethods
@@ -1443,7 +1430,7 @@ export const actions = {
firstName: order.customer.firstName,
lastName: order.customer.lastName,
isSmsOptIn: order.customer.isSmsOptIn,
- phoneNumber: order.customer.phoneNumber,
+ servicePhoneNumber: order.customer.phoneNumber,
},
damage: {
numberOfChips: damage.numberOfChips,
@@ -1463,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: {
@@ -1499,8 +1486,8 @@ export const actions = {
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,
},
},
@@ -1679,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);
@@ -2015,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 186cf2d31..ded194ba8 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -819,6 +819,7 @@ describe("Actions", () => {
// Act
actions.updateStoreWithSaveSessionResponse(context, {
referralNumber: "123",
+ referralSequenceNumber: 123,
referralDate: new Date().toUTCString(),
referralCorrelationId: "xxx-xxx-xxx",
parentAccountNumber: "167132",
@@ -1551,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",
};
@@ -1599,14 +1600,20 @@ describe("Actions", () => {
make: "Honda",
model: "Civic",
style: "Sedan",
- vehicle: {
- carId: "C00000000",
- category: "CAR",
- },
+ carId: "C00000000",
+ category: "CAR",
};
actions.saveVehicle(context, payload);
//Assert
+ expect(dispatch).toHaveBeenNthCalledWith(
+ 1,
+ storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
+ );
+ expect(dispatch).toHaveBeenNthCalledWith(
+ 2,
+ storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
+ );
if (context.state.order.vehicle.year !== payload.year) {
expect(commit).toBeCalledWith(storeMutations.UPDATE_YEAR, payload.year);
}
@@ -1619,8 +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.vehicle.carId);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.vehicle.category);
+ context.commit(storeMutations.UPDATE_CAR_ID, payload.carId);
+ context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.category);
});
it("saveVehicleDamage, should wipe out damage if different", () => {
@@ -3159,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],