Merge branch 'release/2025.05.08' into feature/bugfix/CASH-501
This commit is contained in:
commit
02f317daee
17 changed files with 319 additions and 132 deletions
|
|
@ -18,9 +18,11 @@ pr:
|
||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: node
|
- container: node
|
||||||
image: packagerepository.sagaws.net:8082/safelite/node-build:18
|
image: ghcr.io/safelite/node-build:18
|
||||||
|
endpoint: GitHub Docker
|
||||||
- container: awscli
|
- container: awscli
|
||||||
image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9
|
image: ghcr.io/safelite/awscli2-build:3.9
|
||||||
|
endpoint: GitHub Docker
|
||||||
- container: prettier-node
|
- container: prettier-node
|
||||||
image: ghcr.io/safelite/prettier-node-build:23
|
image: ghcr.io/safelite/prettier-node-build:23
|
||||||
endpoint: GitHub Docker
|
endpoint: GitHub Docker
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ module.exports = {
|
||||||
testResultsProcessor: "jest-junit",
|
testResultsProcessor: "jest-junit",
|
||||||
preset: "@vue/cli-plugin-unit-jest",
|
preset: "@vue/cli-plugin-unit-jest",
|
||||||
transform: { "^.+\\.vue$": "@vue/vue3-jest" },
|
transform: { "^.+\\.vue$": "@vue/vue3-jest" },
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
'/node_modules/(?!.*\\.mjs$)',
|
||||||
|
],
|
||||||
moduleFileExtensions: ["js", "vue"],
|
moduleFileExtensions: ["js", "vue"],
|
||||||
modulePathIgnorePatterns: ["vin-lookup"],
|
modulePathIgnorePatterns: ["vin-lookup"],
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import salesforceWebchat from "./salesforce-webchat.vue";
|
||||||
import * as devHelper from "./salesforce-helper-dev";
|
import * as devHelper from "./salesforce-helper-dev";
|
||||||
import * as qaHelper from "./salesforce-helper-qa";
|
import * as qaHelper from "./salesforce-helper-qa";
|
||||||
import * as prodHelper from "./salesforce-helper-prod";
|
import * as prodHelper from "./salesforce-helper-prod";
|
||||||
|
import { applicationConfig } from "../../constants/application-config";
|
||||||
|
|
||||||
describe("salesforceWebchat.vue", () => {
|
describe("salesforceWebchat.vue", () => {
|
||||||
it("renders correctly", () => {
|
it("renders correctly", () => {
|
||||||
|
|
@ -21,19 +22,19 @@ describe("salesforceWebchat.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("calls the correct initialization function based on environment", () => {
|
it("calls the correct initialization function based on environment", () => {
|
||||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = "Prod";
|
applicationConfig.CURRENT_ENVIRONMENT = "Prod";
|
||||||
let wrapper = shallowMount(salesforceWebchat);
|
let wrapper = shallowMount(salesforceWebchat);
|
||||||
mockProd = jest.spyOn(prodHelper, "initializeSalesforceWebchatForProd");
|
mockProd = jest.spyOn(prodHelper, "initializeSalesforceWebchatForProd");
|
||||||
wrapper.vm.initializeSalesforceWebchat();
|
wrapper.vm.initializeSalesforceWebchat();
|
||||||
expect(mockProd).toHaveBeenCalled();
|
expect(mockProd).toHaveBeenCalled();
|
||||||
|
|
||||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = "QA";
|
applicationConfig.CURRENT_ENVIRONMENT = "QA";
|
||||||
wrapper = shallowMount(salesforceWebchat);
|
wrapper = shallowMount(salesforceWebchat);
|
||||||
mockQa = jest.spyOn(qaHelper, "initializeSalesforceWebchatForQa");
|
mockQa = jest.spyOn(qaHelper, "initializeSalesforceWebchatForQa");
|
||||||
wrapper.vm.initializeSalesforceWebchat();
|
wrapper.vm.initializeSalesforceWebchat();
|
||||||
expect(mockQa).toHaveBeenCalled();
|
expect(mockQa).toHaveBeenCalled();
|
||||||
|
|
||||||
process.env.VUE_APP_CURRENT_ENVIRONMENT = "Dev";
|
applicationConfig.CURRENT_ENVIRONMENT = "Dev";
|
||||||
wrapper = shallowMount(salesforceWebchat);
|
wrapper = shallowMount(salesforceWebchat);
|
||||||
mockDev = jest.spyOn(devHelper, "initializeSalesforceWebchatForDev");
|
mockDev = jest.spyOn(devHelper, "initializeSalesforceWebchatForDev");
|
||||||
wrapper.vm.initializeSalesforceWebchat();
|
wrapper.vm.initializeSalesforceWebchat();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
import { initializeSalesforceWebchatForDev } from "./salesforce-helper-dev";
|
import { initializeSalesforceWebchatForDev } from "./salesforce-helper-dev";
|
||||||
import { initializeSalesforceWebchatForQa } from "./salesforce-helper-qa";
|
import { initializeSalesforceWebchatForQa } from "./salesforce-helper-qa";
|
||||||
import { initializeSalesforceWebchatForProd } from "./salesforce-helper-prod";
|
import { initializeSalesforceWebchatForProd } from "./salesforce-helper-prod";
|
||||||
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "salesforceWebchat",
|
name: "salesforceWebchat",
|
||||||
|
|
@ -28,7 +29,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initializeSalesforceWebchat() {
|
initializeSalesforceWebchat() {
|
||||||
switch (process.env.VUE_APP_CURRENT_ENVIRONMENT) {
|
switch (applicationConfig.CURRENT_ENVIRONMENT) {
|
||||||
case "Prod":
|
case "Prod":
|
||||||
initializeSalesforceWebchatForProd();
|
initializeSalesforceWebchatForProd();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,23 @@ describe("address-lookup.vue", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true);
|
expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should hide the AlertNoService when displayNoServiceAlert is false", async () => {
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
isZipServiceable: true,
|
||||||
|
displayNoServiceAlert: false,
|
||||||
|
lookupVinbyAddressResponse: {
|
||||||
|
isStatePermissible: true,
|
||||||
|
vinVehicles: [], // Return no vehicles
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Ensure displayNoServiceAlert is false
|
||||||
|
await wrapper.setData({ displayNoServiceAlert: false });
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
// Check if the AlertNoService component is not rendered
|
||||||
|
const alertNoService = wrapper.findComponent({ ref: "AlertNoService" });
|
||||||
|
expect(alertNoService.exists()).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("navigation", () => {
|
describe("navigation", () => {
|
||||||
|
|
@ -741,6 +758,17 @@ function setupMocks({
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
|
wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
|
||||||
wrapper.vm.$refs.navbar.removeLoader = jest.fn();
|
wrapper.vm.$refs.navbar.removeLoader = jest.fn();
|
||||||
|
const closestShops = {
|
||||||
|
data: {
|
||||||
|
providers: [
|
||||||
|
{ id: 1, name: "Shop 1" },
|
||||||
|
{ id: 2, name: "Shop 2" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => {
|
||||||
|
return new Promise((resolve) => resolve(closestShops));
|
||||||
|
});
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,13 +81,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
<alert
|
||||||
|
ref="AlertNoService"
|
||||||
|
v-if="displayNoServiceAlert"
|
||||||
|
class="my-4"
|
||||||
|
cmsWidgetName="AlertNoServiceWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
<navbar
|
<navbar
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
ref="navbar"
|
ref="navbar"
|
||||||
:isDisabled="!meta.valid"
|
:isDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction"
|
||||||
:isForwardActionDisabled="!meta.valid" />
|
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -177,6 +184,7 @@ export default {
|
||||||
displayInvalidZipAlert: false,
|
displayInvalidZipAlert: false,
|
||||||
showServiceZipField: this.getServiceZipFromStore(),
|
showServiceZipField: this.getServiceZipFromStore(),
|
||||||
isZipServiceable: false,
|
isZipServiceable: false,
|
||||||
|
displayNoServiceAlert: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -293,6 +301,17 @@ export default {
|
||||||
return this.$refs.navbar.removeLoader();
|
return this.$refs.navbar.removeLoader();
|
||||||
}
|
}
|
||||||
this.displayInvalidZipAlert = false;
|
this.displayInvalidZipAlert = false;
|
||||||
|
|
||||||
|
if (this.serviceZipCode != null && this.isHeavyTruck) {
|
||||||
|
const closestShops = await this.findClosestApplicableShops(
|
||||||
|
this.serviceZipCode,
|
||||||
|
this.carId
|
||||||
|
);
|
||||||
|
this.displayNoServiceAlert = !closestShops?.data?.providers?.length;
|
||||||
|
if (this.displayNoServiceAlert) {
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
}
|
||||||
|
}
|
||||||
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.
|
||||||
|
|
@ -444,6 +463,7 @@ export default {
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
this.displayMatchedDifferentVehicleAlert = false;
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||||
|
this.displayNoServiceAlert = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -495,6 +515,7 @@ export default {
|
||||||
handler(newValue) {
|
handler(newValue) {
|
||||||
// If they modify the service zip code, then hide the error message.
|
// If they modify the service zip code, then hide the error message.
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
|
this.displayNoServiceAlert = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
showServiceZipField: {
|
showServiceZipField: {
|
||||||
|
|
|
||||||
|
|
@ -620,6 +620,8 @@ function setupMocks({
|
||||||
validateZipResponse = { zipCodeCtu: null, isServiceable: false, isValid: true, state: null },
|
validateZipResponse = { zipCodeCtu: null, isServiceable: false, isValid: true, state: null },
|
||||||
//Values to set in the state store
|
//Values to set in the state store
|
||||||
carId = null,
|
carId = null,
|
||||||
|
isHeavyTruck = true,
|
||||||
|
displayNoServiceAlert = true,
|
||||||
serviceLocationZipCode = null,
|
serviceLocationZipCode = null,
|
||||||
registrationZipCode = null,
|
registrationZipCode = null,
|
||||||
licensePlate = null, //"TESTPLATE",
|
licensePlate = null, //"TESTPLATE",
|
||||||
|
|
@ -672,6 +674,8 @@ function setupMocks({
|
||||||
zipCode: registrationZipCode,
|
zipCode: registrationZipCode,
|
||||||
},
|
},
|
||||||
carId: carId,
|
carId: carId,
|
||||||
|
isBigTruck: isHeavyTruck,
|
||||||
|
canSafeliteService: true,
|
||||||
},
|
},
|
||||||
order: {
|
order: {
|
||||||
customer: {
|
customer: {
|
||||||
|
|
@ -716,5 +720,17 @@ function setupMocks({
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
|
||||||
wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
|
wrapper.vm.$refs.navbar.updateButtonText = jest.fn();
|
||||||
wrapper.vm.$refs.navbar.removeLoader = jest.fn();
|
wrapper.vm.$refs.navbar.removeLoader = jest.fn();
|
||||||
|
const closestShops = {
|
||||||
|
data: {
|
||||||
|
providers: [
|
||||||
|
{ id: 1, name: "Shop 1" },
|
||||||
|
{ id: 2, name: "Shop 2" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => {
|
||||||
|
return new Promise((resolve) => resolve(closestShops));
|
||||||
|
});
|
||||||
return { wrapper, apiPromise };
|
return { wrapper, apiPromise };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@
|
||||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
v-bind:isDismissible="false" />
|
||||||
|
|
||||||
<alert
|
<alert
|
||||||
ref="AlertNoService"
|
ref="AlertNoService"
|
||||||
v-if="displayNoServiceAlert"
|
v-if="displayNoServiceAlert"
|
||||||
|
|
@ -87,9 +88,9 @@
|
||||||
<navbar
|
<navbar
|
||||||
ref="navbar"
|
ref="navbar"
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction"
|
||||||
@ForwardClicked="forwardButtonAction || displayNoServiceAlert" />
|
@ForwardClicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -177,6 +178,7 @@ export default {
|
||||||
displayInvalidZipAlert: false,
|
displayInvalidZipAlert: false,
|
||||||
showServiceZipField: this.getServiceZipFromStore(),
|
showServiceZipField: this.getServiceZipFromStore(),
|
||||||
isZipServiceable: false,
|
isZipServiceable: false,
|
||||||
|
displayNoServiceAlert: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -279,6 +281,17 @@ export default {
|
||||||
this.displayInvalidZipAlert = true;
|
this.displayInvalidZipAlert = true;
|
||||||
return this.$refs.navbar.removeLoader();
|
return this.$refs.navbar.removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isHeavyTruck) {
|
||||||
|
const closestShops = await this.findClosestApplicableShops(
|
||||||
|
this.serviceZipCode,
|
||||||
|
this.carId
|
||||||
|
);
|
||||||
|
this.displayNoServiceAlert = !closestShops?.data?.providers?.length;
|
||||||
|
if (this.displayNoServiceAlert) {
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if the CarId has changed.
|
// Check if the CarId has changed.
|
||||||
this.isCarIdDifferent =
|
this.isCarIdDifferent =
|
||||||
vinLookup.data.vehicle.carId !== this.$store.getters.vehicle.carId;
|
vinLookup.data.vehicle.carId !== this.$store.getters.vehicle.carId;
|
||||||
|
|
@ -393,6 +406,7 @@ export default {
|
||||||
this.displayMatchedDifferentVehicleAlert = false;
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||||
this.displayInvalidZipAlert = false;
|
this.displayInvalidZipAlert = false;
|
||||||
|
this.displayNoServiceAlert = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -437,6 +451,7 @@ export default {
|
||||||
serviceZipCode() {
|
serviceZipCode() {
|
||||||
// If they modify the service zip code, then hide the error message.
|
// If they modify the service zip code, then hide the error message.
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
|
this.displayNoServiceAlert = false;
|
||||||
this.$refs.navbar.updateButtonText(
|
this.$refs.navbar.updateButtonText(
|
||||||
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
|
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,16 @@
|
||||||
<component :is="'script'" src="https://js.afterpay.com/afterpay-1.x.js" async></component>
|
<component :is="'script'" src="https://js.afterpay.com/afterpay-1.x.js" async></component>
|
||||||
<div class="my-4 alert-heading text-center">
|
<div class="my-4 alert-heading text-center">
|
||||||
<span v-html="afterpayHeaderCopy" />
|
<span v-html="afterpayHeaderCopy" />
|
||||||
|
|
||||||
<span class="afterpay-amount">{{ this.afterpayPrice }}</span>
|
<span class="afterpay-amount">{{ this.afterpayPrice }}</span>
|
||||||
<br />
|
<br />
|
||||||
<span class="alert-sub-heading" v-html="afterpayHeaderSubHeaderCopy" />
|
<span class="alert-sub-heading" v-html="afterpayHeaderSubHeaderCopy" />
|
||||||
|
<img :src="afterPayImageUrl" class="afterpay-image" />
|
||||||
<img :src="afterPayImageUrl" />
|
|
||||||
|
|
||||||
<a
|
<a
|
||||||
id="afterpay-learnmore"
|
id="afterpay-learnmore"
|
||||||
href="#"
|
href="#"
|
||||||
data-afterpay-modal="en_US-safelite"
|
data-afterpay-modal="en_US-safelite"
|
||||||
data-bind="click:afterpayLearnMore">
|
data-bind="click:afterpayLearnMore"
|
||||||
|
class="afterpay-learn-more">
|
||||||
<img :src="infoIcon" alt="Info Icon" class="info-icon" />
|
<img :src="infoIcon" alt="Info Icon" class="info-icon" />
|
||||||
</a>
|
</a>
|
||||||
<div class="after-pay">
|
<div class="after-pay">
|
||||||
|
|
@ -151,8 +149,8 @@ export default {
|
||||||
|
|
||||||
&.alert-info {
|
&.alert-info {
|
||||||
.alert-heading {
|
.alert-heading {
|
||||||
color: #000000;
|
color: $black;
|
||||||
font-weight: 600;
|
font-weight: $font-weight-600;
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
@include media-breakpoint-up(md) {
|
@include media-breakpoint-up(md) {
|
||||||
|
|
@ -162,11 +160,12 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.afterpay-amount {
|
.afterpay-amount {
|
||||||
color: #0c7e47;
|
color: $green;
|
||||||
|
margin-left: 0.25rem;
|
||||||
}
|
}
|
||||||
.alert-sub-heading {
|
.alert-sub-heading {
|
||||||
color: #4b4c4e;
|
color: $gray-1100;
|
||||||
font-weight: 400;
|
font-weight: $font-weight-normal;
|
||||||
}
|
}
|
||||||
.after-pay {
|
.after-pay {
|
||||||
.after-pay-toggle {
|
.after-pay-toggle {
|
||||||
|
|
@ -180,7 +179,7 @@ export default {
|
||||||
background-position: right center;
|
background-position: right center;
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 9px;
|
height: 0.5625rem;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
&.expanded:after {
|
&.expanded:after {
|
||||||
|
|
@ -194,8 +193,8 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.after-pay-toggle a {
|
.after-pay-toggle a {
|
||||||
font-weight: 600;
|
font-weight: $font-weight-600;
|
||||||
color: #0070d1;
|
color: $blue;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.after-pay-details {
|
.after-pay-details {
|
||||||
|
|
@ -218,27 +217,45 @@ export default {
|
||||||
.payment-card {
|
.payment-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: 6px;
|
border-radius: 0.375rem;
|
||||||
border: 0.25px #b3b4b5;
|
border: 0.25px $gray-1000;
|
||||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 0px 4px 8px -4px rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
.calendar-section {
|
.calendar-section {
|
||||||
background-color: #fff; /* White background for calendar area */
|
background-color: $white; /* White background for calendar area */
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
gap: 2px;
|
gap: 0.125rem;
|
||||||
font-weight: 700;
|
font-weight: $font-weight-700;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
border-top-left-radius: 0.375rem;
|
||||||
|
border-top-right-radius: 0.375rem;
|
||||||
|
width: 4.375rem;
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
width: 5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.payment-amount-section {
|
.payment-amount-section {
|
||||||
background-color: #e0f7e9; /* Light green background for payment area */
|
background-color: $green-600; /* Light green background for payment area */
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: 700;
|
font-weight: $font-weight-700;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
width: 4.375rem;
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
width: 5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.afterpay-learn-more {
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
.afterpay-image {
|
||||||
|
margin-left: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount-due {
|
.amount-due {
|
||||||
color: #00723e; /* Green text */
|
color: $green-1000; /* Green text */
|
||||||
}
|
}
|
||||||
.legend {
|
.legend {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -249,11 +266,11 @@ export default {
|
||||||
.legend-item {
|
.legend-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 2px;
|
gap: 0.125rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.legend-item span {
|
.legend-item span {
|
||||||
font-weight: 400;
|
font-weight: $font-weight-normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,72 +1,70 @@
|
||||||
<template>
|
<template>
|
||||||
<transition name="fade" mode="out-in">
|
<div class="mobile-location-questions">
|
||||||
<div class="mobile-location-questions">
|
<div class="text-center" :id="componentId">
|
||||||
<div class="text-center" :id="componentId">
|
<label
|
||||||
<label
|
for="mobileLocationLinkPromptId"
|
||||||
for="mobileLocationLinkPromptId"
|
:aria-label="mobileLocationLinkPromptText"
|
||||||
:aria-label="mobileLocationLinkPromptText"
|
class="form-label fw-bold w-100 ps-4 pe-4 pt-4 text-black"
|
||||||
class="form-label fw-bold w-100 ps-4 pe-4 pt-4 text-black"
|
v-html="mobileLocationLinkPromptText"></label>
|
||||||
v-html="mobileLocationLinkPromptText"></label>
|
<div class="update-mobile-location-text-link">
|
||||||
<div class="update-mobile-location-text-link">
|
<textLink
|
||||||
<textLink
|
ref="mobileLocationLink"
|
||||||
ref="mobileLocationLink"
|
id="mobileLocationLinkPromptId"
|
||||||
id="mobileLocationLinkPromptId"
|
linkType="text"
|
||||||
linkType="text"
|
:text="mobileLocationLinkText"
|
||||||
:text="mobileLocationLinkText"
|
href="#!"
|
||||||
href="#!"
|
@click-event="openModal" />
|
||||||
@click-event="openModal" />
|
|
||||||
</div>
|
|
||||||
<div v-show="errorMessage" class="row my-1 form-test-error">
|
|
||||||
<span
|
|
||||||
class="d-inline-flex small mt-0 center-error-message"
|
|
||||||
aria-atomic="true"
|
|
||||||
aria-live="polite">
|
|
||||||
{{ errorMessage }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<textBlock
|
|
||||||
v-if="mobileFeeApplies"
|
|
||||||
:customText="mobileFeeText"
|
|
||||||
cmsWidgetName="MobileFeeDisclaimerWidget"
|
|
||||||
typeStyle="caption" />
|
|
||||||
</div>
|
</div>
|
||||||
<modal
|
<div v-show="errorMessage" class="row my-1 form-test-error">
|
||||||
:ref="modalName"
|
<span
|
||||||
:headerText="modalHeaderText"
|
class="d-inline-flex small mt-0 center-error-message"
|
||||||
:footerButtonText="modalFooterText"
|
aria-atomic="true"
|
||||||
:onModalOpenedCallback="onModalOpened"
|
aria-live="polite">
|
||||||
:onModalClosedCallback="onModalClosed"
|
{{ errorMessage }}
|
||||||
@isModalOpened="setModalStatus"
|
</span>
|
||||||
@footer-button-event="setMobileLocation">
|
</div>
|
||||||
<template v-if="isModalOpened">
|
<textBlock
|
||||||
<addressQuestions
|
v-if="mobileFeeApplies"
|
||||||
ref="addressQuestions"
|
:customText="mobileFeeText"
|
||||||
v-model="internalModel.addressQuestions"
|
cmsWidgetName="MobileFeeDisclaimerWidget"
|
||||||
captureApartmentNumberOrBusinessName="true"
|
typeStyle="caption" />
|
||||||
preserveCityAndStateOnReset="true" />
|
|
||||||
<vehicleProtectedQuestion
|
|
||||||
ref="vehicleProtectedQuestion"
|
|
||||||
v-model="internalModel.isVehicleProtected"
|
|
||||||
cmsWidgetName="VehicleProtectedQuestionWidget" />
|
|
||||||
<textBlock cmsWidgetName="WorkspaceRequirementsWidget" typeStyle="caption" />
|
|
||||||
<alert
|
|
||||||
ref="alertInvalidZip"
|
|
||||||
v-if="displayInvalidZipAlert"
|
|
||||||
class="my-4"
|
|
||||||
cmsWidgetName="AlertInvalidZipWidget"
|
|
||||||
alertClass="alert-danger"
|
|
||||||
v-bind:isDismissible="false" />
|
|
||||||
<alert
|
|
||||||
ref="alertMismatchStateAndZip"
|
|
||||||
v-if="displayMismatchStateAndZipAlert"
|
|
||||||
class="my-4"
|
|
||||||
cmsWidgetName="AlertMismatchStateAndZipWidget"
|
|
||||||
alertClass="alert-danger"
|
|
||||||
v-bind:isDismissible="false" />
|
|
||||||
</template>
|
|
||||||
</modal>
|
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
<modal
|
||||||
|
:ref="modalName"
|
||||||
|
:headerText="modalHeaderText"
|
||||||
|
:footerButtonText="modalFooterText"
|
||||||
|
:onModalOpenedCallback="onModalOpened"
|
||||||
|
:onModalClosedCallback="onModalClosed"
|
||||||
|
@isModalOpened="setModalStatus"
|
||||||
|
@footer-button-event="setMobileLocation">
|
||||||
|
<template v-if="isModalOpened">
|
||||||
|
<addressQuestions
|
||||||
|
ref="addressQuestions"
|
||||||
|
v-model="internalModel.addressQuestions"
|
||||||
|
captureApartmentNumberOrBusinessName="true"
|
||||||
|
preserveCityAndStateOnReset="true" />
|
||||||
|
<vehicleProtectedQuestion
|
||||||
|
ref="vehicleProtectedQuestion"
|
||||||
|
v-model="internalModel.isVehicleProtected"
|
||||||
|
cmsWidgetName="VehicleProtectedQuestionWidget" />
|
||||||
|
<textBlock cmsWidgetName="WorkspaceRequirementsWidget" typeStyle="caption" />
|
||||||
|
<alert
|
||||||
|
ref="alertInvalidZip"
|
||||||
|
v-if="displayInvalidZipAlert"
|
||||||
|
class="my-4"
|
||||||
|
cmsWidgetName="AlertInvalidZipWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
|
<alert
|
||||||
|
ref="alertMismatchStateAndZip"
|
||||||
|
v-if="displayMismatchStateAndZipAlert"
|
||||||
|
class="my-4"
|
||||||
|
cmsWidgetName="AlertMismatchStateAndZipWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
|
</template>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -150,6 +148,7 @@ export default {
|
||||||
zipCode: "",
|
zipCode: "",
|
||||||
},
|
},
|
||||||
isVehicleProtected: null,
|
isVehicleProtected: null,
|
||||||
|
isMobileSelected: false,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
mobileFeePart: {
|
mobileFeePart: {
|
||||||
|
|
@ -169,17 +168,7 @@ export default {
|
||||||
return this.getCmsContent(this.linkWidgetName, "HeaderText");
|
return this.getCmsContent(this.linkWidgetName, "HeaderText");
|
||||||
},
|
},
|
||||||
mobileLocationLinkText() {
|
mobileLocationLinkText() {
|
||||||
if (
|
if (this.isMobileAddressComplete()) {
|
||||||
this.addressModel.streetAddress &&
|
|
||||||
this.addressModel.streetAddress !== "" &&
|
|
||||||
this.addressModel.city &&
|
|
||||||
this.addressModel.city !== "" &&
|
|
||||||
this.addressModel.state &&
|
|
||||||
this.addressModel.state !== "" &&
|
|
||||||
this.addressModel.zipCode &&
|
|
||||||
this.addressModel.zipCode !== "" &&
|
|
||||||
this.internalModel.isVehicleProtected !== null
|
|
||||||
) {
|
|
||||||
return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`;
|
return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`;
|
||||||
}
|
}
|
||||||
return this.getCmsContent(this.linkWidgetName, "BodyText");
|
return this.getCmsContent(this.linkWidgetName, "BodyText");
|
||||||
|
|
@ -218,6 +207,19 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
isMobileAddressComplete() {
|
||||||
|
return (
|
||||||
|
this.addressModel.streetAddress &&
|
||||||
|
this.addressModel.streetAddress !== "" &&
|
||||||
|
this.addressModel.city &&
|
||||||
|
this.addressModel.city !== "" &&
|
||||||
|
this.addressModel.state &&
|
||||||
|
this.addressModel.state !== "" &&
|
||||||
|
this.addressModel.zipCode &&
|
||||||
|
this.addressModel.zipCode !== "" &&
|
||||||
|
this.internalModel.isVehicleProtected !== null
|
||||||
|
);
|
||||||
|
},
|
||||||
openModal() {
|
openModal() {
|
||||||
this.modal.openModal();
|
this.modal.openModal();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,16 @@ jest.mock(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
jest.mock(
|
||||||
|
"@/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue",
|
||||||
|
() => ({
|
||||||
|
isMobileAddressComplete: jest.fn(() => {
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
openModal: jest.fn(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
jest.spyOn(baseMixin.methods, "getZipCodeData").mockImplementation((serviceZipCode) => {
|
jest.spyOn(baseMixin.methods, "getZipCodeData").mockImplementation((serviceZipCode) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let mockContainsMilitaryBase = false;
|
let mockContainsMilitaryBase = false;
|
||||||
|
|
@ -343,6 +353,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "43054",
|
zipCode: "43054",
|
||||||
},
|
},
|
||||||
isVehicleProtected: true,
|
isVehicleProtected: true,
|
||||||
|
isMobileSelected: true,
|
||||||
};
|
};
|
||||||
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
||||||
|
|
||||||
|
|
@ -355,6 +366,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "61606",
|
zipCode: "61606",
|
||||||
},
|
},
|
||||||
isVehicleProtected: null,
|
isVehicleProtected: null,
|
||||||
|
isMobileSelected: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -457,6 +469,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "",
|
zipCode: "",
|
||||||
},
|
},
|
||||||
isVehicleProtected: null,
|
isVehicleProtected: null,
|
||||||
|
isMobileSelected: false,
|
||||||
};
|
};
|
||||||
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
||||||
const newMobileLocationQuestions = {
|
const newMobileLocationQuestions = {
|
||||||
|
|
@ -468,6 +481,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "43054",
|
zipCode: "43054",
|
||||||
},
|
},
|
||||||
isVehicleProtected: true,
|
isVehicleProtected: true,
|
||||||
|
isMobileSelected: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wrapper.vm.closeModalAction = jest.fn();
|
wrapper.vm.closeModalAction = jest.fn();
|
||||||
|
|
@ -517,6 +531,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "",
|
zipCode: "",
|
||||||
},
|
},
|
||||||
isVehicleProtected: null,
|
isVehicleProtected: null,
|
||||||
|
isMobileSelected: false,
|
||||||
mobileFeePart: null,
|
mobileFeePart: null,
|
||||||
};
|
};
|
||||||
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
|
||||||
|
|
@ -530,6 +545,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "43081",
|
zipCode: "43081",
|
||||||
},
|
},
|
||||||
isVehicleProtected: true,
|
isVehicleProtected: true,
|
||||||
|
isMobileSelected: true,
|
||||||
mobileFeePart: null,
|
mobileFeePart: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -593,6 +609,7 @@ describe("service-location.vue", () => {
|
||||||
zipCode: "43081",
|
zipCode: "43081",
|
||||||
},
|
},
|
||||||
isVehicleProtected: "YesAnswer",
|
isVehicleProtected: "YesAnswer",
|
||||||
|
isMobileSelected: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wrapper.vm.closeModalAction = jest.fn();
|
wrapper.vm.closeModalAction = jest.fn();
|
||||||
|
|
@ -1433,5 +1450,7 @@ function setupMocks({ mountOptionsMockData = {} }) {
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
const wrapper = shallowMount(serviceLocation, mountOptions);
|
const wrapper = shallowMount(serviceLocation, mountOptions);
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||||
|
wrapper.vm.$refs.mobileLocationQuestions.isMobileAddressComplete = jest.fn();
|
||||||
|
wrapper.vm.$refs.mobileLocationQuestions.openModal = jest.fn();
|
||||||
return { wrapper, apiPromise };
|
return { wrapper, apiPromise };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
<div class="col-md-6 col-xl-4">
|
<div class="col-md-6 col-xl-4">
|
||||||
<mobileLocationModalQuestions
|
<mobileLocationModalQuestions
|
||||||
customComponentId="mobileLocationQuestions"
|
customComponentId="mobileLocationQuestions"
|
||||||
v-if="selectedAppointmentType === 'Mobile'"
|
v-show="selectedAppointmentType === 'Mobile'"
|
||||||
v-model="mobileLocationQuestions"
|
v-model="mobileLocationQuestions"
|
||||||
:mobileFeePart="mobileFeePart"
|
:mobileFeePart="mobileFeePart"
|
||||||
:mobileFeeApplies="mobileFeeApplies"
|
:mobileFeeApplies="mobileFeeApplies"
|
||||||
|
|
@ -171,11 +171,12 @@ const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("mobile-location-required", (value) => {
|
defineRule("mobile-location-required", (value) => {
|
||||||
if (
|
if (
|
||||||
!value.addressQuestions.streetAddress ||
|
value.isMobileSelected &&
|
||||||
!value.addressQuestions.city ||
|
(!value.addressQuestions.streetAddress ||
|
||||||
!value.addressQuestions.state ||
|
!value.addressQuestions.city ||
|
||||||
!value.addressQuestions.zipCode ||
|
!value.addressQuestions.state ||
|
||||||
!value.isVehicleProtected
|
!value.addressQuestions.zipCode ||
|
||||||
|
!value.isVehicleProtected)
|
||||||
) {
|
) {
|
||||||
return errorMessages.MOBILE_LOCATION_REQUIRED;
|
return errorMessages.MOBILE_LOCATION_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
@ -297,6 +298,7 @@ export default {
|
||||||
zipCode: this.zipCode,
|
zipCode: this.zipCode,
|
||||||
},
|
},
|
||||||
isVehicleProtected: this.isVehicleProtected,
|
isVehicleProtected: this.isVehicleProtected,
|
||||||
|
isMobileSelected: this.selectedAppointmentType === "Mobile",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -765,6 +767,10 @@ export default {
|
||||||
this.selectedProvider = new Provider(
|
this.selectedProvider = new Provider(
|
||||||
this.shopProviderData.mobileProviderNumber
|
this.shopProviderData.mobileProviderNumber
|
||||||
);
|
);
|
||||||
|
var mobileLocationQs = this.$refs.mobileLocationQuestions;
|
||||||
|
if (!mobileLocationQs.isMobileAddressComplete()) {
|
||||||
|
mobileLocationQs.openModal();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.selectedProvider = new Provider();
|
this.selectedProvider = new Provider();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,21 @@ describe("service-zip.vue", () => {
|
||||||
expect(wrapper.vm.displayInvalidZipAlert).toBe(false);
|
expect(wrapper.vm.displayInvalidZipAlert).toBe(false);
|
||||||
expect(wrapper.vm.displayNonServiceableZipAlert).toBe(false);
|
expect(wrapper.vm.displayNonServiceableZipAlert).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should hide the AlertNoService when displayNoServiceAlert is false", async () => {
|
||||||
|
// Arrange
|
||||||
|
// no changes to store
|
||||||
|
applyMockStoreDataToGetters();
|
||||||
|
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
wrapper.vm.serviceZipCode = "12345";
|
||||||
|
|
||||||
|
wrapper.vm.displayNoServiceAlert = false;
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
// Check if the AlertNoService component is rendered
|
||||||
|
expect(wrapper.vm.displayNoServiceAlert).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -511,5 +526,15 @@ function setupMocks({ customMountOptions, customZipQuery, customZipDataResponse
|
||||||
];
|
];
|
||||||
|
|
||||||
const wrapper = shallowMount(serviceZip, mountOptions);
|
const wrapper = shallowMount(serviceZip, mountOptions);
|
||||||
|
wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
data: {
|
||||||
|
providers: [
|
||||||
|
{ id: 1, name: "Shop 1" },
|
||||||
|
{ id: 2, name: "Shop 2" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,18 @@
|
||||||
v-model="customAlertData"
|
v-model="customAlertData"
|
||||||
v-if="displayNonServiceableZipAlert"
|
v-if="displayNonServiceableZipAlert"
|
||||||
alertClass="alert-danger" />
|
alertClass="alert-danger" />
|
||||||
|
<alert
|
||||||
|
ref="AlertNoService"
|
||||||
|
v-if="displayNoServiceAlert"
|
||||||
|
class="my-4"
|
||||||
|
cmsWidgetName="AlertNoServiceWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
|
|
||||||
<navbar
|
<navbar
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
ref="navbar"
|
ref="navbar"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction"
|
||||||
@ForwardClicked="forwardButtonAction" />
|
@ForwardClicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -114,6 +121,7 @@ export default {
|
||||||
isHeavyTruck: this.getIsVehicleHeavyTruckServiceableFromStore(),
|
isHeavyTruck: this.getIsVehicleHeavyTruckServiceableFromStore(),
|
||||||
displayInvalidZipAlert: false,
|
displayInvalidZipAlert: false,
|
||||||
displayNonServiceableZipAlert: false,
|
displayNonServiceableZipAlert: false,
|
||||||
|
displayNoServiceAlert: false, // Initialize the property
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -278,17 +286,6 @@ export default {
|
||||||
return this.$refs.navbar.removeLoader();
|
return this.$refs.navbar.removeLoader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.isHeavyTruck) {
|
|
||||||
const closestShops = await this.findClosestApplicableShops(
|
|
||||||
this.serviceZipCode,
|
|
||||||
this.carId
|
|
||||||
);
|
|
||||||
this.displayNoServiceAlert = !closestShops?.data?.providers?.length;
|
|
||||||
if (this.displayNoServiceAlert) {
|
|
||||||
return this.$refs.navbar.removeLoader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const payment = this.$store.getters.payment;
|
const payment = this.$store.getters.payment;
|
||||||
const policy = this.$store.getters.policy;
|
const policy = this.$store.getters.policy;
|
||||||
|
|
||||||
|
|
@ -346,7 +343,6 @@ export default {
|
||||||
serviceZipCode() {
|
serviceZipCode() {
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
this.displayNoServiceAlert = false;
|
this.displayNoServiceAlert = false;
|
||||||
this.displayNoServiceAlert = false;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,23 @@ describe("vin-lookup.vue", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findAllComponents({ name: "alert" }).length).toBe(1);
|
expect(wrapper.findAllComponents({ name: "alert" }).length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should hide the AlertNoService when displayNoServiceAlert is false", async () => {
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
isZipServiceable: true,
|
||||||
|
displayNoServiceAlert: false,
|
||||||
|
lookupVinbyAddressResponse: {
|
||||||
|
isStatePermissible: true,
|
||||||
|
vinVehicles: [], // Return no vehicles
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Ensure displayNoServiceAlert is false
|
||||||
|
await wrapper.setData({ displayNoServiceAlert: false });
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
// Check if the AlertNoService component is not rendered
|
||||||
|
const alertNoService = wrapper.findComponent({ ref: "AlertNoService" });
|
||||||
|
expect(alertNoService.exists()).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getVinFromImage", () => {
|
describe("getVinFromImage", () => {
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,18 @@
|
||||||
"
|
"
|
||||||
alertClass="alert-success" />
|
alertClass="alert-success" />
|
||||||
|
|
||||||
|
<alert
|
||||||
|
ref="AlertNoService"
|
||||||
|
v-if="displayNoServiceAlert"
|
||||||
|
class="my-4"
|
||||||
|
cmsWidgetName="AlertNoServiceWidget"
|
||||||
|
alertClass="alert-danger"
|
||||||
|
v-bind:isDismissible="false" />
|
||||||
|
|
||||||
<navbar
|
<navbar
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
ref="navbar"
|
ref="navbar"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid || displayNoServiceAlert"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction"
|
||||||
@ForwardClicked="forwardButtonAction" />
|
@ForwardClicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -209,6 +217,7 @@ export default {
|
||||||
displayVinNotFoundAlert: false,
|
displayVinNotFoundAlert: false,
|
||||||
displayMatchedDifferentVehicleAlert: false,
|
displayMatchedDifferentVehicleAlert: false,
|
||||||
displayVinScanFailedAlert: false,
|
displayVinScanFailedAlert: false,
|
||||||
|
displayNoServiceAlert: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -247,6 +256,9 @@ export default {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getCarIdfromStore() {
|
||||||
|
return this.$store.getters.vehicle.carId;
|
||||||
|
},
|
||||||
getIsVehicleHeavyTruckServiceableFromStore() {
|
getIsVehicleHeavyTruckServiceableFromStore() {
|
||||||
return store.getters.vehicle.isBigTruck && store.getters.vehicle.canSafeliteService;
|
return store.getters.vehicle.isBigTruck && store.getters.vehicle.canSafeliteService;
|
||||||
},
|
},
|
||||||
|
|
@ -341,7 +353,7 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
if (this.isHeavyTruck) {
|
if (this.isHeavyTruck) {
|
||||||
closestShops = await this.findClosestApplicableShops(
|
const closestShops = await this.findClosestApplicableShops(
|
||||||
this.serviceZipCode,
|
this.serviceZipCode,
|
||||||
this.carId
|
this.carId
|
||||||
);
|
);
|
||||||
|
|
@ -499,7 +511,6 @@ export default {
|
||||||
this.displayVinNotFoundAlert = false;
|
this.displayVinNotFoundAlert = false;
|
||||||
this.displayVinScanFailedAlert = false;
|
this.displayVinScanFailedAlert = false;
|
||||||
this.displayNoServiceAlert = false;
|
this.displayNoServiceAlert = false;
|
||||||
this.displayNoServiceAlert = false;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -576,6 +587,7 @@ export default {
|
||||||
},
|
},
|
||||||
serviceZipCode() {
|
serviceZipCode() {
|
||||||
this.displayNonServiceableZipAlert = false;
|
this.displayNonServiceableZipAlert = false;
|
||||||
|
this.displayNoServiceAlert = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,11 @@ $green-300: #94d7b6;
|
||||||
$green-400: #5abc8c; // Used in theme
|
$green-400: #5abc8c; // Used in theme
|
||||||
$green-500: #2ca168;
|
$green-500: #2ca168;
|
||||||
$green: #0c7e47; // Default Green
|
$green: #0c7e47; // Default Green
|
||||||
|
$green-600: #e7f2ed;
|
||||||
$green-700: #006a36;
|
$green-700: #006a36;
|
||||||
$green-800: #004f28;
|
$green-800: #004f28;
|
||||||
$green-900: #00331a;
|
$green-900: #00331a;
|
||||||
|
$green-1000: #00723e;
|
||||||
|
|
||||||
// Yellows
|
// Yellows
|
||||||
$yellow-100: #fff5eb;
|
$yellow-100: #fff5eb;
|
||||||
|
|
@ -59,6 +61,8 @@ $gray-600: #4d5151; // Used in theme
|
||||||
$gray-700: #303333; // Used in theme
|
$gray-700: #303333; // Used in theme
|
||||||
$gray-800: #222424; // Used in theme
|
$gray-800: #222424; // Used in theme
|
||||||
$gray-900: #181a1a; // Used in theme
|
$gray-900: #181a1a; // Used in theme
|
||||||
|
$gray-1000: #b3b4b5;
|
||||||
|
$gray-1100: #4b4c4e;
|
||||||
|
|
||||||
//orange
|
//orange
|
||||||
$orange-600: #e86421;
|
$orange-600: #e86421;
|
||||||
|
|
@ -134,6 +138,8 @@ $font-weight-lighter: lighter;
|
||||||
$font-weight-light: 300;
|
$font-weight-light: 300;
|
||||||
$font-weight-normal: 400;
|
$font-weight-normal: 400;
|
||||||
$font-weight-bold: 500;
|
$font-weight-bold: 500;
|
||||||
|
$font-weight-600: 600;
|
||||||
|
$font-weight-700: 700;
|
||||||
$font-weight-bolder: bolder;
|
$font-weight-bolder: bolder;
|
||||||
|
|
||||||
//Headings
|
//Headings
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue