Merge branch 'develop' into feature/digital/SSR-179
This commit is contained in:
commit
a59440d823
15 changed files with 769 additions and 423 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
// Components
|
// Components
|
||||||
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
import addressQuestions from "@/common-components/address-questions/address-questions";
|
||||||
import alert from "@/ux-components/alert/alert";
|
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { mount, shallowMount } from "@vue/test-utils";
|
import { mount, shallowMount } from "@vue/test-utils";
|
||||||
|
|
@ -7,7 +7,6 @@ import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { useMainStore } from "@/store";
|
import { useMainStore } from "@/store";
|
||||||
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
import e from "express";
|
|
||||||
|
|
||||||
jest.mock("@/helpers/damage-helper", () => ({
|
jest.mock("@/helpers/damage-helper", () => ({
|
||||||
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
|
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
|
||||||
|
|
@ -21,48 +20,6 @@ jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
|
||||||
describe("address-lookup.vue", () => {
|
describe("address-lookup.vue", () => {
|
||||||
describe("page level alerts", () => {
|
describe("page level alerts", () => {
|
||||||
test("if the address is not serviceable display the Non-Serviceable Zip Alert", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockRegistrationAddress = {
|
|
||||||
streetAddress: "1234 Main St",
|
|
||||||
city: "Columbus",
|
|
||||||
state: "OH",
|
|
||||||
zipCode: "43215",
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
isZipValid: true,
|
|
||||||
isZipServiceable: false,
|
|
||||||
vinVehicles: [
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN",
|
|
||||||
vehicle: {
|
|
||||||
carId: "C0000",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN",
|
|
||||||
vehicle: {
|
|
||||||
carId: "C0000",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
await wrapper.setData({
|
|
||||||
customerQuestions: {
|
|
||||||
addressQuestions: mockRegistrationAddress,
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("if the address matches a different vehicle display the Matched Different VehicleAlert", async () => {
|
test("if the address matches a different vehicle display the Matched Different VehicleAlert", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockRegistrationAddress = {
|
const mockRegistrationAddress = {
|
||||||
|
|
@ -73,7 +30,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
vinVehicles: [
|
vinVehicles: [
|
||||||
{
|
{
|
||||||
vehicle: {
|
vehicle: {
|
||||||
|
|
@ -110,7 +66,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
isStatePermissible: false,
|
isStatePermissible: false,
|
||||||
lookupVinbyAddressResponse: {
|
lookupVinbyAddressResponse: {
|
||||||
isStatePermissible: false,
|
isStatePermissible: false,
|
||||||
|
|
@ -158,7 +113,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
lookupVinbyAddressResponse: {
|
lookupVinbyAddressResponse: {
|
||||||
isStatePermissible: true,
|
isStatePermissible: true,
|
||||||
vinVehicles: [], // Return no vehicles
|
vinVehicles: [], // Return no vehicles
|
||||||
|
|
@ -188,7 +142,6 @@ describe("address-lookup.vue", () => {
|
||||||
test("if the back button is clicked, navigate back", async () => {
|
test("if the back button is clicked, navigate back", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -198,7 +151,7 @@ describe("address-lookup.vue", () => {
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("if the car entered matches one of the vehicles found and the zip is serviceable, navigate forward", async () => {
|
test("if the car entered matches one of the vehicles found navigate forward", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockRegistrationAddress = {
|
const mockRegistrationAddress = {
|
||||||
streetAddress: "1234 Main St",
|
streetAddress: "1234 Main St",
|
||||||
|
|
@ -208,7 +161,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
vinVehicles: [
|
vinVehicles: [
|
||||||
{
|
{
|
||||||
vehicle: {
|
vehicle: {
|
||||||
|
|
@ -244,7 +196,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
isStatePermissible: true,
|
isStatePermissible: true,
|
||||||
vinVehicles: [
|
vinVehicles: [
|
||||||
{
|
{
|
||||||
|
|
@ -299,52 +250,7 @@ describe("address-lookup.vue", () => {
|
||||||
carsFound
|
carsFound
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("if the car entered matches one of the vehicles found but the zip is NOT serviceable, do not navigate forward", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockRegistrationAddress = {
|
|
||||||
streetAddress: "1234 Main St",
|
|
||||||
city: "Columbus",
|
|
||||||
state: "OH",
|
|
||||||
zipCode: "43215",
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
isZipServiceable: false,
|
|
||||||
isStatePermissible: true,
|
|
||||||
vinVehicles: [
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN",
|
|
||||||
vehicle: {
|
|
||||||
carId: "CARID",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN2",
|
|
||||||
vehicle: {
|
|
||||||
carId: "CARID2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = "CARID";
|
|
||||||
|
|
||||||
await wrapper.setData({
|
|
||||||
customerQuestions: {
|
|
||||||
addressQuestions: mockRegistrationAddress,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper.vm.navigateForward = jest.fn();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.navigateForward).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page", async () => {
|
test("if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockRegistrationAddress = {
|
const mockRegistrationAddress = {
|
||||||
|
|
@ -355,7 +261,6 @@ describe("address-lookup.vue", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
isZipServiceable: true,
|
|
||||||
isStatePermissible: true,
|
isStatePermissible: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -450,135 +355,9 @@ describe("address-lookup.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("registration and service zips", () => {
|
|
||||||
describe("if registration zip is serviceable", () => {
|
|
||||||
test("if registration address is provided => update service address on successful continue", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockRegistrationAddress = {
|
|
||||||
streetAddress: "1234 Main St",
|
|
||||||
city: "Columbus",
|
|
||||||
state: "OH",
|
|
||||||
zipCode: "43215",
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
isZipServiceable: true,
|
|
||||||
isStatePermissible: true,
|
|
||||||
vinVehicles: [
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN",
|
|
||||||
vehicle: {
|
|
||||||
carId: "CARID",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
route: { query: "address-lookup" },
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = "CARID";
|
|
||||||
useMainStore().saveRegistrationAddressLookup = jest.fn();
|
|
||||||
|
|
||||||
await wrapper.setData({
|
|
||||||
customerQuestions: {
|
|
||||||
addressQuestions: mockRegistrationAddress,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(useMainStore().saveRegistrationAddressLookup).toHaveBeenCalled();
|
|
||||||
expect(useMainStore().validateZip).toHaveBeenCalledWith({ zip: "43215" });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("if registration zip is not serviceable", () => {
|
|
||||||
test("if registration address is provided and user clicks continue => show non-serviceable zip alert", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockRegistrationAddress = {
|
|
||||||
streetAddress: "1234 Main St",
|
|
||||||
city: "Columbus",
|
|
||||||
state: "OH",
|
|
||||||
zipCode: "43215",
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
isZipValid: true,
|
|
||||||
isZipServiceable: false,
|
|
||||||
vinVehicles: [
|
|
||||||
{
|
|
||||||
vin: "TEST_VIN",
|
|
||||||
vehicle: {
|
|
||||||
carId: "C0000",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = "C0000";
|
|
||||||
|
|
||||||
await wrapper.setData({
|
|
||||||
customerQuestions: {
|
|
||||||
addressQuestions: mockRegistrationAddress,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).exists()).toBe(
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.displayNonServiceableZipAlert).toBe(true);
|
|
||||||
expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).exists()).toBe(
|
|
||||||
true
|
|
||||||
);
|
|
||||||
expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(
|
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("if registration address, service zip are provided, and user clicks continue => don't update service address", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockRegistrationAddress = {
|
|
||||||
streetAddress: "1234 Main St",
|
|
||||||
city: "Columbus",
|
|
||||||
state: "OH",
|
|
||||||
zipCode: "43215",
|
|
||||||
};
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
isZipServiceable: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = "CARID";
|
|
||||||
|
|
||||||
await wrapper.setData({
|
|
||||||
customerQuestions: {
|
|
||||||
addressQuestions: mockRegistrationAddress,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().saveRegistrationAddressLookup = jest.fn();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(useMainStore().saveRegistrationAddressLookup).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
isZipValid = true,
|
|
||||||
isZipServiceable = true,
|
|
||||||
lookupVinbyAddressResponse,
|
lookupVinbyAddressResponse,
|
||||||
partsOrQuestions = [],
|
partsOrQuestions = [],
|
||||||
isStatePermissible = true,
|
isStatePermissible = true,
|
||||||
|
|
@ -587,16 +366,6 @@ function setupMocks({
|
||||||
route = null,
|
route = null,
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
||||||
useMainStore().validateZip = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
|
||||||
isValid: isZipValid,
|
|
||||||
isServiceable: isZipServiceable,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().lookupVinByAddress = jest.fn().mockImplementation(() => {
|
useMainStore().lookupVinByAddress = jest.fn().mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
data: lookupVinbyAddressResponse
|
data: lookupVinbyAddressResponse
|
||||||
|
|
@ -652,10 +421,6 @@ function setupMocks({
|
||||||
);
|
);
|
||||||
|
|
||||||
const apiResponses = {
|
const apiResponses = {
|
||||||
serviceZipValidationResponse: {
|
|
||||||
isValid: isZipValid,
|
|
||||||
isServiceable: isZipServiceable,
|
|
||||||
},
|
|
||||||
vinLookupResponse: {
|
vinLookupResponse: {
|
||||||
isStatePermissible: isStatePermissible,
|
isStatePermissible: isStatePermissible,
|
||||||
vinVehicles: vinVehicles,
|
vinVehicles: vinVehicles,
|
||||||
|
|
|
||||||
|
|
@ -28,21 +28,6 @@
|
||||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
v-bind:isDismissible="false" />
|
||||||
<alert
|
|
||||||
ref="alertInvalidZip"
|
|
||||||
v-if="displayInvalidZipAlert"
|
|
||||||
class="mb-4"
|
|
||||||
cmsWidgetName="AlertInvalidZipWidget"
|
|
||||||
alertClass="alert-danger"
|
|
||||||
v-bind:isDismissible="false" />
|
|
||||||
<alert
|
|
||||||
ref="alertNonServiceableZip"
|
|
||||||
v-if="displayNonServiceableZipAlert"
|
|
||||||
class="mb-4"
|
|
||||||
alertClass="alert-danger"
|
|
||||||
:manualHeadline="AlertNonServiceableZipHeader"
|
|
||||||
:manualCopy="AlertNonServiceableZipBody"
|
|
||||||
v-bind:isDismissible="false" />
|
|
||||||
<alert
|
<alert
|
||||||
ref="alertVinLookupsByHomeAddressNotAllowed"
|
ref="alertVinLookupsByHomeAddressNotAllowed"
|
||||||
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||||
|
|
@ -50,23 +35,9 @@
|
||||||
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
v-bind:isDismissible="false" />
|
v-bind:isDismissible="false" />
|
||||||
<transition name="fade" mode="out-in">
|
|
||||||
<div class="service-zip-field" v-if="showServiceZipField" aria-live="polite">
|
|
||||||
<div class="row mb-4">
|
|
||||||
<div class="col">
|
|
||||||
<textboxQuestion
|
|
||||||
cmsWidgetName="ServiceZipQuestionWidget"
|
|
||||||
v-model="serviceZipCode"
|
|
||||||
ref="serviceZip"
|
|
||||||
inputId="7add1b26df344f2caf1678de5797803f"
|
|
||||||
aria-haspopup=""
|
|
||||||
mask="#####"
|
|
||||||
validationRules="service-zip-required|service-zip-format" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
|
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
|
||||||
|
|
||||||
<siteFooter
|
<siteFooter
|
||||||
cmsWidgetName="SiteFooterWidget"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
ref="siteFooter"
|
ref="siteFooter"
|
||||||
|
|
@ -90,9 +61,7 @@ import customerQuestions from "@/layouts/address-lookup/customer-questions/custo
|
||||||
import alert from "@/ux-components/alert/alert";
|
import alert from "@/ux-components/alert/alert";
|
||||||
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
||||||
|
|
||||||
import { Form, defineRule } from "vee-validate";
|
import { Form } from "vee-validate";
|
||||||
import { required, regex } from "@/helpers/validation-rules";
|
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
|
@ -103,13 +72,6 @@ import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-help
|
||||||
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
||||||
import { useMainStore } from "@/store"
|
import { useMainStore } from "@/store"
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES - Note: Additional rules are defined in Customer Questions and Address Questions components
|
|
||||||
defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
|
|
||||||
defineRule(
|
|
||||||
"service-zip-format",
|
|
||||||
regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)
|
|
||||||
);
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "address-lookup",
|
name: "address-lookup",
|
||||||
mixins: [baseFormMixin, vinPagesMixin],
|
mixins: [baseFormMixin, vinPagesMixin],
|
||||||
|
|
@ -144,8 +106,6 @@ export default {
|
||||||
firstName: "",
|
firstName: "",
|
||||||
lastName: "",
|
lastName: "",
|
||||||
},
|
},
|
||||||
serviceZipCode: this.serviceZip,
|
|
||||||
displayNonServiceableZipAlert: false,
|
|
||||||
displayVinNotFoundAlert: false,
|
displayVinNotFoundAlert: false,
|
||||||
displayMatchedDifferentVehicleAlert: false,
|
displayMatchedDifferentVehicleAlert: false,
|
||||||
displayVinLookupByHomeAddressNotAllowedAlert: false,
|
displayVinLookupByHomeAddressNotAllowedAlert: false,
|
||||||
|
|
@ -153,9 +113,6 @@ export default {
|
||||||
isCarIdDifferent: false,
|
isCarIdDifferent: false,
|
||||||
isSelectedGlassAvailableForVehicle: true,
|
isSelectedGlassAvailableForVehicle: true,
|
||||||
customAlertData: {},
|
customAlertData: {},
|
||||||
displayInvalidZipAlert: false,
|
|
||||||
showServiceZipField: this.serviceZip,
|
|
||||||
isZipServiceable: false,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -201,13 +158,7 @@ export default {
|
||||||
{
|
{
|
||||||
resultKey: "vinLookupResponse",
|
resultKey: "vinLookupResponse",
|
||||||
promise: vinLookupResponse,
|
promise: vinLookupResponse,
|
||||||
},
|
}
|
||||||
{
|
|
||||||
resultKey: "serviceZipValidationResponse",
|
|
||||||
promise: this.serviceZipCode
|
|
||||||
? useMainStore().validateZip({zip: this.serviceZipCode})
|
|
||||||
: useMainStore().validateZip({zip: this.customerQuestions.addressQuestions.zipCode})
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
@ -219,14 +170,6 @@ export default {
|
||||||
return this.$refs.siteFooter.removeLoader();
|
return this.$refs.siteFooter.removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
|
|
||||||
const isZipValid = resultMap.serviceZipValidationResponse.isValid;
|
|
||||||
if (this.serviceZipCode && !isZipValid) {
|
|
||||||
this.displayInvalidZipAlert = true;
|
|
||||||
return this.$refs.siteFooter.removeLoader();
|
|
||||||
}
|
|
||||||
this.displayInvalidZipAlert = false;
|
|
||||||
|
|
||||||
const carsFound = resultMap.vinLookupResponse.vinVehicles;
|
const carsFound = resultMap.vinLookupResponse.vinVehicles;
|
||||||
|
|
||||||
// Handle cases for different amounts of VINS found for the address.
|
// Handle cases for different amounts of VINS found for the address.
|
||||||
|
|
@ -252,11 +195,11 @@ export default {
|
||||||
return this.$refs.siteFooter.removeLoader();
|
return this.$refs.siteFooter.removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
// update data if the zip or service zip is serviceable
|
// update data
|
||||||
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
|
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
|
||||||
} else if (carsFound.length > 1) {
|
} else if (carsFound.length > 1) {
|
||||||
|
|
||||||
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
|
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
|
||||||
// so we can go to the Heritage Funnel directly
|
|
||||||
const matchingCars = carsFound.filter(
|
const matchingCars = carsFound.filter(
|
||||||
(vin) => vin.vehicle.carId === this.mainStore.order.vehicle.carId
|
(vin) => vin.vehicle.carId === this.mainStore.order.vehicle.carId
|
||||||
);
|
);
|
||||||
|
|
@ -273,52 +216,26 @@ export default {
|
||||||
return this.$refs.siteFooter.removeLoader();
|
return this.$refs.siteFooter.removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the either the registration zip code or service zip code are not serviceable
|
|
||||||
this.isZipServiceable = resultMap.serviceZipValidationResponse.isServiceable;
|
|
||||||
if (!this.isZipServiceable) {
|
|
||||||
this.displayNonServiceableZipAlert = true;
|
|
||||||
this.$refs.siteFooter.disableForwardButton();
|
|
||||||
this.showServiceZipField = true;
|
|
||||||
return this.$refs.siteFooter.removeLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the registration zip code is serviceable and nothing was entered for the service zip code
|
|
||||||
// then set the service zip code to the registration zip code
|
|
||||||
if (!this.serviceZipCode) {
|
|
||||||
this.serviceZipCode = this.customerQuestions.addressQuestions.zipCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save vehicle, customer, service and registration information
|
// Save vehicle, customer, service and registration information
|
||||||
await useMainStore().saveRegistrationAddressLookup(
|
await useMainStore().saveRegistrationAddressLookup(
|
||||||
{
|
{
|
||||||
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||||
vehicleInfo:
|
vehicleInfo:
|
||||||
Object.keys(vehicleInfoToCommit).length === 0
|
Object.keys(vehicleInfoToCommit).length === 0
|
||||||
? this.mainStore.order.vehicle
|
? useMainStore().order.vehicle
|
||||||
: vehicleInfoToCommit,
|
: vehicleInfoToCommit,
|
||||||
registrationInfo: {
|
registrationInfo: {
|
||||||
firstName: this.customerQuestions.firstName,
|
firstName: this.customerQuestions.firstName,
|
||||||
lastName: this.customerQuestions.lastName,
|
lastName: this.customerQuestions.lastName,
|
||||||
address: this.customerQuestions.addressQuestions.streetAddress,
|
address: this.customerQuestions.addressQuestions.streetAddress,
|
||||||
city: this.customerQuestions.addressQuestions.city,
|
city: this.customerQuestions.addressQuestions.city,
|
||||||
state: resultMap.serviceZipValidationResponse.state,
|
state: this.customerQuestions.addressQuestions.state,
|
||||||
zipCode: this.customerQuestions.addressQuestions.zipCode,
|
zipCode: this.customerQuestions.addressQuestions.zipCode,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
await useMainStore().saveServiceLocation(
|
|
||||||
{
|
|
||||||
address: this.customerQuestions.addressQuestions.streetAddress,
|
|
||||||
city: this.customerQuestions.addressQuestions.city,
|
|
||||||
zipCode: this.serviceZipCode,
|
|
||||||
state: resultMap.serviceZipValidationResponse.state,
|
|
||||||
zipCodeCtu: resultMap.serviceZipValidationResponse.zipCodeCtu,
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
return await this.navigateForward(carsFound);
|
return await this.navigateForward(carsFound);
|
||||||
},
|
},
|
||||||
async navigateForward(carsFound) {
|
async navigateForward(carsFound) {
|
||||||
|
|
@ -353,7 +270,6 @@ export default {
|
||||||
},
|
},
|
||||||
resetWarningsAndErrors() {
|
resetWarningsAndErrors() {
|
||||||
this.displayVinNotFoundAlert = false;
|
this.displayVinNotFoundAlert = false;
|
||||||
this.displayNonServiceableZipAlert = false;
|
|
||||||
this.displayMatchedDifferentVehicleAlert = false;
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||||
this.$refs.siteFooter.enableForwardAction();
|
this.$refs.siteFooter.enableForwardAction();
|
||||||
|
|
@ -364,19 +280,6 @@ export default {
|
||||||
this.loadDefaultsFromStore();
|
this.loadDefaultsFromStore();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
AlertNonServiceableZipHeader() {
|
|
||||||
const zipCode = this.serviceZipCode
|
|
||||||
? this.serviceZipCode
|
|
||||||
: this.customerQuestions.addressQuestions.zipCode;
|
|
||||||
const text = this.getCmsContent(
|
|
||||||
"AlertNonServiceableZipWidget",
|
|
||||||
"HeadlineText"
|
|
||||||
).replaceAll("{custom:serviceZip}", zipCode);
|
|
||||||
return text;
|
|
||||||
},
|
|
||||||
AlertNonServiceableZipBody() {
|
|
||||||
return this.getCmsContent("AlertNonServiceableZipWidget", "BodyText");
|
|
||||||
},
|
|
||||||
AlertMatchedDifferentVehicleHeader() {
|
AlertMatchedDifferentVehicleHeader() {
|
||||||
return this.getCmsContent(
|
return this.getCmsContent(
|
||||||
"AlertMatchedDifferentVehicleWidget",
|
"AlertMatchedDifferentVehicleWidget",
|
||||||
|
|
@ -400,25 +303,10 @@ export default {
|
||||||
this.$refs.siteFooter.updateButtonText(
|
this.$refs.siteFooter.updateButtonText(
|
||||||
this.getCmsContent("siteFooterWidget", "ForwardButtonText")
|
this.getCmsContent("siteFooterWidget", "ForwardButtonText")
|
||||||
);
|
);
|
||||||
this.showServiceZipField = false;
|
|
||||||
this.resetWarningsAndErrors();
|
this.resetWarningsAndErrors();
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
}
|
||||||
serviceZipCode: {
|
|
||||||
handler(newValue) {
|
|
||||||
// If they modify the service zip code, then hide the error message.
|
|
||||||
this.resetWarningsAndErrors();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
showServiceZipField: {
|
|
||||||
handler(newValue) {
|
|
||||||
// If the Service Zip Code field is ever hidden, clear out it's value
|
|
||||||
if (!newValue) {
|
|
||||||
this.serviceZipCode = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
siteHeader,
|
siteHeader,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
import addressQuestions from "@/common-components/address-questions/address-questions";
|
||||||
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
||||||
import { defineRule } from "vee-validate";
|
import { defineRule } from "vee-validate";
|
||||||
import { required } from "@/helpers/validation-rules";
|
import { required } from "@/helpers/validation-rules";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* eslint-env jest */
|
||||||
|
import { render } from '@testing-library/vue';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import VinLocationInformationComponent from './vin-location-information.vue';
|
||||||
|
|
||||||
|
const mockText = Object.freeze({
|
||||||
|
HEADER: 'Mock Header',
|
||||||
|
BODY: 'Mock Body',
|
||||||
|
});
|
||||||
|
|
||||||
|
const mountOptions = {
|
||||||
|
global: {
|
||||||
|
mixins: [
|
||||||
|
{
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((cmsWidgetName, fieldName) => {
|
||||||
|
if (cmsWidgetName === 'WhereCanIFindMyVINToggle') {
|
||||||
|
if (fieldName === 'HeaderText') {
|
||||||
|
return mockText.HEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldName === 'BodyText') {
|
||||||
|
return mockText.BODY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('vin-location-information.vue', () => {
|
||||||
|
test('VIN Location Detail is NOT displayed on the screen as a default.', () => {
|
||||||
|
const { container } = render(VinLocationInformationComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||||
|
|
||||||
|
expect(vinLocationDetailSection).not.toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Toggling VIN Location Detail', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
const { container, getByText } = render(VinLocationInformationComponent, mountOptions);
|
||||||
|
const toggleLink = getByText(mockText.HEADER);
|
||||||
|
|
||||||
|
await user.click(toggleLink);
|
||||||
|
let vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||||
|
expect(vinLocationDetailSection).toBeVisible();
|
||||||
|
|
||||||
|
await user.click(toggleLink);
|
||||||
|
vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||||
|
expect(vinLocationDetailSection).not.toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
cmsWidgetName="AlertVinNotFoundWidget"
|
cmsWidgetName="AlertVinNotFoundWidget"
|
||||||
id="vehicle-not-found-alert"
|
id="vehicle-not-found-alert"
|
||||||
|
aria-label="vehicle-not-found-alert"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||||
:manualCopy="body"
|
:manualCopy="body"
|
||||||
:manualHeadline="header"
|
:manualHeadline="header"
|
||||||
|
aria-label="vehicle-not-matched-alert"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* eslint-env jest */
|
||||||
|
import { getDamageString } from '@/helpers/damage-helper';
|
||||||
|
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
|
||||||
|
import { RouterLinkStub } from '@vue/test-utils';
|
||||||
|
import { render } from '@testing-library/vue';
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import VinLookupAlertsComponent from './vin-lookup-alerts.vue';
|
||||||
|
|
||||||
|
jest.mock('@/helpers/damage-helper');
|
||||||
|
|
||||||
|
const mountOptions = {
|
||||||
|
global: {
|
||||||
|
stubs: {
|
||||||
|
RouterLink: RouterLinkStub,
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
{
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn(() => ''),
|
||||||
|
getFooterInfoBoxHeight: jest.fn(() => 80),
|
||||||
|
cssClassNameForCmsWidget: jest.fn(() => 'widget-name-mock-class'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('vin-lookup-alerts.vue', () => {
|
||||||
|
test('VehicleNotFoundAlert is displayed on the screen', () => {
|
||||||
|
mountOptions.props = {
|
||||||
|
activeAlertType: vehicleLookupAlertTypes.NOT_FOUND,
|
||||||
|
};
|
||||||
|
const { queryByRole } = render(VinLookupAlertsComponent, mountOptions);
|
||||||
|
const vehicleNotFoundAlert = queryByRole('alert', { name: 'vehicle-not-found-alert' });
|
||||||
|
const vehicleNotMatchedAlert = queryByRole('alert', { name: 'vehicle-not-matched-alert' });
|
||||||
|
|
||||||
|
expect(vehicleNotFoundAlert).toBeVisible();
|
||||||
|
expect(vehicleNotMatchedAlert).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('VehicleNotMatchedAlert is displayed on the screen', () => {
|
||||||
|
getDamageString.mockImplementation(() => 'Mock Damage String');
|
||||||
|
mountOptions.props = {
|
||||||
|
activeAlertType: vehicleLookupAlertTypes.NOT_MATCHED,
|
||||||
|
};
|
||||||
|
mountOptions.global.provide = {
|
||||||
|
vehicleFromLookup: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { queryByRole } = render(VinLookupAlertsComponent, mountOptions);
|
||||||
|
const vehicleNotFoundAlert = queryByRole('alert', { name: 'vehicle-not-found-alert' });
|
||||||
|
const vehicleNotMatchedAlert = queryByRole('alert', { name: 'vehicle-not-matched-alert' });
|
||||||
|
|
||||||
|
expect(vehicleNotFoundAlert).toEqual(null);
|
||||||
|
expect(vehicleNotMatchedAlert).toBeVisible();
|
||||||
|
});
|
||||||
|
});
|
||||||
453
src/layouts/vin-lookup/vin-lookup.spec.js
Normal file
453
src/layouts/vin-lookup/vin-lookup.spec.js
Normal file
|
|
@ -0,0 +1,453 @@
|
||||||
|
/* eslint-env jest */
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import { flushPromises } from '@vue/test-utils';
|
||||||
|
import { render, waitFor } from '@testing-library/vue';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { errorMessages } from '@/constants/error-messages';
|
||||||
|
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||||
|
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
||||||
|
import { routerParams } from '@/router/router-params';
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
import VinLookupComponent from './vin-lookup.vue';
|
||||||
|
|
||||||
|
const continueButtonQuerySelector = '[data-test-id="site-footer-main-button"]';
|
||||||
|
const errorMessageWrapperElSelector = '#vin-question-wrapper .form-test-error';
|
||||||
|
const vinInputSelector = '#vin-question';
|
||||||
|
const mockValidVin = '12345678901234567';
|
||||||
|
const mockCarId = 'Mock Car Id';
|
||||||
|
const lookupVehicleByVin = {
|
||||||
|
methodName: 'lookupVehicleByVin',
|
||||||
|
mockResponse: {
|
||||||
|
data: {
|
||||||
|
carId: mockCarId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const getPartsOrQuestions = {
|
||||||
|
methodName: 'getPartsOrQuestions',
|
||||||
|
mockResponse: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const vehicleWithPartQuestionsMockResponse = {
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vehicleWithMultiplePartsMockResponse = {
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vehicleWithMoldingQuestionsMockResponse = {
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
childPartQuestions: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vehicleWithCapabilityQuestionsMockResponse = {
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
requiresCapabilityQuestions: true,
|
||||||
|
partNumber: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vehicleWithNoAdditionalPartsOrQuestionsMockResponse = {
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
childPartQuestions: [],
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
partQuestions: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockRoute = {
|
||||||
|
query: {
|
||||||
|
// Needed inside vehicle-questions-mixin
|
||||||
|
issPage: issPageValues.VIN_LOOKUP,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mockRouter = {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
};
|
||||||
|
const maska = jest.fn();
|
||||||
|
jest.mock('@/helpers/damage-helper', () => ({
|
||||||
|
isGlassAvailableForCarId: jest.fn().mockResolvedValue(false),
|
||||||
|
}));
|
||||||
|
const mountOptions = {
|
||||||
|
global: {
|
||||||
|
directives: {
|
||||||
|
maska,
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
{
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn(() => ''),
|
||||||
|
getFooterInfoBoxHeight: jest.fn(() => 80),
|
||||||
|
cssClassNameForCmsWidget: jest.fn(() => 'widget-name-mock-class'),
|
||||||
|
getPageNameByQueryString: jest.fn(() => ''),
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
navigationScenarios() {
|
||||||
|
return navigationScenarios;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
mocks: {
|
||||||
|
$route: mockRoute,
|
||||||
|
$router: mockRouter,
|
||||||
|
},
|
||||||
|
plugins: [createTestingPinia({
|
||||||
|
initialState: {
|
||||||
|
main: {
|
||||||
|
order: {
|
||||||
|
vehicle: {
|
||||||
|
carId: mockCarId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stubActions: false,
|
||||||
|
})],
|
||||||
|
stubs: {
|
||||||
|
siteHeader: true,
|
||||||
|
siteSubHeader: true,
|
||||||
|
vehicleBanner: true,
|
||||||
|
vinLocationInformation: true,
|
||||||
|
vinLookupAlerts: true,
|
||||||
|
vinQuestion: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('vin-lookup.vue', () => {
|
||||||
|
describe('Client-side validation', () => {
|
||||||
|
test.each([
|
||||||
|
{ vin: null },
|
||||||
|
{ vin: '' },
|
||||||
|
])('VIN Required error messsage is displayed.', async ({ vin }) => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.data = () => ({
|
||||||
|
vin,
|
||||||
|
});
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
|
||||||
|
user.click(continueButton);
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||||
|
expect(errorMessageWrapperEl).toBeVisible();
|
||||||
|
|
||||||
|
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||||
|
expect(errorMessageEl.textContent).toBe(errorMessages.VIN_REQUIRED);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
{ vin: '11' },
|
||||||
|
{ vin: 'I1234567890123456' },
|
||||||
|
{ vin: 'O1234567890123456' },
|
||||||
|
{ vin: 'Q1234567890123456' },
|
||||||
|
])('VIN Invalid Format error messsage is displayed.', async ({ vin }) => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.data = () => ({
|
||||||
|
vin,
|
||||||
|
});
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
|
||||||
|
user.click(continueButton);
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||||
|
expect(errorMessageWrapperEl).toBeVisible();
|
||||||
|
|
||||||
|
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||||
|
expect(errorMessageEl.textContent).toBe(errorMessages.VIN_FORMAT);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('No error message is displayed when the vin is in the accepted format.', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.data = () => ({
|
||||||
|
vin: '12345678901234567',
|
||||||
|
});
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
|
||||||
|
user.click(continueButton);
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||||
|
expect(errorMessageWrapperEl).not.toBeVisible();
|
||||||
|
|
||||||
|
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||||
|
expect(errorMessageEl.textContent).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Navigation', () => {
|
||||||
|
test('Click "Back", execute navigate with navigationScenario.CLICKED_BACK.', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
const backButton = container.querySelector('[data-test-id="site-footer-back-button"]');
|
||||||
|
|
||||||
|
await user.click(backButton);
|
||||||
|
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, mockRoute);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page.', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithPartQuestionsMockResponse;
|
||||||
|
lookupVehicleByVin.mockResponse.data.carId = 'Different Car Id';
|
||||||
|
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
|
||||||
|
mountOptions.data = () => ({
|
||||||
|
activeVehicleLookupAlertType: null,
|
||||||
|
needToLookupVehicle: false,
|
||||||
|
vehicleFromLookup: {
|
||||||
|
carId: 'Different Car Id',
|
||||||
|
},
|
||||||
|
vin: mockValidVin,
|
||||||
|
});
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
|
mockRoute,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Succesful navigateForward', () => {
|
||||||
|
test('Vehicle with Part Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_PART_QUESTIONS', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithPartQuestionsMockResponse;
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinInput = container.querySelector(vinInputSelector);
|
||||||
|
await user.type(vinInput, mockValidVin);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate)
|
||||||
|
.toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||||
|
mockRoute,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Vehicle with Multiple Parts. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithMultiplePartsMockResponse;
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinInput = container.querySelector(vinInputSelector);
|
||||||
|
await user.type(vinInput, mockValidVin);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate)
|
||||||
|
.toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
|
||||||
|
mockRoute,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Vehicle with Molding Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithMoldingQuestionsMockResponse;
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinInput = container.querySelector(vinInputSelector);
|
||||||
|
await user.type(vinInput, mockValidVin);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate)
|
||||||
|
.toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
|
||||||
|
mockRoute,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Vehicle with Capability Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
const store = useMainStore();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithCapabilityQuestionsMockResponse;
|
||||||
|
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
store.getCapabilityQuestions.mockResolvedValueOnce({ data: [] });
|
||||||
|
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinInput = container.querySelector(vinInputSelector);
|
||||||
|
await user.type(vinInput, mockValidVin);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate)
|
||||||
|
.toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
|
||||||
|
mockRoute,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Vehicle no additional Parts or Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
mountOptions.global.stubs.vinQuestion = false;
|
||||||
|
getPartsOrQuestions.mockResponse = vehicleWithNoAdditionalPartsOrQuestionsMockResponse;
|
||||||
|
|
||||||
|
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||||
|
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||||
|
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||||
|
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||||
|
|
||||||
|
const { container } = render(VinLookupComponent, mountOptions);
|
||||||
|
|
||||||
|
const vinInput = container.querySelector(vinInputSelector);
|
||||||
|
await user.type(vinInput, mockValidVin);
|
||||||
|
|
||||||
|
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||||
|
await user.click(continueButton);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockRouter.navigate)
|
||||||
|
.toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||||
|
mockRoute,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -40,15 +40,16 @@
|
||||||
<script>
|
<script>
|
||||||
// Import Supporting Files
|
// Import Supporting Files
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { endpoints } from '@/constants/endpoints';
|
|
||||||
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
|
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
|
||||||
import globalMethods from '@/global-methods';
|
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
|
import { isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
|
import { routerParams } from '@/router/router-params';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
|
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import siteFooter from '@/common-components/site-footer/site-footer.vue';
|
import siteFooter from '@/common-components/site-footer/site-footer.vue';
|
||||||
import siteHeader from '@/common-components/site-header/site-header.vue';
|
import siteHeader from '@/common-components/site-header/site-header.vue';
|
||||||
|
|
@ -60,7 +61,7 @@ import vinQuestion from './vin-question/vin-question.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'vin-lookup',
|
name: 'vin-lookup',
|
||||||
mixins: [baseFormMixin],
|
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
||||||
components: {
|
components: {
|
||||||
siteFooter,
|
siteFooter,
|
||||||
siteHeader,
|
siteHeader,
|
||||||
|
|
@ -79,8 +80,9 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeVehicleLookupAlertType: null,
|
activeVehicleLookupAlertType: null,
|
||||||
|
needToLookupVehicle: true,
|
||||||
vehicleFromLookup: null,
|
vehicleFromLookup: null,
|
||||||
vin: null,
|
vin: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
|
|
@ -105,6 +107,14 @@ export default {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isCarIdDifferentFromTheStore() {
|
||||||
|
return (
|
||||||
|
this.vehicleFromLookup !== null
|
||||||
|
&& this.vehicleFromLookup.carId !== this.mainStore.vehicle.carId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisiteValid() {
|
arePagePrerequisiteValid() {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -115,40 +125,77 @@ export default {
|
||||||
*/
|
*/
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
},
|
},
|
||||||
|
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
this.resetActiveAlert();
|
this.resetActiveAlert();
|
||||||
|
// Temp solution to reset the 'disabled' style on the Continue button
|
||||||
|
this.$refs.siteFooter.enableForwardAction();
|
||||||
|
|
||||||
|
if (this.needToLookupVehicle) {
|
||||||
|
const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin);
|
||||||
|
|
||||||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
if (vehicleLookupResponse.error) {
|
||||||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin);
|
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
|
||||||
|
this.resetVehicleFromLookup();
|
||||||
|
this.$refs.siteFooter.removeLoader();
|
||||||
|
// Temp solution to turn on 'disabled' style on the Continue button
|
||||||
|
// because the form itself actually passes its client-side validation.
|
||||||
|
// SSR-189 Scenario #4.
|
||||||
|
this.$refs.siteFooter.disableForwardButton();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (vehicleLookupResponse.error) {
|
// Add vin bcs the response from the service doesn't contain vin
|
||||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
|
this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { vin: this.vin });
|
||||||
this.resetVehicleFromLookup();
|
}
|
||||||
|
|
||||||
|
if (this.needToLookupVehicle && this.isCarIdDifferentFromTheStore) {
|
||||||
|
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_MATCHED;
|
||||||
|
|
||||||
|
const vehicleYearMakeModel = `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model}`;
|
||||||
|
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModel}`);
|
||||||
|
this.$refs.siteFooter.removeLoader();
|
||||||
|
|
||||||
|
this.needToLookupVehicle = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isSelectedGlassAvailableForVehicle = true;
|
||||||
|
if (this.isCarIdDifferentFromTheStore) {
|
||||||
|
isSelectedGlassAvailableForVehicle =
|
||||||
|
await isGlassAvailableForCarId(this.vehicleFromLookup.carId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// navigate back to vehicle-damage
|
||||||
|
if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) {
|
||||||
|
this.mainStore.updateVehicle(this.vehicleFromLookup);
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// navigate() doesn't stop the processing flow
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainStore.updateVehicle(this.vehicleFromLookup);
|
||||||
|
const partsOrQuestionsResponse = await this.getPartsOrQuestions();
|
||||||
|
if (partsOrQuestionsResponse.error) {
|
||||||
|
// To Do: Need requirement on what to do here
|
||||||
|
console.error('Error on retrieving PartsOrQuestions');
|
||||||
this.$refs.siteFooter.removeLoader();
|
this.$refs.siteFooter.removeLoader();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.vehicleFromLookup = vehicleLookupResponse.data;
|
// Comes from vehicleQuestionsMixin.navigateForward()
|
||||||
if (this.vehicleFromLookup.carId !== this.mainStore.vehicle.carId) {
|
await this.navigateForward(partsOrQuestionsResponse.data.partsOrQuestions, this);
|
||||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_MATCHED;
|
|
||||||
|
|
||||||
const vehicleYearMakeModel = `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model}`;
|
|
||||||
|
|
||||||
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModel}`);
|
|
||||||
this.$refs.siteFooter.removeLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue
|
|
||||||
},
|
},
|
||||||
async lookupVehicleByVin(vin) {
|
async getPartsOrQuestions() {
|
||||||
try {
|
try {
|
||||||
const response = await globalMethods.callHttpClient({
|
const response = await this.mainStore.getPartsOrQuestions();
|
||||||
method: endpoints.LookupVehicleByVin.method,
|
|
||||||
endpoint: endpoints.LookupVehicleByVin.url,
|
|
||||||
payload: {
|
|
||||||
vin,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (responseError) {
|
} catch (responseError) {
|
||||||
|
|
@ -159,6 +206,18 @@ export default {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async lookupVehicleByVin(vin) {
|
||||||
|
try {
|
||||||
|
return await this.mainStore.lookupVehicleByVin(vin);
|
||||||
|
}
|
||||||
|
catch (responseError) {
|
||||||
|
return {
|
||||||
|
error: {
|
||||||
|
status: responseError.status,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
resetActiveAlert() {
|
resetActiveAlert() {
|
||||||
this.activeVehicleLookupAlertType = null;
|
this.activeVehicleLookupAlertType = null;
|
||||||
},
|
},
|
||||||
|
|
@ -167,5 +226,15 @@ export default {
|
||||||
},
|
},
|
||||||
resetDependentState() {},
|
resetDependentState() {},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
vin() {
|
||||||
|
this.resetActiveAlert();
|
||||||
|
this.$refs.siteFooter.enableForwardAction();
|
||||||
|
this.needToLookupVehicle = true;
|
||||||
|
this.$refs.siteFooter.updateButtonText(
|
||||||
|
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
inputId="policyNumberField"
|
inputId="policyNumberField"
|
||||||
cmsWidgetName="PolicyNumberQuestion"
|
cmsWidgetName="PolicyNumberQuestion"
|
||||||
v-model="policyNumber"
|
v-model="welcomePageModel.policyNumber"
|
||||||
isRequired
|
isRequired
|
||||||
ref="policyNumber"
|
ref="policyNumber"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
type="date"
|
type="date"
|
||||||
cmsWidgetName="DateOfLossQuestion"
|
cmsWidgetName="DateOfLossQuestion"
|
||||||
v-model="dateOfLoss"
|
v-model="welcomePageModel.dateOfLoss"
|
||||||
inputId="dateOfLossField"
|
inputId="dateOfLossField"
|
||||||
isRequired
|
isRequired
|
||||||
ref="dateOfLoss"
|
ref="dateOfLoss"
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<dropdownQuestion
|
<dropdownQuestion
|
||||||
cmsWidgetName="DamageCauseQuestion"
|
cmsWidgetName="DamageCauseQuestion"
|
||||||
v-model="damageCause"
|
v-model="welcomePageModel.damageCause"
|
||||||
ref="damageCause"
|
ref="damageCause"
|
||||||
inputId="damageCauseQuestionField"
|
inputId="damageCauseQuestionField"
|
||||||
:options="DamageCauseOptions"
|
:options="DamageCauseOptions"
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
inputId="damageCityField"
|
inputId="damageCityField"
|
||||||
cmsWidgetName="DamageCityQuestion"
|
cmsWidgetName="DamageCityQuestion"
|
||||||
v-model="damageCity"
|
v-model="welcomePageModel.damageCity"
|
||||||
isRequired
|
isRequired
|
||||||
ref="damageCity"
|
ref="damageCity"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<dropdownQuestion
|
<dropdownQuestion
|
||||||
cmsWidgetName="DamageStateQuestion"
|
cmsWidgetName="DamageStateQuestion"
|
||||||
v-model="damageState"
|
v-model="welcomePageModel.damageState"
|
||||||
ref="state"
|
ref="state"
|
||||||
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
||||||
:options="stateOptions"
|
:options="stateOptions"
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<buttonQuestion
|
<buttonQuestion
|
||||||
cmsWidgetName="GlassOnlyQuestion"
|
cmsWidgetName="GlassOnlyQuestion"
|
||||||
v-model="isDamageGlassOnly"
|
v-model="welcomePageModel.isDamageGlassOnly"
|
||||||
inputId = "isDamageGlassOnly"
|
inputId = "isDamageGlassOnly"
|
||||||
:answers="DamageGlassOnlyOptions"
|
:answers="DamageGlassOnlyOptions"
|
||||||
:questionText="DamageGlassOnlyQuestion"
|
:questionText="DamageGlassOnlyQuestion"
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
inputId="phoneNumberField"
|
inputId="phoneNumberField"
|
||||||
cmsWidgetName="PhoneNumberQuestion"
|
cmsWidgetName="PhoneNumberQuestion"
|
||||||
v-model="phoneNumber"
|
v-model="welcomePageModel.phoneNumber"
|
||||||
validationRules="phone-number-required|phone-number-format"
|
validationRules="phone-number-required|phone-number-format"
|
||||||
isRequired
|
isRequired
|
||||||
ref="phoneNumber"
|
ref="phoneNumber"
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
inputId="emailField"
|
inputId="emailField"
|
||||||
cmsWidgetName="EmailAddressQuestion"
|
cmsWidgetName="EmailAddressQuestion"
|
||||||
v-model="email"
|
v-model="welcomePageModel.email"
|
||||||
ref="email"
|
ref="email"
|
||||||
validationRules="email-address-required|email-address-format"
|
validationRules="email-address-required|email-address-format"
|
||||||
isRequired
|
isRequired
|
||||||
|
|
@ -145,6 +145,7 @@
|
||||||
import { required, regex } from "@/helpers/validation-rules";
|
import { required, regex } from "@/helpers/validation-rules";
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
//define validation rules
|
//define validation rules
|
||||||
defineRule("loss-date-required", required(errorMessages.LOSS_DATE_REQUIRED));
|
defineRule("loss-date-required", required(errorMessages.LOSS_DATE_REQUIRED));
|
||||||
|
|
@ -176,17 +177,13 @@
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
policyNumber: "",
|
welcomePageModel: this.getWelcomePageModelFromStore()
|
||||||
policyZipCode: "",
|
|
||||||
dateOfLoss: "",
|
|
||||||
damageCause: "",
|
|
||||||
damageState: "",
|
|
||||||
damageCity: "",
|
|
||||||
isDamageGlassOnly: "",
|
|
||||||
phoneNumber: "",
|
|
||||||
email: ""
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
return { mainStore };
|
||||||
|
},
|
||||||
async beforeRouteEnter(to, from, next)
|
async beforeRouteEnter(to, from, next)
|
||||||
{
|
{
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -210,6 +207,7 @@
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
|
this.mainStore.updatePolicyData(this.welcomePageModel);
|
||||||
return this.navigateForward();
|
return this.navigateForward();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -219,20 +217,32 @@
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
getWelcomePageModelFromStore() {
|
||||||
|
return {
|
||||||
|
policyNumber : this.mainStore.order.policy.policyNumber,
|
||||||
|
dateOfLoss : this.mainStore.order.policy.dateOfLoss,
|
||||||
|
damageCause : this.mainStore.order.policy.damageCause,
|
||||||
|
damageState : this.mainStore.order.policy.damageState,
|
||||||
|
damageCity : this.mainStore.order.policy.damageCity,
|
||||||
|
isDamageGlassOnly : this.mainStore.order.policy.isDamageGlassOnly,
|
||||||
|
phoneNumber : this.mainStore.order.customer.phoneNumber,
|
||||||
|
email : this.mainStore.order.customer.emailAddress,
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed:{
|
computed:{
|
||||||
DamageCauseOptions() {
|
DamageCauseOptions() {
|
||||||
const damageCauseAnswers = this.getCmsContent("DamageCauseQuestion", "Answers");
|
const damageCauseAnswers = this.getCmsContent("DamageCauseQuestion", "Answers");
|
||||||
const answerArray = [];
|
const damageCauseAnswersObj ={};
|
||||||
if(damageCauseAnswers)
|
if(damageCauseAnswers)
|
||||||
{
|
{
|
||||||
for (let answer of Object.values(damageCauseAnswers)) {
|
for (let answer of Object.values(damageCauseAnswers)) {
|
||||||
if (answer?.Name) {
|
if (answer?.Name) {
|
||||||
answerArray.push(answer.Name);
|
damageCauseAnswersObj[answer.Name] = answer.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return answerArray;
|
return damageCauseAnswersObj;
|
||||||
},
|
},
|
||||||
DamageGlassOnlyOptions()
|
DamageGlassOnlyOptions()
|
||||||
{
|
{
|
||||||
|
|
@ -299,14 +309,6 @@
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
welcomePageModel: {
|
|
||||||
get: function () {
|
|
||||||
return this.modelValue;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
this.$emit("update:modelValue", newValue);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
siteHeader,
|
siteHeader,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,31 @@ const routingTable = function(store) {
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP,
|
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||||
|
destinationIssPageValue: issPageValues.PART_QUESTIONS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_PARTS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
|
||||||
|
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
|
||||||
|
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||||
|
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const routerParams = {
|
const routerParams = Object.freeze({
|
||||||
DISPLAY_VEHICLE_CHANGE_ALERT: "displayVehicleChangeAlert",
|
DISPLAY_VEHICLE_CHANGE_ALERT: "displayVehicleChangeAlert",
|
||||||
};
|
});
|
||||||
|
|
||||||
export { routerParams };
|
export { routerParams };
|
||||||
|
|
@ -41,6 +41,14 @@ const getDefaultState = () => {
|
||||||
moldingQuestionAnswers: null,
|
moldingQuestionAnswers: null,
|
||||||
capabilityQuestionAnswers: null,
|
capabilityQuestionAnswers: null,
|
||||||
},
|
},
|
||||||
|
policy: {
|
||||||
|
policyNumber: null,
|
||||||
|
dateOfLoss: null,
|
||||||
|
damageCause: null,
|
||||||
|
damageState: null,
|
||||||
|
damageCity: null,
|
||||||
|
isDamageGlassOnly: null,
|
||||||
|
},
|
||||||
customer: {
|
customer: {
|
||||||
address: {
|
address: {
|
||||||
streetAddress: null,
|
streetAddress: null,
|
||||||
|
|
@ -51,6 +59,7 @@ const getDefaultState = () => {
|
||||||
firstName: null,
|
firstName: null,
|
||||||
lastName: null,
|
lastName: null,
|
||||||
emailAddress: null,
|
emailAddress: null,
|
||||||
|
phoneNumber: null,
|
||||||
},
|
},
|
||||||
serviceLocation: {
|
serviceLocation: {
|
||||||
address: null,
|
address: null,
|
||||||
|
|
@ -389,6 +398,16 @@ export const useMainStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
lookupVehicleByVin(vin) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.LookupVehicleByVin.method,
|
||||||
|
endpoint: endpoints.LookupVehicleByVin.url,
|
||||||
|
payload: {
|
||||||
|
vin,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setVehicle() {
|
setVehicle() {
|
||||||
return globalMethods
|
return globalMethods
|
||||||
.callHttpClient({
|
.callHttpClient({
|
||||||
|
|
@ -635,7 +654,17 @@ export const useMainStore = defineStore({
|
||||||
updatePageData(pageData) {
|
updatePageData(pageData) {
|
||||||
this.applicationUser.pageData[pageData.page] = pageData.data;
|
this.applicationUser.pageData[pageData.page] = pageData.data;
|
||||||
},
|
},
|
||||||
|
updatePolicyData(welcomePageModel)
|
||||||
|
{
|
||||||
|
this.order.policy.policyNumber = welcomePageModel?.policyNumber;
|
||||||
|
this.order.policy.dateOfLoss = welcomePageModel?.dateOfLoss;
|
||||||
|
this.order.policy.damageCause = welcomePageModel?.damageCause;
|
||||||
|
this.order.policy.damageState = welcomePageModel?.damageState;
|
||||||
|
this.order.policy.damageCity = welcomePageModel?.damageCity;
|
||||||
|
this.order.policy.isDamageGlassOnly = welcomePageModel?.isDamageGlassOnly;
|
||||||
|
this.order.customer.phoneNumber = welcomePageModel?.phoneNumber;
|
||||||
|
this.order.customer.emailAddress = welcomePageModel?.email;
|
||||||
|
},
|
||||||
savePartQuestionAnswers(partQuestionAnswersArray) {
|
savePartQuestionAnswers(partQuestionAnswersArray) {
|
||||||
// if part question answers have changed, reset subsequent question answers
|
// if part question answers have changed, reset subsequent question answers
|
||||||
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
|
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue