Merge branch 'develop' into defect/CSR-1467
This commit is contained in:
commit
8a119e89f4
10 changed files with 18988 additions and 36 deletions
18896
src/constants/single-windshield-carids.js
Normal file
18896
src/constants/single-windshield-carids.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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}`,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue