Merge remote-tracking branch 'origin/develop' into feature/CSR-1137

This commit is contained in:
Scott Kiener 2023-05-18 14:34:05 -04:00
commit 8967676496
12 changed files with 234 additions and 261 deletions

View file

@ -15,10 +15,12 @@ module.exports = {
"!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue",
"!src/layouts/reveal/**/*.vue", "!src/layouts/reveal/**/*.vue",
"!src/ux-components/text-link/**/*.vue", "!src/ux-components/text-link/**/*.vue",
"!src/common-components/date-picker/**/*.vue", // Temp until unit tests completed "!src/digital-components/date-picker/**/*.vue", // Temp until unit tests completed
"!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing "!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing
"!src/common-components/funnel-header/menu-modal/**/*.vue", "!src/common-components/funnel-header/menu-modal/**/*.vue",
"!src/layouts/schedule/*.vue", // Temp test exclusion while in development "!src/layouts/schedule/*.vue", // Temp test exclusion while in development
"!src/layouts/schedule/helpers/schedule-helper.js", // Temp test exclusion while in development
"!src/layouts/review/*.vue", // Temp test exclusion while in development
// END // END
], // ! means exclude from coverage. ], // ! means exclude from coverage.
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],

View file

@ -120,7 +120,7 @@ export default {
isRequired: Boolean, isRequired: Boolean,
isOverflowScrollable: Boolean, isOverflowScrollable: Boolean,
isWide: Boolean, isWide: Boolean,
modelValue: [Array, Number, String, Object], modelValue: [Array, Number, String],
value: [Number, String], value: [Number, String],
validationRules: String, validationRules: String,
suppressError: Boolean, suppressError: Boolean,
@ -140,7 +140,7 @@ export default {
const fieldOptions = { const fieldOptions = {
value: modelValue, value: modelValue,
initialValue: modelValue, initialValue: null,
}; };
const { errorMessage, handleBlur, handleChange, meta, validate, errors, resetField } = const { errorMessage, handleBlur, handleChange, meta, validate, errors, resetField } =
@ -255,10 +255,8 @@ export default {
}, },
}, },
watch: { watch: {
modelValue(newValue) { modelValue(newValue, oldValue) {
this.resetField({ this.resetField();
value: newValue,
});
}, },
answers() { answers() {
//once we get the answers to display from parent, see if we need a GA event to log what we showed //once we get the answers to display from parent, see if we need a GA event to log what we showed
@ -295,16 +293,16 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
// .button-question-overflow { .button-question-overflow {
// height: calc(100vh - 274px); height: calc(100vh - 274px);
// .overflow-scroll { .overflow-scroll {
// // Height will be determined by overall height of content above list // Height will be determined by overall height of content above list
// height: calc(100% - 314px); height: calc(100% - 314px);
// overflow-x: hidden !important; overflow-x: hidden !important;
// -webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
// } }
// } }
.button-question { .button-question {
color: $black; color: $black;

View file

@ -6,15 +6,55 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js";
describe("date-picker.vue", () => { describe("date-picker.vue", () => {
describe("initial setup", () => { describe("initial setup", () => {
test("Creates a date object from today", () => { test("Creates a date object from today", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = await setupMocks({
propsData: {
selectableDatesSetting: "custom"
},
});
// Act wrapper.vm.loadInitialData = jest.fn().mockImplementation(
const testResult = wrapper.vm.todayDate instanceof Date; () =>
new Promise((resolve, reject) => {
resolve({
data: [responseValue],
});
})
);
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
expect(wrapper.vm.loadInitialData).toHaveBeenCalled();
// console.log("wrapper.vm.today: ", wrapper.vm.today)
// // Act
// const testResult = wrapper.vm.today instanceof Date;
// console.log("testResult: ", testResult)
// Assert // // Assert
expect(testResult).toEqual(true); // expect(testResult).toEqual(true);
wrapper.unmount(); wrapper.unmount();
}); });

View file

@ -9,18 +9,18 @@ import { headerKeys } from "@/constants/header-keys";
export default { export default {
callHttpClient({ method, endpoint, payload, logApiCall = true, isFormData = false }) { callHttpClient({ method, endpoint, payload, logApiCall = true, isFormData = false }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); let payloadAndAnalyticsData = {};
if (isFormData) {
payloadAndAnalyticsData = payload;
payloadAndAnalyticsData.append("AppName", "FixMyGlass");
} else {
Object.assign(payloadAndAnalyticsData, payload, { AppName: "FixMyGlass" });
}
const headers = { const headers = {
[headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings),
}; };
if (endpoint.toLowerCase().includes("/analytics/")) {
cfDistroUrl = "";
endpoint = "";
method = "GET";
}
axios({ axios({
method: method, method: method,
url: cfDistroUrl + endpoint, url: cfDistroUrl + endpoint,

View file

@ -1,6 +1,6 @@
<template> <template>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div class="appointment-type-question" aria-live="polite"> <div class="appointment-type-question" aria-live="polite" v-if="isDisplayed">
<buttonQuestion <buttonQuestion
ref="buttonQuestion" ref="buttonQuestion"
customButtonQuestionId="appointmentTypeQuestion" customButtonQuestionId="appointmentTypeQuestion"
@ -25,6 +25,7 @@ export default {
modelValue: String, modelValue: String,
groupName: String, groupName: String,
isAvailable: Boolean, isAvailable: Boolean,
isDisplayed: Boolean,
suppressError: Boolean, suppressError: Boolean,
validationRules: String, validationRules: String,
cmsWidgetName: String, cmsWidgetName: String,

View file

@ -45,4 +45,18 @@ describe("object-cloning-helper.js", () => {
// Assert // Assert
expect(result).toStrictEqual(expected); expect(result).toStrictEqual(expected);
}); });
it("Should return a copy of the array", async () => {
// Arrange
const array = [9, 8, 7, 6, 5, 4, 3, 2, 1];
const expected = [9, 8, 7, 6, 5, 4, 3, 2, 1];
// Act
const result = deepClone(array);
// Assert
expect(result).toStrictEqual(expected);
});
}); });

View file

@ -1,9 +1,10 @@
import { getPricedMobileFeePart } from "./service-location-helper"; import { getPricedMobileFeePart, getServiceabilityDetails } from "./service-location-helper";
import { storeActions } from "@/constants/store-actions"; import { storeActions } from "@/constants/store-actions";
const mockStoreActionGetMobileFeePart = storeActions.GET_MOBILE_FEE_PART; const mockStoreActionGetMobileFeePart = storeActions.GET_MOBILE_FEE_PART;
const mockStoreActionPriceOrderItemsAndSaveServerData = const mockStoreActionPriceOrderItemsAndSaveServerData =
storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA; storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA;
const mockStoreActionGetServiceabilityDetails = storeActions.GET_SERVICEABILITY_DETAILS;
jest.mock("@/mixins/base-mixin.js", () => ({ jest.mock("@/mixins/base-mixin.js", () => ({
methods: { methods: {
@ -40,56 +41,87 @@ jest.mock("@/mixins/base-mixin.js", () => ({
}, },
]); ]);
} }
if (actionName === mockStoreActionGetServiceabilityDetails) {
return Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
});
}
}), }),
}, },
})); }));
describe("service-location-helper.js", () => { describe("service-location-helper.js", () => {
it("Should return null if no service zip code is passed in", async () => { describe("getPricedMobileFeePart", () => {
// Arrange it("Should return null if no service zip code is passed in", async () => {
const serviceZipCode = null; // Arrange
const damageType = "Replace"; const serviceZipCode = null;
const parentAccountNumber = 167132; const damageType = "Replace";
const billToAccountNumber = 1234; const parentAccountNumber = 167132;
const expected = null; const billToAccountNumber = 1234;
const expected = null;
// Act // Act
const result = await getPricedMobileFeePart( const result = await getPricedMobileFeePart(
serviceZipCode, serviceZipCode,
damageType, damageType,
parentAccountNumber, parentAccountNumber,
billToAccountNumber billToAccountNumber
); );
// Assert // Assert
expect(result).toEqual(expected); expect(result).toEqual(expected);
});
it("Should return the priced mobile fee part", async () => {
// Arrange
const serviceZipCode = "43235";
const damageType = "Replace";
const parentAccountNumber = 167132;
const billToAccountNumber = 1234;
const expected = {
partNumber: "MOBILE FEE",
description: "MOBILE FEE",
partType: "FEE",
laborAmount: 49.99,
sellingPrice: 0,
kitPrice: 0,
};
// Act
const result = await getPricedMobileFeePart(
serviceZipCode,
damageType,
parentAccountNumber,
billToAccountNumber
);
// Assert
expect(result).toEqual(expected);
});
}); });
it("Should return the priced mobile fee part", async () => { describe("getServiceabilityDetails", () => {
// Arrange it("Should return the serviceability details", async () => {
const serviceZipCode = "43235"; // Arrange
const damageType = "Replace"; const serviceZipCode = "43235";
const parentAccountNumber = 167132;
const billToAccountNumber = 1234;
const expected = { const expected = {
partNumber: "MOBILE FEE", isGlassServiceableInshop: true,
description: "MOBILE FEE", isRecalibrationServiceableInshop: true,
partType: "FEE", isGlassServiceableMobile: true,
laborAmount: 49.99, isRecalibrationServiceableMobile: true,
sellingPrice: 0, };
kitPrice: 0,
};
// Act // Act
const result = await getPricedMobileFeePart( const result = await getServiceabilityDetails(serviceZipCode);
serviceZipCode,
damageType,
parentAccountNumber,
billToAccountNumber
);
// Assert // Assert
expect(result).toEqual(expected); expect(result).toEqual(expected);
});
}); });
}); });

