Merge branch 'develop' into defect/CSR-1467

This commit is contained in:
Leah Schumann 2023-06-28 08:25:38 -04:00
commit 8a119e89f4
10 changed files with 18988 additions and 36 deletions

File diff suppressed because it is too large Load diff

View file

@ -17,18 +17,12 @@ export default {
additionalSuccessEventDataHandler,
}) {
return new Promise((resolve, reject) => {
let cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" });
const headers = {
[headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings),
};
if (endpoint.toLowerCase().includes("/analytics/")) {
cfDistroUrl = "";
endpoint = "";
method = "GET";
}
axios({
method: method,
url: cfDistroUrl + endpoint,
@ -44,7 +38,7 @@ export default {
additionalEventData = "_" + additionalSuccessEventDataHandler(response);
}
const pageName = analyticsMixIn.methods.getPageName();
const nextPageName = router.getNextPage() || pageName;
const nextPageName = router.lastNavigationPage || pageName;
analyticsMixIn.methods.pushEventToGA(
GaCategories.API_RESPONSE,
`${nextPageName}_${endpoint}`,

View file

@ -27,7 +27,7 @@
v-model="customerModel.emailAddress"
ref="emailAddress"
customInputId="emailAddress"
validationRules="email-address-required|email-address-format" />
validationRules="email-address-format" />
</div>
</div>
<div class="row mb-4">
@ -49,7 +49,6 @@ import textBlock from "@/digital-components/text-block/text-block";
// DEFINE VALIDATION RULES
defineRule("first-name-required", required(errorMessages.FIRST_NAME_REQUIRED));
defineRule("last-name-required", required(errorMessages.LAST_NAME_REQUIRED));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(
"email-address-format",
regex(

View file

@ -151,7 +151,6 @@ export default {
if (
store.getters.order.vehicle.carId &&
store.getters.order.serviceLocation.zipCode &&
store.getters.order.customer.emailAddress &&
store.getters.pageData(fmgPageValues.ADDRESS_VEHICLES)
) {
return true;

View file

@ -44,8 +44,8 @@
cmsWidgetName="EmailAddressQuestionWidget"
v-model="emailAddress"
inputId="emailAddress"
isRequired
validationRules="email-address-required|email-address-format" />
disableAutoFill
validationRules="email-address-format" />
</div>
</div>
<div class="row mb-2">
@ -117,7 +117,6 @@ import { queryStrings } from "@/constants/query-strings";
// Define Validation Rules
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(
"email-address-format",
regex(

View file

@ -24,7 +24,7 @@
v-model="registrationZipCode"
customInputId="zip"
mask="#####"
validationRules="zip-required|zip-format" />
validationRules="registration-zip-required|zip-format" />
</div>
</div>
<div class="row mt-0">
@ -33,7 +33,7 @@
cmsWidgetName="EmailAddressQuestionWidget"
v-model="email"
customInputId="email"
validationRules="email-address-required|email-address-format" />
validationRules="email-address-format" />
</div>
</div>
<div class="row mb-2">
@ -114,9 +114,8 @@ import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule("license-plate-required", required(errorMessages.LICENSE_PLATE_REQUIRED));
defineRule("zip-required", required(errorMessages.REGISTRATION_ZIP_REQUIRED));
defineRule("registration-zip-required", required(errorMessages.REGISTRATION_ZIP_REQUIRED));
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(
"email-address-format",
regex(

View file

@ -59,7 +59,7 @@
v-model="emailAddress"
customInputId="emailAddress"
isRequired
validationRules="email-address-required|email-address-format" />
validationRules="email-address-format" />
</div>
</div>
<div class="row mb-2">
@ -152,7 +152,6 @@ import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(
"email-address-format",
regex(

View file

@ -156,6 +156,14 @@ const router = createRouter({
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
router.beforeEach(async (to, from, next) => {
// set lastNavigationPage here to capture state before API calls for analytics.
// use current page url query string name when to.name is "root" (due to unresolved navigation in beforeEach)
router.lastNavigationPage = to.name == "root" ? analyticsMixin.methods.getPageName() : to.name;
next();
});
router.afterEach(async (to, from) => {
// Update lastPageVisited in the store
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);

View file

@ -8,6 +8,7 @@ import { storeActions } from "@/constants/store-actions";
import { applicationConfig } from "@/constants/application-config";
import { experimentTriggers } from "@/constants/experiments";
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
import { singleWindshieldCarIds } from "@/constants/single-windshield-carids";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
import { deepEqual } from "@/helpers/object-helper";
@ -642,13 +643,28 @@ export const actions = {
},
lookupVinByImage(context, image) {
const data = new FormData();
data.append("vinImage", image);
return globalMethods.callHttpClient({
method: endpoints.LookupVinByImage.method,
endpoint: endpoints.LookupVinByImage.url,
payload: data,
isFormData: true,
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = (e) => {
resolve(reader.result);
};
reader.readAsDataURL(image);
}).then((result) => {
const components = result.split(",");
const contentType = image.type;
const imageBase64 = components[1];
const data = {
imageData: imageBase64,
contentType: contentType,
fileName: image.name,
};
return globalMethods.callHttpClient({
method: endpoints.LookupVinByImage.method,
endpoint: endpoints.LookupVinByImage.url,
payload: data,
});
});
},
@ -1346,7 +1362,7 @@ export const actions = {
},
},
customer: {
emailAddress: order.customer.emailAddress,
emailAddress: order.customer.emailAddress || null,
},
damage: {
numberOfChips: damage.numberOfChips,
@ -1943,6 +1959,19 @@ export const actions = {
},
isVinOptionalVehicle(context) {
//Optional for carIds with only a single windshield
if (
singleWindshieldCarIds.find((item) => item === context.state.order.vehicle.carId) &&
context.state.order.damage.glassToReplace.length == 1 &&
context.state.order.damage.glassToReplace.find(
(glassToReplace) =>
glassToReplace.glassLocation.toLowerCase() ===
damageLocationsSelected.WINDSHIELD.toLowerCase()
)
) {
return true;
}
//Optional for specific YMMSs
switch (context.state.order.vehicle.make.toLowerCase()) {
case "mercedes benz":
case "volkswagen":
@ -1951,14 +1980,12 @@ 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

View file

@ -406,14 +406,16 @@ describe("Actions", () => {
it("lookupVinByImage action, should return list of vins", async () => {
// Arrange
const context = state;
const dummyImage = {};
const image = new File([], "test.jpg", {
type: "image/jpeg",
});
globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: ["1C6JJTAG3NL134044"] });
});
// Act
const response = await actions.lookupVinByImage(context, dummyImage);
const response = await actions.lookupVinByImage(context, image);
// Assert
expect(response.data).toEqual(["1C6JJTAG3NL134044"]);
@ -422,7 +424,9 @@ describe("Actions", () => {
it("lookupVinByImage action, should reject if error in calling API", async () => {
// Arrange
const context = state;
const dummyImage = {};
const image = new File([], "test.jpg", {
type: "image/jpeg",
});
globalMethods.callHttpClient.mockImplementation(() => {
return Promise.reject("An error occurred");
@ -431,9 +435,7 @@ describe("Actions", () => {
// Act
// Assert
await expect(actions.lookupVinByImage(context, dummyImage)).rejects.toEqual(
"An error occurred"
);
await expect(actions.lookupVinByImage(context, image)).rejects.toEqual("An error occurred");
});
it("getVehicleMakes action, should return makes list", async () => {
@ -3209,6 +3211,36 @@ describe("isVinOptionalVehicle", () => {
},
};
var vinOptionalResult = actions.isVinOptionalVehicle(context);
expect(vinOptionalResult).toEqual(expectedVinSkip);
}
);
const testcarID = [
["CR00000100", "make", [{ glassLocation: "driver" }], false],
["CR00067899", "make2", [{ glassLocation: "windshield" }], true],
[
"CR00062396",
"make3",
[{ glassLocation: "windshield" }, { glassLocation: "driver" }],
false,
],
["CR00066428", "make4", [{ glassLocation: "rear" }], false],
];
test.each(testcarID)(
"%s %s %o should skip vin lookup is %s",
async (carId, make, glassLocation, expectedVinSkip) => {
const context = state;
context.state = {
order: {
vehicle: { make: make, carId: carId },
damage: {
glassToReplace: glassLocation,
},
},
};
var vinOptionalResult = actions.isVinOptionalVehicle(context);
expect(vinOptionalResult).toEqual(expectedVinSkip);
}