View file

@ -236,35 +236,40 @@ export default {
}); });
}, },
async setMobileLocation() { async setMobileLocation() {
// Validate the Zip Code if (
const zipCodeData = await this.getZipCodeData( this.internalModel.addressQuestions.zipCode !==
this.internalModel.addressQuestions.zipCode this.modelValue.addressQuestions.zipCode
); ) {
// Validate the Zip Code
const zipCodeData = await this.getZipCodeData(
this.internalModel.addressQuestions.zipCode
);
if (!zipCodeData.isValid) { if (!zipCodeData.isValid) {
this.displayInvalidZipAlert = true; this.displayInvalidZipAlert = true;
this.resetModalButtonStyle(); this.resetModalButtonStyle();
} else { } else {
// retrieve mobile fee part // retrieve mobile fee part
const serviceZipCode = this.internalModel.addressQuestions.zipCode; const serviceZipCode = this.internalModel.addressQuestions.zipCode;
const mobileFeePart = await getPricedMobileFeePart(serviceZipCode); const mobileFeePart = await getPricedMobileFeePart(serviceZipCode);
// retrieve serviceability details // retrieve serviceability details
const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode); const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode);
// update content related to service zip code // update content related to service zip code
this.$emit("updated-mobile-fee-part", mobileFeePart); this.$emit("updated-mobile-fee-part", mobileFeePart);
this.$emit("updated-serviceability", serviceabilityDetails.data); this.$emit("updated-serviceability", serviceabilityDetails.data);
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
// Update the page level model // Update the page level model
this.$emit("update:modelValue", this.internalModel); this.$emit("update:modelValue", this.internalModel);
if (this.onZipUpdateCallback) { if (this.onZipUpdateCallback) {
await this.onZipUpdateCallback(serviceZipCode); await this.onZipUpdateCallback(serviceZipCode);
}
this.closeModal();
} }
this.closeModal();
} }
}, },
}, },

View file

@ -505,36 +505,6 @@ describe("service-location.vue", () => {
expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeInfo); expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeInfo);
}); });
test("resets appointment type selection when service zip code is updated by mobile location modal when Mobile is not selected", async () => {
// Arrange
const { wrapper } = setupMocks({});
await wrapper.setData({
selectedAppointmentType: "Dropoff",
});
const mobileLocationQuestionsComponent = wrapper.findComponent({
ref: "mobileLocationQuestions",
});
mobileLocationQuestionsComponent.resetComponent = jest.fn();
const serviceZipCodeComponent = wrapper.findComponent({
ref: "serviceZipCodeQuestion",
});
serviceZipCodeComponent.resetMobileFeePart = jest.fn();
const newServiceZipCodeQuestion = {
zipCode: "61606",
state: "IL",
};
// Act
serviceZipCodeComponent.vm.$emit("update:modelValue", newServiceZipCodeQuestion);
// Assert
expect(wrapper.vm.selectedAppointmentType).toStrictEqual(null);
});
test("does not reset appointment type selection when service zip code is updated by mobile location modal when Mobile is selected", async () => { test("does not reset appointment type selection when service zip code is updated by mobile location modal when Mobile is selected", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});

View file

@ -47,9 +47,10 @@
alertClass="alert-warning" /> alertClass="alert-warning" />
<appointmentTypeQuestion <appointmentTypeQuestion
v-model="selectedAppointmentType" v-model="selectedAppointmentType"
v-show="!displayNoShopsAlert" v-show="isAppointmentTypeDisplayed"
:isServiceableMobile="isServiceableMobile" :isServiceableMobile="isServiceableMobile"
:isServiceableInshop="isServiceableInshop" :isServiceableInshop="isServiceableInshop"
:isDisplayed="isAppointmentTypeDisplayed"
ref="appointmentTypeQuestion" ref="appointmentTypeQuestion"
groupName="appointmentTypeQuestion" groupName="appointmentTypeQuestion"
cmsWidgetName="AppointmentTypeQuestionWidget" cmsWidgetName="AppointmentTypeQuestionWidget"
@ -71,9 +72,7 @@
<shopQuestion <shopQuestion
ref="shopQuestion" ref="shopQuestion"
v-show="isShopQuestionDisplayed" v-show="isShopQuestionDisplayed"
v-model="selectedProviderNumber" v-model="selectedProvider"
@providerSelected="onProviderSelected"
:serviceZipCode="zipCode"
:selectedAppointmentType="selectedAppointmentType" :selectedAppointmentType="selectedAppointmentType"
:isDisplayed="isShopQuestionDisplayed" :isDisplayed="isShopQuestionDisplayed"
cmsWidgetName="ShopQuestionWidget" /> cmsWidgetName="ShopQuestionWidget" />
@ -134,16 +133,6 @@ defineRule("mobile-location-required", (value) => {
return true; return true;
}); });
const defaultProvider = {
providerNumber: null,
address: {
streetAddress: null,
city: null,
state: null,
zip: null,
},
};
export default { export default {
name: "service-location", name: "service-location",
data() { data() {
@ -160,7 +149,6 @@ export default {
isRecalibrationServiceableMobile: null, isRecalibrationServiceableMobile: null,
selectedAppointmentType: this.getSelectedAppointmentType(), selectedAppointmentType: this.getSelectedAppointmentType(),
selectedProvider: this.getSelectedProvider(), selectedProvider: this.getSelectedProvider(),
selectedProviderNumber: this.getSelectedProvider().providerNumber,
mobileFeePart: null, mobileFeePart: null,
zipContainsMilitaryBase: false, zipContainsMilitaryBase: false,
zipCodeCtu: null, zipCodeCtu: null,
@ -228,7 +216,7 @@ export default {
if (newValue.zipCode !== this.zipCode) { if (newValue.zipCode !== this.zipCode) {
this.resetMobileLocation(); this.resetMobileLocation();
this.selectedAppointmentType = null; this.selectedAppointmentType = null;
this.selectedProvider = defaultProvider; this.selectedProvider = null;
} }
this.state = newValue.state; this.state = newValue.state;
@ -263,7 +251,7 @@ export default {
if (!this.selectedAppointmentType == "Mobile") { if (!this.selectedAppointmentType == "Mobile") {
this.selectedAppointmentType = null; this.selectedAppointmentType = null;
} }
this.selectedProvider = defaultProvider; this.selectedProvider = null;
} }
}, },
}, },
@ -287,8 +275,11 @@ export default {
this.selectedAppointmentType === "Dropoff" this.selectedAppointmentType === "Dropoff"
); );
}, },
// Specifically check for isRecalibrationServiceableMobile === false, not null or true. isAppointmentTypeDisplayed() {
return this.zipCode && !this.displayNoShopsAlert;
},
requiresInshopRecalibration() { requiresInshopRecalibration() {
// Specifically check for isRecalibrationServiceableMobile === false, not null or true.
return ( return (
this.isServiceableInshop && this.isServiceableInshop &&
this.isGlassServiceableMobile && this.isGlassServiceableMobile &&
@ -342,6 +333,9 @@ export default {
this.zipContainsMilitaryBase = val; this.zipContainsMilitaryBase = val;
} }
}, },
setMobileFeePart(mobileFeePart) {
this.mobileFeePart = mobileFeePart;
},
getServiceAddressFromStore() { getServiceAddressFromStore() {
return store.getters.order.serviceLocation.address; return store.getters.order.serviceLocation.address;
}, },
@ -358,10 +352,7 @@ export default {
return store.getters.order.serviceLocation.appointmentType; return store.getters.order.serviceLocation.appointmentType;
}, },
getSelectedProvider() { getSelectedProvider() {
return store.getters.order.serviceLocation.provider ?? defaultProvider; return store.getters.order.serviceLocation.provider;
},
setMobileFeePart(mobileFeePart) {
this.mobileFeePart = mobileFeePart;
}, },
resetMobileLocation() { resetMobileLocation() {
this.streetAddress = ""; this.streetAddress = "";
@ -417,9 +408,6 @@ export default {
async reloadShopData() { async reloadShopData() {
await this.$refs.shopQuestion.reloadShopData(this.zipCode); await this.$refs.shopQuestion.reloadShopData(this.zipCode);
}, },
onProviderSelected(selectedProvider) {
this.selectedProvider = selectedProvider;
},
}, },
components: { components: {
alert, alert,

View file

@ -434,7 +434,7 @@ describe("shop-question.vue", () => {
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
modelValue: selectedProvider.providerNumber, modelValue: selectedProvider,
serviceZipCode: "43081", serviceZipCode: "43081",
selectedAppointmentType: "Dropoff", selectedAppointmentType: "Dropoff",
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
@ -460,18 +460,7 @@ describe("shop-question.vue", () => {
const { wrapper } = setupMocks({ const { wrapper } = setupMocks({
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
modelValue: { modelValue: null,
address: {
city: "POWELL",
country: "US",
state: "OH",
streetAddress: "3938 POWELL RD",
zipCode: "43065",
},
distanceInMiles: 16.2690495685233,
providerNumber: "003341",
},
serviceZipCode: "43081",
selectedAppointmentType: "Dropoff", selectedAppointmentType: "Dropoff",
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
}, },
@ -481,99 +470,22 @@ describe("shop-question.vue", () => {
}); });
// Act // Act
wrapper.vm.initializeComponent(shopQuestionInitialData); await wrapper.vm.initializeComponent(shopQuestionInitialData);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
expect(wrapper.vm.answers.length).toEqual(3);
await wrapper.setProps({ await wrapper.setProps({
selectedAppointmentType: "Inshop", selectedAppointmentType: "Inshop",
}); });
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Assert // Assert
expect(wrapper.vm.answers.length).toEqual(3); expect(wrapper.vm.answers.length).toEqual(3);
}); });
// it("Should reload the shops when the service zip code changes", async () => {
// // Arrange
// const { wrapper } = setupMocks({
// mixins: [mockMixin],
// props: {
// modelValue: {
// address: {
// city: "POWELL",
// country: "US",
// state: "OH",
// streetAddress: "3938 POWELL RD",
// zipCode: "43065",
// },
// distanceInMiles: 16.2690495685233,
// providerNumber: "003341",
// },
// serviceZipCode: "43081",
// selectedAppointmentType: "Dropoff",
// cmsWidgetName: cmsWidgetName,
// isDisplayed: true
// },
// mountOptions: {
// attachTo: document.body,
// },
// });
// wrapper.vm.$options.methods.loadInitialData = jest.fn().mockImplementation(() => {
// return new Promise((resolve) => {
// resolve(mockNewShopList);
// });
// });
// // Act
// wrapper.vm.initializeComponent(shopQuestionInitialData);
// await wrapper.vm.$options.watch.serviceZipCode.handler.call(wrapper.vm, "43054");
// // Assert
// expect(wrapper.vm.shopProviders.length).toEqual(3);
// expect(wrapper.vm.shopProviders).toEqual(mockNewShopList.shopProviders);
// });
// it("Should clear the existing answers when the service zip code changes", async () => {
// // Arrange
// const { wrapper } = setupMocks({
// mixins: [mockMixin],
// props: {
// modelValue: {
// address: {
// city: "POWELL",
// country: "US",
// state: "OH",
// streetAddress: "3938 POWELL RD",
// zipCode: "43065",
// },
// distanceInMiles: 16.2690495685233,
// providerNumber: "003341",
// },
// serviceZipCode: "43081",
// selectedAppointmentType: "Dropoff",
// cmsWidgetName: cmsWidgetName,
// },
// mountOptions: {
// attachTo: document.body,
// },
// });
// //Act
// wrapper.vm.initializeComponent(shopQuestionInitialData);
// wrapper.setProps({
// selectedAppointmentType: "Inshop",
// });
// await wrapper.vm.$nextTick();
// // Assert
// expect(wrapper.vm.answers.length).toEqual(3);
// });
}); });
function setupMocks({ mountOptions, mixins, props, isShallowMount = true }) { function setupMocks({ mountOptions, mixins, props, isShallowMount = true }) {

View file

@ -68,8 +68,8 @@ export default {
props: { props: {
modelValue: { modelValue: {
type: Object, type: Object,
default: () => null,
}, },
serviceZipCode: String,
selectedAppointmentType: String, selectedAppointmentType: String,
cmsWidgetName: String, cmsWidgetName: String,
validationRules: String, validationRules: String,
@ -81,16 +81,12 @@ export default {
}, },
selectedValue: { selectedValue: {
get: function () { get: function () {
return this.modelValue; return this.modelValue?.providerNumber;
}, },
set: function (newValue) { set: function (newValue) {
// Button Question only supports primitive values so we must get the full object to emit to the page // Button Question only supports Number, String data types so we must get the full object to emit
const provider = this.shopProviders?.find( const provider = this.getSelectedProviderObject(newValue);
(provider) => provider.providerNumber == newValue this.$emit("update:modelValue", provider);
);
this.$emit("update:modelValue", newValue);
this.$emit("providerSelected", provider);
}, },
}, },
displayDropoffInformation() { displayDropoffInformation() {
@ -170,11 +166,6 @@ export default {
resetAnswers() { resetAnswers() {
this.answers = []; this.answers = [];
this.shopIndex = 0; this.shopIndex = 0;
this.selectedValue = "";
if (this.$refs.buttonQuestion) {
this.$refs.buttonQuestion.resetField();
}
}, },
async reloadShopData(serviceZipCode) { async reloadShopData(serviceZipCode) {
const result = await this.loadData(serviceZipCode); const result = await this.loadData(serviceZipCode);
@ -185,6 +176,20 @@ export default {
await nextTick(); await nextTick();
await this.getNextShopsFromList(); await this.getNextShopsFromList();
}, },
getSelectedProviderObject(providerNumber) {
const provider = this.shopProviders?.find(
(provider) => provider.providerNumber == providerNumber
);
return provider;
},
getSelectedProviderIndex(providers, selectedProviderNumber) {
const index = providers.findIndex(
(provider) => provider.providerNumber == selectedProviderNumber
);
return index;
},
}, },
watch: { watch: {
selectedAppointmentType: { selectedAppointmentType: {
@ -193,6 +198,12 @@ export default {
await this.$nextTick(); await this.$nextTick();
this.selectedValue = null;
this.$refs.buttonQuestion?.resetField();
await this.$nextTick();
if (newValue !== "Mobile") { if (newValue !== "Mobile") {
await this.getNextShopsFromList(); await this.getNextShopsFromList();
} }
@ -200,19 +211,19 @@ export default {
}, },
shopProviders: { shopProviders: {
async handler(newValue) { async handler(newValue) {
//this.resetAnswers();
await this.$nextTick(); await this.$nextTick();
if (this.selectedAppointmentType) { if (this.selectedAppointmentType) {
const selectedShopIndex = newValue.findIndex( const selectedShopIndex = this.getSelectedProviderIndex(
(provider) => provider.providerNumber == this.modelValue newValue,
this.modelValue?.providerNumber
); );
if (selectedShopIndex >= 3) { if (selectedShopIndex >= 3) {
await this.getNextShopsFromList(selectedShopIndex + 1); await this.getNextShopsFromList(selectedShopIndex + 1);
} else { } else {
await this.getNextShopsFromList(); await this.getNextShopsFromList();
await this.$nextTick();
} }
} }
}, },