-
@@ -57,17 +50,14 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import alert from "@/ux-components/alert/alert";
-import loadingModal from '@/common-components/loading-modal/loading-modal.vue';
+import loadingModal from "@/common-components/loading-modal/loading-modal.vue";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { Form } from "vee-validate";
import store from "@/store";
-import { storeMutations } from "@/constants/store-mutations.js";
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
-import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
-import { assertParenthesizedExpression } from "@babel/types";
export default {
name: "vehicle-parts",
@@ -77,25 +67,25 @@ export default {
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Settle promises and get results
const promiseResultMap = [
- {
- resultKey: "cmsContent",
- promise: cmsContentPromise,
- },
+ {
+ resultKey: "cmsContent",
+ promise: cmsContentPromise,
+ },
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
- vm.setCmsContent(resultMap.cmsContent);
+ vm.setCmsContent(resultMap.cmsContent);
- // Glass Part Question dynamic component
- Object.keys(vm.$refs)
- .filter((r) => r.includes(vm.RefPrefix) && vm.$refs[r][0] !== undefined)
- .forEach((c) =>
- vm.$refs[c][0].initializeComponent({
- ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
- FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget,
- })
- );
+ // Glass Part Question dynamic component
+ Object.keys(vm.$refs)
+ .filter((r) => r.includes(vm.RefPrefix) && vm.$refs[r][0] !== undefined)
+ .forEach((c) =>
+ vm.$refs[c][0].initializeComponent({
+ ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
+ FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget,
+ })
+ );
});
},
data() {
@@ -111,11 +101,13 @@ export default {
this.selectedGlassPartNumbers.length !== this.PartsFromApi.partsOrQuestions.length
);
},
- selectedGlassPartNumbers () {
+ selectedGlassPartNumbers() {
// Compile all selected parts from the page.
const numberArray = [];
for (let glassPart of Object.values(this.selectedGlassParts)) {
- if (glassPart?.partNumber) { numberArray.push(glassPart.partNumber) }
+ if (glassPart?.partNumber) {
+ numberArray.push(glassPart.partNumber);
+ }
}
return numberArray;
},
@@ -132,7 +124,8 @@ export default {
ColorAnswerText: p.color,
FeatureAnswers: [
{
- FeatureAnswerText: p.description === "" ? p.color : p.description,
+ FeatureAnswerText:
+ p.description === "" ? p.color : p.description,
PartNumber: p.partNumber,
},
],
@@ -156,16 +149,17 @@ export default {
methods: {
arePagePrerequisitesValid() {
// Check if isRepair is populated and if the pageData we need is here (Parts data)
- return store.getters.damage.isRepair != null && store.getters.pageData(fmgPageValues.VEHICLE_PARTS) &&
- Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0;
+ return (
+ store.getters.damage.isRepair != null &&
+ store.getters.pageData(fmgPageValues.VEHICLE_PARTS) &&
+ Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0
+ );
},
async forwardButtonAction() {
const matchedParts = [];
// Match them to the parts from the API.
- for (let [key, value] of Object.entries(
- this.PartsFromApi.partsOrQuestions
- )) {
+ for (let [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) {
for (let [partKey, partValue] of Object.entries(value.parts)) {
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
@@ -188,7 +182,11 @@ export default {
throw new Error("Could not match any parts to the selected parts");
}
- await this.dispatchStoreAction(this.storeActions.RESET_MOLDING_AND_CAPABILITY_QUESTIONS_IF_NEEDED, matchedParts, false);
+ await this.dispatchStoreAction(
+ this.storeActions.RESET_MOLDING_AND_CAPABILITY_QUESTIONS_IF_NEEDED,
+ matchedParts,
+ false
+ );
// Navigate to the next page
this.navigateForward(matchedParts);
@@ -196,20 +194,18 @@ export default {
LoadInitialPartsData() {
const partsData = this.PartsFromApi;
- const alreadyPopulatedPartsData =
+ this.alreadyPopulatedPartsData =
this.$store.getters.lineItems.glassParts === null
- ? []
- : this.$store.getters.lineItems.glassParts;
+ ? []
+ : this.$store.getters.lineItems.glassParts;
partsData.partsOrQuestions.map((g) => {
// If the part is already populated, use the value from the store and populate the v-model.
- Object.keys(alreadyPopulatedPartsData).forEach((key) => {
- const partNumber = alreadyPopulatedPartsData[key].partNumber;
+ Object.keys(this.alreadyPopulatedPartsData).forEach((key) => {
+ const partNumber = this.alreadyPopulatedPartsData[key].partNumber;
g.parts.forEach((p) => {
if (p.partNumber === partNumber) {
- this.selectedGlassParts[g.glassLocation + "-" + g.glassName] = {
- [g.glassLocation]: [partNumber],
- };
+ this.selectedGlassParts[g.glassLocation + "-" + g.glassName] = p;
}
});
});
diff --git a/src/layouts/vehicle-style/style-question/style-question.vue b/src/layouts/vehicle-style/style-question/style-question.vue
index 4e6e90798..806f7ac41 100644
--- a/src/layouts/vehicle-style/style-question/style-question.vue
+++ b/src/layouts/vehicle-style/style-question/style-question.vue
@@ -23,7 +23,7 @@ export default {
name: "style-question",
data() {
return {
- styles: Array,
+ styles: [],
};
},
props: {
diff --git a/src/layouts/vehicle-year/year-question/year-question.vue b/src/layouts/vehicle-year/year-question/year-question.vue
index 8889a0fdc..6851f282c 100644
--- a/src/layouts/vehicle-year/year-question/year-question.vue
+++ b/src/layouts/vehicle-year/year-question/year-question.vue
@@ -21,7 +21,7 @@ export default {
name: "year-question",
data() {
return {
- years: Array,
+ years: [],
};
},
props: {
diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js
index 6eb18e462..e773c6a01 100644
--- a/src/mixins/analytics-mixin.js
+++ b/src/mixins/analytics-mixin.js
@@ -48,6 +48,7 @@ export default {
pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null) {
const currentPageName = getPageNameByQueryString();
const labelToLog = getValueToLog(label, valueToLogType);
+
const eventToBePushed = {
'event': GaEvents.GENERIC_EVENT,
'category': category,
@@ -140,7 +141,7 @@ export default {
noSession() {
return getSessionKeyValue() === 0 || getSessionIdValue() === '00000000-0000-0000-0000-000000000000';
- }
+ },
},
computed: {
analyticsPageEvents() {
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
index f175c61b8..6189c0b00 100644
--- a/src/mixins/base-mixin.js
+++ b/src/mixins/base-mixin.js
@@ -6,12 +6,11 @@ import { vehicleCategories } from "@/constants/vehicle-categories.js";
import { routerParams } from "@/router/router-constants/router-params";
import { queryStrings } from "@/constants/query-strings";
import { dynamicStrings } from "@/constants/dynamic-strings";
-import { settleAllPromises } from "@/helpers/layout-helper";
export default {
data() {
return {
- cmsContentByWidget: {}
+ cmsContentByWidget: {},
};
},
methods: {
@@ -19,7 +18,9 @@ export default {
this.$root.cmsContentByWidget = cmsContent;
},
getCmsContent(widgetName, fieldName) {
- return this.$root.cmsContentByWidget?.[widgetName]?.[fieldName] ? this.$root.cmsContentByWidget[widgetName][fieldName] : '';
+ return this.$root.cmsContentByWidget?.[widgetName]?.[fieldName]
+ ? this.$root.cmsContentByWidget[widgetName][fieldName]
+ : "";
},
dispatchStoreAction(type, payload, encodePayload = true) {
// Encode the payload if required
@@ -32,7 +33,7 @@ export default {
savePageDataToStore(page, data) {
store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data });
},
- onSubmit() { }, // DO NOT REMOVE; needed to prevent default form submit behavior
+ onSubmit() {}, // DO NOT REMOVE; needed to prevent default form submit behavior. Cannot use .prevent modifier for vee-validate Form
onInvalidSubmit({ values, errors, results }) {
// identify the first error field and put focus on it
// get error names array
@@ -49,14 +50,17 @@ export default {
return footerInfoBox ? footerInfoBox.offsetHeight : 0;
},
async getZipCodeData(zipCode) {
- const serviceZipValidationResponse = await this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: zipCode });
-
- return {
- isValid: serviceZipValidationResponse.data.isValid,
+ const serviceZipValidationResponse = await this.dispatchStoreAction(
+ storeActions.VALIDATE_ZIP,
+ { zip: zipCode }
+ );
+
+ return {
+ isValid: serviceZipValidationResponse.data.isValid,
isServiceable: serviceZipValidationResponse.data.isServiceable,
- state: serviceZipValidationResponse.data.state
+ state: serviceZipValidationResponse.data.state,
};
- }
+ },
},
computed: {
storeActions() {
@@ -74,13 +78,13 @@ export default {
routerParams() {
return routerParams;
},
- queryStrings(){
+ queryStrings() {
return queryStrings;
},
- dynamicStrings(){
+ dynamicStrings() {
return dynamicStrings;
},
- cssClassNameForCmsWidget(){
+ cssClassNameForCmsWidget() {
return "widget-name-" + this.cmsWidgetName;
},
},
diff --git a/src/mixins/input-button-wrapper-mixin.js b/src/mixins/input-button-wrapper-mixin.js
new file mode 100644
index 000000000..1878de18b
--- /dev/null
+++ b/src/mixins/input-button-wrapper-mixin.js
@@ -0,0 +1,36 @@
+import { inputButtonProps } from "@/common-components/base-input-button/button-functionality-props";
+
+export default {
+ model: {
+ prop: "modelValue",
+ event: "change",
+ },
+ props: {
+ ...inputButtonProps,
+ buttonLabel: [Number, String],
+ buttonLabelSubCopy: String,
+ buttonImage: String,
+ buttonImageId: String,
+ altText: {
+ type: String,
+ default: "",
+ },
+ textPosition: String,
+ screenReaderOnlyText: String,
+ isWide: Boolean,
+ },
+ computed: {
+ selectedValue: {
+ get() {
+ return this.modelValue;
+ },
+ set(e) {
+ if (this.preHandleAnswerChange) {
+ this.preHandleAnswerChange(e);
+ }
+
+ this.$emit("update:modelValue", e);
+ },
+ },
+ },
+};
\ No newline at end of file
diff --git a/src/mixins/input-button-wrapper-mixin.spec.js b/src/mixins/input-button-wrapper-mixin.spec.js
new file mode 100644
index 000000000..c0028ddab
--- /dev/null
+++ b/src/mixins/input-button-wrapper-mixin.spec.js
@@ -0,0 +1,317 @@
+import { mount } from "@vue/test-utils";
+import baseInputButton from "@/common-components/base-input-button/base-input-button";
+import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
+import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal";
+import listButton from "@/ux-components/list-button/list-button";
+import listCard from "@/ux-components/list-card/list-card";
+import radio from "@/ux-components/radio/radio";
+
+describe("input-button-wrapper-mixin", () => {
+ describe("mouse clicks", () => {
+ describe("checkbox", () => {
+ test("click on both => both are selected", async () => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: true,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+ expect(inputButtonOne.vm.isMultiSelect).toBe(true);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
+ expect(wrapper.vm.value).toEqual([]);
+
+ await inputButtonOne.find("input").trigger("click");
+ await inputButtonTwo.find("input").trigger("click");
+
+ // Assert
+ expect(wrapper.vm.value).toEqual(["value1", "value2"]);
+ });
+
+ test("click input 1, 2, 1 => only input 2 selected", async () => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: true,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+ expect(inputButtonOne.vm.isMultiSelect).toBe(true);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
+ expect(wrapper.vm.value).toEqual([]);
+
+ await inputButtonOne.find("input").trigger("click");
+ await inputButtonTwo.find("input").trigger("click");
+ await inputButtonOne.find("input").trigger("click");
+
+ // Assert
+ expect(wrapper.vm.value).toEqual(["value2"]);
+ });
+ });
+
+ describe("radio", () => {
+ test("click on both => last clicked is selected", async () => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: false,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+ expect(inputButtonOne.vm.isMultiSelect).toBe(false);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
+ expect(wrapper.vm.value).toEqual("");
+
+ await inputButtonOne.find("input").trigger("click");
+ await inputButtonTwo.find("input").trigger("click");
+
+ // Assert
+ expect(wrapper.vm.value).toEqual("value2");
+ });
+
+ test("click input 1, 2, 1 => input 1 is selected", async () => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: false,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+ expect(inputButtonOne.vm.isMultiSelect).toBe(false);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
+ expect(wrapper.vm.value).toEqual("");
+
+ await inputButtonOne.find("input").trigger("click");
+ await inputButtonTwo.find("input").trigger("click");
+ await inputButtonOne.find("input").trigger("click");
+
+ // Assert
+ expect(wrapper.vm.value).toEqual("value1");
+ });
+ });
+ });
+
+ describe("initial values", () => {
+ describe("checkbox", () => {
+ const defaultCheckedCases = [
+ [["value2"], false, true],
+ [["value1", "value2"], true, true],
+ [["value1"], true, false],
+ [[], false, false],
+ ];
+ test.each(defaultCheckedCases)(
+ "initial value is %s => correct input buttons are selected",
+ async (modelValue, isInputButtonOneChecked, isInputButtonTwoChecked) => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: true,
+ initialValue: modelValue,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputs = wrapper.findAll("input");
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+
+ // Assert
+ expect(inputButtonOne.vm.isMultiSelect).toBe(true);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
+ expect(inputs[0].element.checked).toBe(isInputButtonOneChecked);
+ expect(inputs[1].element.checked).toBe(isInputButtonTwoChecked);
+ expect(wrapper.vm.value).toEqual(modelValue);
+ }
+ );
+ });
+
+ describe("radio", () => {
+ const defaultCheckedCases = [
+ ["", false, false],
+ ["value1", true, false],
+ ["value2", false, true],
+ [[], false, false],
+ ];
+ test.each(defaultCheckedCases)(
+ "initial value is %s => correct input buttons are selected",
+ async (modelValue, isInputButtonOneChecked, isInputButtonTwoChecked) => {
+ // Arrange
+ const { wrapper } = setupBaseInputButtonWrapper({
+ mockData: {
+ isMultiSelect: false,
+ initialValue: modelValue,
+ },
+ });
+
+ // Act
+ const buttonWrappers = wrapper.findAllComponents({
+ name: "baseInputButtonWrapper",
+ });
+ const inputs = wrapper.findAll("input");
+ const inputButtonOne = buttonWrappers.at(0);
+ const inputButtonTwo = buttonWrappers.at(1);
+
+ // Assert
+ expect(inputButtonOne.vm.isMultiSelect).toBe(false);
+ expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
+ expect(inputs[0].element.checked).toBe(isInputButtonOneChecked);
+ expect(inputs[1].element.checked).toBe(isInputButtonTwoChecked);
+ expect(wrapper.vm.value).toEqual(modelValue);
+ }
+ );
+ });
+ });
+
+ // shared checks between components that use input-button-wrapper-mixin
+ describe("shared checks", () => {
+ const inputButtonComponents = [listButtonHorizontal, listButton, listCard, radio];
+ test.each(inputButtonComponents.map((x) => [x.name, x]))(
+ "%s - should return input type checkbox if isMultiSelect is true",
+ async (name, inputButtonComponent) => {
+ // Act
+ const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
+ component: inputButtonComponent,
+ mockData: {
+ propsData: {
+ isMultiSelect: true,
+ },
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("input");
+ expect(input.attributes().type).toEqual("checkbox");
+ }
+ );
+
+ test.each(inputButtonComponents.map((x) => [x.name, x]))(
+ "%s - return input type radio if isMultiSelect is false or not specified",
+ async (name, inputButtonComponent) => {
+ // Act
+ const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
+ component: inputButtonComponent,
+ mockData: {
+ propsData: {
+ isMultiSelect: false,
+ },
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("input");
+ expect(input.attributes().type).toEqual("radio");
+ }
+ );
+
+ const selectedValues = ["something", ["test"]];
+ inputButtonComponents.forEach((inputButtonComponent) => {
+ test.each(selectedValues)(
+ `${inputButtonComponent.name} with selectedValue %s - should emit button value on click`,
+ async (selectedValue) => {
+ // Act
+ const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
+ component: inputButtonComponent,
+ mockData: {
+ propsData: {
+ isRadioHorizontal: true,
+ buttonLabel: "Windshield",
+ value: "List Card Checkbox",
+ groupID: "radio-demo-1",
+ groupName: "radio 1",
+ buttonImage: "windshield-damage.svg",
+ isRequired: true,
+ isWide: false,
+ modelValue: ["List Card Checkbox"],
+ buttonID: "list-card-id",
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = selectedValue;
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual(selectedValue);
+ }
+ );
+ });
+ });
+});
+
+function setupMocksForComponentsUsingInputButtonWrapperMixin({ mockData, component }) {
+ const wrapper = mount(component, {
+ ...mockData,
+ propsData: {
+ ...mockData.propsData,
+ groupName: "my-group",
+ modelValue: mockData.propsData?.isMultiSelect ? ["5"] : "5",
+ value: "4",
+ },
+ mixins: [inputButtonWrapperMixin],
+ });
+
+ return { wrapper };
+}
+
+function setupBaseInputButtonWrapper({ mockData = {} }) {
+ baseInputButton.methods.pushClickEventToGA = jest.fn();
+
+ const baseInputButtonWrapper = {
+ name: "baseInputButtonWrapper",
+ components: { baseInputButton },
+ template: '
',
+ mixins: [inputButtonWrapperMixin],
+ };
+
+ let parentComponentTemplate = `
`;
+ parentComponentTemplate += ``;
+ parentComponentTemplate += ``;
+ parentComponentTemplate += `
`;
+ const wrapper = mount(
+ {
+ data() {
+ return {
+ value: mockData.initialValue ?? (mockData.isMultiSelect ? [] : ""),
+ $route: {
+ query: {
+ fmgPage: "myPage",
+ },
+ },
+ };
+ },
+ template: parentComponentTemplate,
+ components: { baseInputButtonWrapper },
+ },
+ {}
+ );
+
+ return { wrapper };
+}
diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js
index 9884117d7..b4fc5f893 100644
--- a/src/mixins/vehicle-questions-mixin.js
+++ b/src/mixins/vehicle-questions-mixin.js
@@ -177,7 +177,6 @@ export default {
// if single parts only
const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions);
// save to store lineItems.glassParts
- // TODO KO
self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts);
self.$refs.loadingModal.showModal();
diff --git a/src/router/index.js b/src/router/index.js
index c9e0a4a52..a11dae75c 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -238,7 +238,7 @@ function navigateToUrl(url, optionalQuery = {}) {
for (const queryKey in optionalQuery) {
externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]);
}
-
+
window.location.assign(externalUrl);
}
diff --git a/src/store/index.js b/src/store/index.js
index 6dcfd0162..c4ee9e282 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,4 +1,4 @@
-import { createStore } from "vuex";
+import { createStore, Store } from "vuex";
import { endpoints } from "@/constants/endpoints.js";
import { storeMutations } from "@/constants/store-mutations";
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
@@ -50,22 +50,22 @@ const getDefaultState = () => {
glassToReplace: null,
partQuestionAnswers: null,
moldingQuestionAnswers: null,
- capabilityQuestionAnswers: null
+ capabilityQuestionAnswers: null,
},
lineItems: {
- glassParts: null
+ glassParts: null,
},
payment: {
isInsurance: null,
insuranceCoverage: {
- isVerified: null
- }
+ isVerified: null,
+ },
},
referralNumber: null,
referralDate: null,
referralCorrelationId: null,
accountNumber: 0,
- eon: null
+ eon: null,
},
applicationUser: {
eventBus: [],
@@ -76,9 +76,15 @@ const getDefaultState = () => {
crmCustomerId: null,
lastPageVisited: null,
experiments: [],
- triggeredSiteEntry: false
+ triggeredSiteEntry: false,
},
- }
+ // gaClickInformation: {
+ // currentlySelectedValues: {},
+ // firedGaClickEventValues: {},
+ // lastFocusedInputGroup: "",
+ // wasLastFocusedInputMultiselect: undefined,
+ // },
+ };
};
export const state = getDefaultState();
@@ -195,7 +201,6 @@ export const mutations = {
state.order.customer.emailAddress = customerEmailAddress;
},
updateVehicle(state, vehicleInfo) {
-
state.order.vehicle.year = vehicleInfo.year;
state.order.vehicle.make = vehicleInfo.make;
state.order.vehicle.model = vehicleInfo.model;
@@ -209,7 +214,8 @@ export const mutations = {
state.order.vehicle.imageColor = vehicleInfo.imageVifColor;
},
updateRegistration(state, registrationInfo) {
- state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate;
+ state.order.vehicle.registration.licensePlate =
+ registrationInfo?.licensePlate;
state.order.vehicle.registration.address = registrationInfo?.address;
state.order.vehicle.registration.city = registrationInfo?.city;
state.order.vehicle.registration.state = registrationInfo?.state;
@@ -235,7 +241,7 @@ export const mutations = {
state.applicationUser.crmCustomerId = crmCustomerId;
},
updateLastPageVisited(state, lastPageVisited) {
- state.applicationUser.lastPageVisited = lastPageVisited
+ state.applicationUser.lastPageVisited = lastPageVisited;
},
// EVENT BUS MUTATIONS
addEventToBus(state, event) {
@@ -244,8 +250,7 @@ export const mutations = {
removeEventFromBus(state, eventData) {
const matchedEvent = state.applicationUser.eventBus.find(
({ category, subCategory }) =>
- category === eventData.category &&
- subCategory === eventData.subCategory
+ category === eventData.category && subCategory === eventData.subCategory
);
const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
@@ -331,7 +336,7 @@ export const mutations = {
state: orderInformation.vehicle.registration.state,
zipCode: orderInformation.vehicle.registration.zipCode,
licensePlate: orderInformation.vehicle.registration.licensePlateNumber,
- }
+ },
});
state.order.damage.glassToReplace = orderInformation.damage.glassToReplace;
@@ -340,13 +345,18 @@ export const mutations = {
state.order.lineItems.glassParts = orderInformation.parts;
state.order.accountNumber = orderInformation.accountNumber;
- state.order.serviceLocation.address = orderInformation.serviceLocation.streetAddress,
- state.order.serviceLocation.city = orderInformation.serviceLocation.city,
- state.order.serviceLocation.state = orderInformation.serviceLocation.state,
- state.order.serviceLocation.zipCode = orderInformation.serviceLocation.zipCode;
+ (state.order.serviceLocation.address =
+ orderInformation.serviceLocation.streetAddress),
+ (state.order.serviceLocation.city =
+ orderInformation.serviceLocation.city),
+ (state.order.serviceLocation.state =
+ orderInformation.serviceLocation.state),
+ (state.order.serviceLocation.zipCode =
+ orderInformation.serviceLocation.zipCode);
state.order.payment.isInsurance = orderInformation.IsInsuranceOrder;
- state.order.payment.insuranceCoverage.isVerified = orderInformation?.insuranceInfo.coverageVerified;
+ state.order.payment.insuranceCoverage.isVerified =
+ orderInformation?.insuranceInfo.coverageVerified;
state.order.customer.emailAddress = orderInformation.customer.emailAddress;
state.applicationUser.experiments = orderInformation.experiments;
@@ -356,8 +366,23 @@ export const mutations = {
},
updateTriggeredSiteEntry(state, wasSiteEntryTriggered) {
state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
- }
-}
+ },
+ // START GA click event mutations
+ // updateCurrentlySelectedValues(state, groupName, value) {
+ // state.gaClickInformation.currentlySelectedValues[groupName] = value;
+ // },
+ // updateFiredGaClickEventValues(state, groupName, value) {
+ // state.gaClickInformation.firedGaClickEventValues[groupName] = value;
+ // },
+ // updateLastFocusedInputGroup(state, groupName) {
+ // state.gaClickInformation.lastFocusedInputGroup = groupName;
+ // },
+ // updateWasLastFocusedInputMultiselect(state, wasLastFocusedInputMultiselect) {
+ // state.gaClickInformation.wasLastFocusedInputMultiselect =
+ // wasLastFocusedInputMultiselect;
+ // },
+ // END GA click event mutations
+};
// Export Getters
export const getters = {
@@ -373,7 +398,9 @@ export const getters = {
eventBus: (state) => state.applicationUser.eventBus,
damage: (state) => state.order.damage,
lineItems: (state) => state.order.lineItems,
- pageData: (state) => (page) => { return state.applicationUser.pageData[page]; },
+ pageData: (state) => (page) => {
+ return state.applicationUser.pageData[page];
+ },
applicationUser: (state) => state.applicationUser,
order: (state) => state.order,
payment: (state) => state.order.payment,
@@ -390,7 +417,8 @@ export const getters = {
funnelServiceState: state.order.serviceLocation.state,
funnelServiceZipCode: state.order.serviceLocation.zipCode,
funnelParentAccountNumber: state.order.accountNumber,
- funnelIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
+ funnelIsCoverageVerified:
+ state.order.payment.insuranceCoverage.isVerified,
funnelHasRecalibrationPart: getHasRecalibrationPart(state),
funnelSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
funnelSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.WINDSHIELD),
@@ -403,8 +431,12 @@ export const getters = {
funnelOrderPartTypes: [...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "recalibrationType"), ...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, "recalibrationType")],
}
},
- experimentSettings: (state) => state.applicationUser.experiments.map(x => x.settings).reduce((r, c) => Object.assign(r, c), {}) ?? {}
-}
+ experimentSettings: (state) =>
+ state.applicationUser.experiments
+ .map((x) => x.settings)
+ .reduce((r, c) => Object.assign(r, c), {}) ?? {},
+ // gaClickInformation: (state) => state.gaClickInformation,
+};
function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
return (array ?? []).map(x => x[propertyName]).filter(x => x);
@@ -412,7 +444,6 @@ function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) {
// Export Actions
export const actions = {
-
// Vehicle API Actions
getVehicleYears(context) {
return globalMethods.callHttpClient({
@@ -443,11 +474,14 @@ export const actions = {
endpoint: endpoints.LookupVinByPlate.url,
payload: {
licensePlate: licensePlate,
- licenseState: licenseState
+ licenseState: licenseState,
},
});
},
- lookupVinByAddress(context, { licenseLastName, licenseStreetAddress, licenseZip, licenseState }) {
+ lookupVinByAddress(
+ context,
+ { licenseLastName, licenseStreetAddress, licenseZip, licenseState }
+ ) {
return globalMethods.callHttpClient({
method: endpoints.LookupVinByAddress.method,
endpoint: endpoints.LookupVinByAddress.url,
@@ -455,7 +489,7 @@ export const actions = {
licenseLastName: licenseLastName,
licenseStreetAddress: licenseStreetAddress,
licenseZip: licenseZip,
- licenseState: licenseState
+ licenseState: licenseState,
},
});
},
@@ -489,10 +523,22 @@ export const actions = {
})
.then((response) => {
context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId);
- context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, response.data.imageUrl);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, response.data.imageVifNumber);
- context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, response.data.imageVifColor);
+ context.commit(
+ storeMutations.UPDATE_VEHICLE_CATEGORY,
+ response.data.category
+ );
+ context.commit(
+ storeMutations.UPDATE_VEHICLE_IMAGE_URL,
+ response.data.imageUrl
+ );
+ context.commit(
+ storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER,
+ response.data.imageVifNumber
+ );
+ context.commit(
+ storeMutations.UPDATE_VEHICLE_IMAGE_COLOR,
+ response.data.imageVifColor
+ );
return response;
});
},
@@ -506,8 +552,8 @@ export const actions = {
validateZip(context, { zip }) {
return globalMethods.callHttpClient({
methods: endpoints.ValidateZip.method,
- endpoint: `${endpoints.ValidateZip.url}/${zip}`
- })
+ endpoint: `${endpoints.ValidateZip.url}/${zip}`,
+ });
},
// Dependency Actions
@@ -522,7 +568,7 @@ export const actions = {
},
resetRegistrationAndDependencies(context) {
context.commit(storeMutations.RESET_REGISTRATION_STATE);
- context.commit(storeMutations.RESET_GLASS_PARTS_STATE)
+ context.commit(storeMutations.RESET_GLASS_PARTS_STATE);
},
resetPartsAndDependencies(context) {
context.commit(storeMutations.RESET_GLASS_PARTS_STATE);
@@ -578,8 +624,8 @@ export const actions = {
assignmentId: experiment.assignmentId,
sessionKey: sessionKey,
pageName: pageName,
- }
- }
+ },
+ },
});
},
@@ -587,13 +633,28 @@ export const actions = {
updateStoreWithSaveSessionResponse(context, { referralNumber, referralDate, referralCorrelationId, eon, accountNumber, savedSessionId, crmCustomerId }) {
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
- context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
+ context.commit(
+ storeMutations.UPDATE_REFERRAL_CORRELATION_ID,
+ referralCorrelationId
+ );
context.commit(storeMutations.UPDATE_EON, eon);
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, accountNumber);
context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId);
context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId);
},
- logPageView(context, { userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
+ logPageView(
+ context,
+ {
+ userId,
+ sessionKey,
+ pageName,
+ sessionId,
+ action,
+ event,
+ shouldUseSessionId,
+ experimentsForUser,
+ }
+ ) {
var payload = {
userId: userId,
sessionKey: sessionKey,
@@ -603,17 +664,31 @@ export const actions = {
action: action,
event: event,
shouldUseSessionId: shouldUseSessionId,
- experimentsForUser: experimentsForUser
+ experimentsForUser: experimentsForUser,
};
return globalMethods.callHttpClient({
method: endpoints.LogPageView.method,
endpoint: endpoints.LogPageView.url,
payload: payload,
- logApiCall: false
+ logApiCall: false,
});
},
- logCustomEvent(context, { userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) {
+ logCustomEvent(
+ context,
+ {
+ userId,
+ sessionKey,
+ pageName,
+ sessionId,
+ category,
+ action,
+ label,
+ value,
+ shouldUseSessionId,
+ experimentsForUser,
+ }
+ ) {
var payload = {
userId: userId,
sessionKey: sessionKey,
@@ -625,14 +700,14 @@ export const actions = {
label: label,
value: value,
shouldUseSessionId: shouldUseSessionId,
- experimentsForUser: experimentsForUser
+ experimentsForUser: experimentsForUser,
};
return globalMethods.callHttpClient({
method: endpoints.LogCustomEvent.method,
endpoint: endpoints.LogCustomEvent.url,
payload: payload,
- logApiCall: false
+ logApiCall: false,
});
},
initializeSession(context, { userId, sessionId, userAgent, referrer }) {
@@ -644,22 +719,28 @@ export const actions = {
userAgent: userAgent,
operatorId: "WEB",
userName: "SafeliteConceptFunnel",
- referrer: referrer
+ referrer: referrer,
};
return globalMethods.callHttpClient({
method: endpoints.InitializeSession.method,
endpoint: endpoints.InitializeSession.url,
payload: payload,
- logApiCall: false
+ logApiCall: false,
});
},
// Misc Actions
- setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
+ setReferralInformation(
+ context,
+ { referralNumber, referralDate, referralCorrelationId, eon }
+ ) {
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
- context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
+ context.commit(
+ storeMutations.UPDATE_REFERRAL_CORRELATION_ID,
+ referralCorrelationId
+ );
context.commit(storeMutations.UPDATE_EON, eon);
},
@@ -667,11 +748,14 @@ export const actions = {
return globalMethods.callHttpClient({
method: endpoints.GetExperimentsByUser.method,
endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`,
- payload: {}
+ payload: {},
});
},
- async runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) {
+ async runExperimentsForTrigger(
+ context,
+ { userId, triggerEvent, triggerValue }
+ ) {
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
}
@@ -681,7 +765,7 @@ export const actions = {
userId: userId,
triggerEvent: triggerEvent,
triggerValue: triggerValue,
- experimentOrder: context.getters.experimentOrder
+ experimentOrder: context.getters.experimentOrder,
};
const response = await globalMethods.callHttpClient({
@@ -690,7 +774,10 @@ export const actions = {
payload: payload,
});
- context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments);
+ context.commit(
+ storeMutations.UPDATE_EXPERIMENTS,
+ response.data.experiments
+ );
},
getEvoxImage(context, { relativeUrl }) {
@@ -722,7 +809,7 @@ export const actions = {
carId: carId,
glassPieces: glassArrayForPayload,
zip: zipCode,
- vin: vin
+ vin: vin,
},
});
@@ -756,7 +843,7 @@ export const actions = {
glassPieces: glassArrayForPayload,
answerResults: resultsArrayForPayload,
zip: zipCode,
- vin: vin
+ vin: vin,
},
});
@@ -770,24 +857,31 @@ export const actions = {
return globalMethods.callHttpClient({
method: endpoints.GetCapabilityQuestions.method,
endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`,
- })
+ });
},
getPartFromCapabilityQuestionAnswer(context, glassLocation) {
- const pageData = context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS);
+ const pageData = context.getters.pageData(
+ fmgPageValues.CAPABILITY_QUESTIONS
+ );
- const part = pageData.partsOrQuestions.find(x => x.glassLocation === glassLocation).parts[0];
- const capabilityQuestionAnswers = context.getters.damage.capabilityQuestionAnswers;
- const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(x => x.glassLocation === glassLocation);
+ const part = pageData.partsOrQuestions.find(
+ (x) => x.glassLocation === glassLocation
+ ).parts[0];
+ const capabilityQuestionAnswers =
+ context.getters.damage.capabilityQuestionAnswers;
+ const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(
+ (x) => x.glassLocation === glassLocation
+ );
return globalMethods.callHttpClient({
method: endpoints.GetPartFromCapabilityAnswer.method,
endpoint: endpoints.GetPartFromCapabilityAnswer.url,
payload: {
part,
- capabilityAnswerResults: capabilityQuestionAnswersForPart
- }
- })
+ capabilityAnswerResults: capabilityQuestionAnswersForPart,
+ },
+ });
},
// Session API Actions
@@ -825,21 +919,21 @@ export const actions = {
damage: {
numberOfChips: damage.numberOfChips,
glassToReplace: newGlassToReplace,
- isRepair: damage.isRepair
+ isRepair: damage.isRepair,
},
customer: {
emailAddress: order.customer.emailAddress,
},
lineItems: {
- glassParts: lineItems.glassParts
+ glassParts: lineItems.glassParts,
},
serviceLocation: {
streetAddress: order.serviceLocation.address,
city: order.serviceLocation.city,
state: order.serviceLocation.state,
- zipCode: order.serviceLocation.zipCode
+ zipCode: order.serviceLocation.zipCode,
},
- referralNumber: order.referralNumber?.toString(), // TODO It'd be nice to save these as strings in the first place
+ referralNumber: order.referralNumber?.toString(), // TODO It'd be nice to save these as strings in the first place
referralDate: order.referralDate,
accountNumber: order.accountNumber?.toString(),
existingPromoCode: null,
@@ -884,8 +978,7 @@ export const actions = {
// Vehicle
saveVehicleYear(context, year) {
-
- //Reset dependent state when changing
+ //Reset dependent state when changing
if (context.state.order.vehicle.year !== year) {
context.commit(storeMutations.UPDATE_MAKE, null);
context.commit(storeMutations.UPDATE_MODEL, null);
@@ -906,7 +999,6 @@ export const actions = {
}
},
saveVehicleMake(context, make) {
-
//Reset dependent state when changing
if (context.state.order.vehicle.make !== make) {
context.commit(storeMutations.UPDATE_MODEL, null);
@@ -927,8 +1019,7 @@ export const actions = {
}
},
saveVehicleModel(context, model) {
-
- //Reset dependent state when changing
+ //Reset dependent state when changing
if (context.state.order.vehicle.model !== model) {
context.commit(storeMutations.UPDATE_STYLE, null);
context.commit(storeMutations.UPDATE_CAR_ID, null);
@@ -947,7 +1038,7 @@ export const actions = {
}
},
saveVehicleStyle(context, style) {
- //Reset dependent state when changing
+ //Reset dependent state when changing
if (context.state.order.vehicle.style !== style) {
context.commit(storeMutations.UPDATE_CAR_ID, null);
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
@@ -964,20 +1055,32 @@ export const actions = {
context.commit(storeMutations.UPDATE_STYLE, style);
}
},
- saveVehicleDamage(context, { isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount }) {
-
+ saveVehicleDamage(
+ context,
+ { isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount }
+ ) {
const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort();
- const isGlassToReplaceTheSame = (context.state.order.damage.glassToReplace?.length === selectedGlassToReplace.length)
- && context.state.order.damage.glassToReplace
+ const isGlassToReplaceTheSame =
+ context.state.order.damage.glassToReplace?.length ===
+ selectedGlassToReplace.length &&
+ context.state.order.damage.glassToReplace
.slice()
.sort()
- .every((obj, index) => obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation && obj.glassName === selectedGlassPassedInSorted[index].glassName);
- const isWindshieldRepairTheSame = isWindshieldRepair === context.state.order.damage.isRepair;
- const isChipCountTheSame = Array.isArray(selectedWindshieldChipCount) //TODO: fix the underlying components so this is never an array
- ? selectedWindshieldChipCount[0] === context.state.order.damage.numberOfChips
- : selectedWindshieldChipCount === context.state.order.damage.numberOfChips;
+ .every(
+ (obj, index) =>
+ obj.glassLocation ===
+ selectedGlassPassedInSorted[index].glassLocation &&
+ obj.glassName === selectedGlassPassedInSorted[index].glassName
+ );
+ const isWindshieldRepairTheSame =
+ isWindshieldRepair === context.state.order.damage.isRepair;
- const isDamageChanging = !isGlassToReplaceTheSame || !isWindshieldRepairTheSame || (isWindshieldRepair && !isChipCountTheSame);
+ const isChipCountTheSame = selectedWindshieldChipCount === context.state.order.damage.numberOfChips;
+
+ const isDamageChanging =
+ !isGlassToReplaceTheSame ||
+ !isWindshieldRepairTheSame ||
+ (isWindshieldRepair && !isChipCountTheSame);
if (isDamageChanging) {
//Reset dependent state when changing
@@ -985,14 +1088,23 @@ export const actions = {
// Save new values
context.commit(storeMutations.UPDATE_IS_REPAIR, isWindshieldRepair);
- context.commit(storeMutations.UPDATE_NUMBER_OF_CHIPS, isWindshieldRepair ? parseInt(selectedWindshieldChipCount) : null);
- context.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, selectedGlassToReplace);
+ context.commit(
+ storeMutations.UPDATE_NUMBER_OF_CHIPS,
+ isWindshieldRepair ? parseInt(selectedWindshieldChipCount) : null
+ );
+ context.commit(
+ storeMutations.UPDATE_GLASS_TO_REPLACE,
+ selectedGlassToReplace
+ );
}
},
// Vin lookup
- saveVinLookup(context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
- //Reset dependent state when changing
+ saveVinLookup(
+ context,
+ { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }
+ ) {
+ //Reset dependent state when changing
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
@@ -1006,10 +1118,15 @@ export const actions = {
context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo);
}
},
- saveRegistrationLicensePlateLookup(context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
- //Reset dependent state when changing
- if (registrationInfo?.licensePlate !== context.state.order.vehicle.registration?.licensePlate) {
-
+ saveRegistrationLicensePlateLookup(
+ context,
+ { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }
+ ) {
+ //Reset dependent state when changing
+ if (
+ registrationInfo?.licensePlate !==
+ context.state.order.vehicle.registration?.licensePlate
+ ) {
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
if (!isSelectedGlassAvailableForVehicle) {
@@ -1022,10 +1139,25 @@ export const actions = {
context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo);
}
},
- saveRegistrationAddressLookup(context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
- //Reset dependent state when changing
- if (registrationInfo?.address !== context.state.order.vehicle.registration?.address || registrationInfo?.city !== context.state.order.vehicle.registration?.city || registrationInfo?.state !== context.state.order.vehicle.registration?.state || registrationInfo?.zipCode !== context.state.order.vehicle.registration?.zipCode || registrationInfo?.firstName !== context.state.order.vehicle.registration?.firstName || registrationInfo?.lastName !== context.state.order.vehicle.registration?.lastName) {
-
+ saveRegistrationAddressLookup(
+ context,
+ { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }
+ ) {
+ //Reset dependent state when changing
+ if (
+ registrationInfo?.address !==
+ context.state.order.vehicle.registration?.address ||
+ registrationInfo?.city !==
+ context.state.order.vehicle.registration?.city ||
+ registrationInfo?.state !==
+ context.state.order.vehicle.registration?.state ||
+ registrationInfo?.zipCode !==
+ context.state.order.vehicle.registration?.zipCode ||
+ registrationInfo?.firstName !==
+ context.state.order.vehicle.registration?.firstName ||
+ registrationInfo?.lastName !==
+ context.state.order.vehicle.registration?.lastName
+ ) {
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
if (!isSelectedGlassAvailableForVehicle) {
@@ -1040,72 +1172,141 @@ export const actions = {
},
savePartQuestionAnswers(context, partQuestionAnswersArray) {
// if part question answers have changed, reset subsequent question answers
- const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(context.getters.damage.partQuestionAnswers, "result");
- const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(partQuestionAnswersArray, "result")
- const havePartQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length ||
- !sortedPreviousResultsArray?.every((x, i) => x.result === sortedPartQuestionAnswersArray[i].result);
+ const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
+ context.getters.damage.partQuestionAnswers,
+ "result"
+ );
+ const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(
+ partQuestionAnswersArray,
+ "result"
+ );
+ const havePartQuestionAnswersChanged =
+ sortedPreviousResultsArray?.length !==
+ sortedPartQuestionAnswersArray.length ||
+ !sortedPreviousResultsArray?.every(
+ (x, i) => x.result === sortedPartQuestionAnswersArray[i].result
+ );
if (havePartQuestionAnswersChanged) {
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null);
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.VEHICLE_PARTS, data: null });
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.MOLDING_QUESTIONS, data: null });
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.VEHICLE_PARTS,
+ data: null,
+ });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.MOLDING_QUESTIONS,
+ data: null,
+ });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.CAPABILITY_QUESTIONS,
+ data: null,
+ });
}
//Save new values
- context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray);
+ context.commit(
+ storeMutations.UPDATE_PART_QUESTION_ANSWERS,
+ partQuestionAnswersArray
+ );
},
resetMoldingAndCapabilityQuestionAnswersIfNeeded(context, matchedParts) {
- const partsOrQuestionsDataToCompareWith = context.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)?.partsOrQuestions ?? context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)?.partsOrQuestions ?? [];
+ const partsOrQuestionsDataToCompareWith =
+ context.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)
+ ?.partsOrQuestions ??
+ context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)
+ ?.partsOrQuestions ??
+ [];
function getAllPartNumbers(partsOrQuestions) {
return partsOrQuestions[0]?.parts
- ? [...partsOrQuestions].map(glass => glass.parts).flat().map(part => part.partNumber).filter(partNumber => !partNumber.toUpperCase().includes("FEE")).sort().join(",")
- : []
+ ? [...partsOrQuestions]
+ .map((glass) => glass.parts)
+ .flat()
+ .map((part) => part.partNumber)
+ .filter((partNumber) => !partNumber.toUpperCase().includes("FEE"))
+ .sort()
+ .join(",")
+ : [];
}
- const previouslySelectedPartNumbers = getAllPartNumbers(partsOrQuestionsDataToCompareWith);
+ const previouslySelectedPartNumbers = getAllPartNumbers(
+ partsOrQuestionsDataToCompareWith
+ );
const currentlySelectedPartNumbers = getAllPartNumbers(matchedParts);
- const haveSelectedVehiclePartsChanged = previouslySelectedPartNumbers !== currentlySelectedPartNumbers;
+ const haveSelectedVehiclePartsChanged =
+ previouslySelectedPartNumbers !== currentlySelectedPartNumbers;
if (haveSelectedVehiclePartsChanged) {
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null);
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.MOLDING_QUESTIONS, data: null });
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.MOLDING_QUESTIONS,
+ data: null,
+ });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.CAPABILITY_QUESTIONS,
+ data: null,
+ });
}
},
saveMoldingQuestionAnswers(context, moldingQuestionAnswers) {
- const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(context.getters.damage.moldingQuestionAnswers, "partNum");
- const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(moldingQuestionAnswers, "partNum");
- const haveMoldingQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length ||
- !sortedPreviousResultsArray?.every((x, i) => x.partNum === sortedMoldingQuestionAnswersArray[i].partNum);
+ const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
+ context.getters.damage.moldingQuestionAnswers,
+ "partNum"
+ );
+ const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(
+ moldingQuestionAnswers,
+ "partNum"
+ );
+ const haveMoldingQuestionAnswersChanged =
+ sortedPreviousResultsArray?.length !==
+ sortedMoldingQuestionAnswersArray.length ||
+ !sortedPreviousResultsArray?.every(
+ (x, i) => x.partNum === sortedMoldingQuestionAnswersArray[i].partNum
+ );
if (haveMoldingQuestionAnswersChanged) {
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
- context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null });
+ context.commit(storeMutations.UPDATE_PAGE_DATA, {
+ page: fmgPageValues.CAPABILITY_QUESTIONS,
+ data: null,
+ });
}
//Save new values
- context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, moldingQuestionAnswers);
+ context.commit(
+ storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS,
+ moldingQuestionAnswers
+ );
},
saveCapabilityQuestionAnswers(context, capabilityQuestionAnswers) {
- const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(context.getters.damage.capabilityQuestionAnswers, "result");
- const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(capabilityQuestionAnswers, "result");
- const haveCapabilityQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length ||
- !sortedPreviousResultsArray?.every((x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result);
+ const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(
+ context.getters.damage.capabilityQuestionAnswers,
+ "result"
+ );
+ const sortedCapabilityQuestionAnswersArray =
+ sortArrayOfObjectsByPropertyValue(capabilityQuestionAnswers, "result");
+ const haveCapabilityQuestionAnswersChanged =
+ sortedPreviousResultsArray?.length !==
+ sortedCapabilityQuestionAnswersArray.length ||
+ !sortedPreviousResultsArray?.every(
+ (x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result
+ );
if (haveCapabilityQuestionAnswersChanged) {
context.commit(storeMutations.UPDATE_GLASS_PARTS, null);
}
//Save new values
- context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, capabilityQuestionAnswers);
+ context.commit(
+ storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS,
+ capabilityQuestionAnswers
+ );
},
// Misc order actions
saveServiceLocation(context, serviceLocationInfo) {
@@ -1117,7 +1318,6 @@ export const actions = {
saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) {
//Reset dependent state when changing
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
-
if (!isSelectedGlassAvailableForVehicle) {
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
@@ -1132,12 +1332,11 @@ export const actions = {
},
clearVin(context) {
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
- }
-}
+ },
+};
export default createStore({
plugins: [createPersistedState()],
-
// IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons:
// * The CMS can reference the fields by name
// * Return users may have a previous "version" of the model, and we don't want
@@ -1160,23 +1359,20 @@ function getHasRecalibrationPart(state) {
} else { // Has 'requiresRecalibration' but no 'recalibrationType' at all
return true;
}
- } else { // Does not have 'requiresRecalibration'
+ } else {
+ // Does not have 'requiresRecalibration'
return false;
}
-
}
function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
if (!arrayOfObjects) return null;
return arrayOfObjects.sort((a, b) => {
- if (a[propertyName] < b[propertyName])
- return -1;
- else if (a[propertyName] > b[propertyName])
- return 1;
- else
- return 0;
- })
+ if (a[propertyName] < b[propertyName]) return -1;
+ else if (a[propertyName] > b[propertyName]) return 1;
+ else return 0;
+ });
}
function convertGlassPieceNamingForApi(glassArray) {
@@ -1212,4 +1408,4 @@ function convertGlassPieceNamingFromApi(glassArray) {
return glass;
});
return glassArray;
-}
\ No newline at end of file
+}
diff --git a/src/styles/common-error-styles.scss b/src/styles/common-error-styles.scss
index 3d4771ff5..ea39df63c 100644
--- a/src/styles/common-error-styles.scss
+++ b/src/styles/common-error-styles.scss
@@ -3,7 +3,6 @@ html {
&.list-button,
&.list-card,
&.list-card.list-button {
- border: none;
color: $red;
input[type=checkbox]:focus + label,
input[type=radio]:focus + label {
diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue
index 8396351f8..4342c18b1 100644
--- a/src/ux-components/button-main/button-main.vue
+++ b/src/ux-components/button-main/button-main.vue
@@ -2,15 +2,17 @@
@@ -33,11 +35,16 @@ export default {
};
},
methods: {
- removeLoader(){
+ removeLoader() {
this.isLoaderDisplayed = false;
},
clicked() {
- this.pushEventToGA(this.$route.query[this.queryStrings.FMG_PAGE], this.GaActions.CLICKED, this.buttonText, true);
+ this.pushEventToGA(
+ this.$route.query[this.queryStrings.FMG_PAGE],
+ this.GaActions.CLICKED,
+ this.buttonText,
+ true
+ );
if (!this.isDisabled) {
this.isLoaderDisplayed = true;
this.$emit("click-event");
@@ -98,7 +105,8 @@ export default {
background: $blue-700;
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
}
- &.delay {// fixes flicker while transitioning between states
+ &.delay {
+ // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
@@ -137,7 +145,8 @@ export default {
color: $white;
@include blue-gradient;
}
- &.delay {// fixes flicker while transitioning between states
+ &.delay {
+ // fixes flicker while transitioning between states
transition: background 0s 0s ease-in-out;
}
}
diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.spec.js b/src/ux-components/list-button-horizontal/list-button-horizontal.spec.js
index db439af75..09a63b349 100644
--- a/src/ux-components/list-button-horizontal/list-button-horizontal.spec.js
+++ b/src/ux-components/list-button-horizontal/list-button-horizontal.spec.js
@@ -1,271 +1,139 @@
-import { shallowMount } from "@vue/test-utils";
+import { mount } from "@vue/test-utils";
import listButtonHorizontal from "./list-button-horizontal";
-import { nextTick } from "vue";
-import { GaActions } from "@/constants/analytics";
+import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
describe("list-button-horizontal.vue", () => {
- it("Should return input type checkbox if isMultiSelect is true", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isMultiSelect: true,
- },
+ describe("styling/UI", () => {
+ it("Should return screen reader text", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ screenReaderOnlyText: "Screen Reader Only Text",
+ },
+ },
+ });
+
+ // Assert
+ const paragraph = wrapper.find("span.sr-only");
+
+ expect(paragraph.text()).toEqual("Screen Reader Only Text");
+ });
+
+ it("Should return text alignment class", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ textPosition: "text-center",
+ },
+ },
+ });
+
+ // Assert
+ const paragraph = wrapper.find("span.m-0");
+
+ expect(paragraph.attributes("class")).toContain("text-center");
+ });
+
+ it("Should return aria-required state", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isRequired: true,
+ },
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("input");
+
+ expect(input.attributes()["aria-required"]).toEqual("true");
+ });
+
+ it("is cash or insurance button => has 'radio-fancy' class", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isCashOrInsurance: true,
+ },
+ },
+ });
+
+ // Assert
+ const label = wrapper.find("label");
+
+ expect(label.classes()).toContain("radio-fancy");
+ });
+
+ test("has buttonLabel => displays buttonLabel", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ },
+ },
+ });
+
+ // Assert
+ const content = wrapper.find(".list-button-horizontal-content");
+ expect(content.isVisible()).toBe(true);
+ expect(content.text()).toContain("Surprise!");
+ });
+
+ test("has buttonLabelSubCopy => displays buttonLabelSubCopy", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ buttonLabelSubCopy: "Super duper surprise :)",
+ },
+ },
+ });
+
+ // Assert
+ const content = wrapper.find(".list-button-horizontal-content");
+ expect(content.isVisible()).toBe(true);
+ expect(content.text()).toContain("Super duper surprise :)");
+ });
+
+ test("has screenReaderOnlyText => displays screenReaderOnlyText", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ buttonLabelSubCopy: "Super duper surprise :)",
+ screenReaderOnlyText: "Tests are fun!",
+ },
+ },
+ });
+
+ // Assert
+ const content = wrapper.find(".list-button-horizontal-content");
+ const screenReaderOnlyText = wrapper.find(".sr-only");
+ expect(content.isVisible()).toBe(true);
+ expect(screenReaderOnlyText.exists()).toBe(true);
+ expect(screenReaderOnlyText.text()).toContain("Tests are fun!");
+ });
});
-
- // Assert
- const input = wrapper.find("input");
-
- expect(input.attributes().type).toEqual("checkbox");
- });
-
- it("Should return input type radio if isMultiSelect is false or not specified", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isMultiSelect: false,
- },
- });
-
- // Assert
- const input = wrapper.find("input");
-
- expect(input.attributes().type).toEqual("radio");
- });
-
- it("Should return primary label text (buttonID)", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- buttonID: "List Card Checkbox",
- },
- });
-
- // Assert
- const label = wrapper.find("label");
-
- expect(label.attributes().for).toEqual("List Card Checkbox");
- });
-
- it("Should return screen reader text", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- screenReaderOnlyText: "Screen Reader Only Text",
- },
- });
-
- // Assert
- const paragraph = wrapper.find("span.sr-only");
-
- expect(paragraph.text()).toEqual("Screen Reader Only Text");
- });
-
- it("Should return text alignment class", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- textPosition: "text-center",
- },
- });
-
- // Assert
- const paragraph = wrapper.find("span.m-0");
-
- expect(paragraph.attributes("class")).toContain("text-center");
- });
-
- it("Should return aria-required state", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isRequired: true,
- },
- });
-
- // Assert
- const input = wrapper.find("input");
-
- expect(input.attributes()["aria-required"]).toEqual("true");
- });
-
- it("Should return loader enabled true", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
-
- const label = wrapper.find("label");
-
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.exists()).toBe(true);
- });
-
- it("Should return loader color", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- loaderColor: "blue",
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
-
- const label = wrapper.find("label");
-
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.attributes("class")).toContain("blue");
- });
-
- it("Should return loader position", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- loaderPosition: "right",
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
-
- const label = wrapper.find("label");
-
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.attributes("class")).toContain("right");
- });
-
- it("Should emit button value on click", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- value: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- modelValue: ["List Card Checkbox"],
- },
- });
- wrapper.vm.handleCheckChange();
- // Assert
- expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean, buttonId: undefined, checkValue: false}]);
- });
-
- it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- buttonID: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- modelValue: ["List Card Checkbox"],
- isMultiSelect: false,
- value: "Car-Front",
- selectedValues: ["Car-Front"]
- },
- });
- // Assert
- expect(wrapper.vm.checkValue).toEqual(true);
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- selectingInitiatesLoad: false,
- },
- });
-
- // Assert
- wrapper.vm.handleInputChange();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
- it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- isMultiSelect: true,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButtonHorizontal, {
- propsData: {
- selectingInitiatesLoad: false,
- isMultiSelect: false,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
});
+
+function setupMocks({ mockData }) {
+ const wrapper = mount(listButtonHorizontal, {
+ ...mockData,
+ propsData: {
+ ...mockData.propsData,
+ groupName: "my-group",
+ modelValue: mockData.propsData?.isMultiSelect ? ["5"] : "5",
+ value: mockData.propsData?.isMultiSelect ? ["4"] : "4",
+ },
+ mixins: [inputButtonWrapperMixin],
+ });
+
+ return { wrapper };
+}
diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue
index b9d11d098..c0371f9f7 100644
--- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue
+++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue
@@ -1,345 +1,222 @@
-
-
-
-
+
+
+
+ {{ buttonLabel }}
+
+
+ {{ buttonLabelSubCopy }}
+
+
+ {{ screenReaderOnlyText }}
+
+
+
diff --git a/src/ux-components/list-button/list-button.spec.js b/src/ux-components/list-button/list-button.spec.js
index 53c7f5f65..0b4909420 100644
--- a/src/ux-components/list-button/list-button.spec.js
+++ b/src/ux-components/list-button/list-button.spec.js
@@ -1,263 +1,304 @@
-import { shallowMount } from "@vue/test-utils";
+import { mount } from "@vue/test-utils";
import listButton from "./list-button";
-import { nextTick } from "vue";
import { GaActions } from "@/constants/analytics";
+import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
describe("list-button.vue", () => {
- it("Should return input type checkbox if isMultiSelect is true", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isMultiSelect: true,
- },
+ describe("loader", () => {
+ it("selectingInitiatesLoad is true and answer is changed => show the loader", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ global: {
+ mocks: {
+ $route: { query: { fmgPage: "page-name" } },
+ GaActions: GaActions,
+ pushEventToGA: jest.fn(),
+ },
+ },
+ propsData: {
+ selectingInitiatesLoad: true,
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = "something";
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ const loader = wrapper.findComponent({ name: "loader" });
+ expect(loader.exists()).toBe(true);
+ });
+
+ it("Should return loader color", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({
+ mockData: {
+ global: {
+ mocks: {
+ $route: { query: { fmgPage: "page-name" } },
+ GaActions: GaActions,
+ pushEventToGA: jest.fn(),
+ },
+ },
+ propsData: {
+ loaderColor: "blue",
+ selectingInitiatesLoad: true,
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = "something";
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ const loader = wrapper.findComponent({ name: "loader" });
+ expect(loader.attributes("class")).toContain("blue");
+ });
+
+ it("Should return loader position", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ global: {
+ mocks: {
+ $route: { query: { fmgPage: "page-name" } },
+ GaActions: GaActions,
+ pushEventToGA: jest.fn(),
+ },
+ },
+ propsData: {
+ loaderPosition: "right",
+ selectingInitiatesLoad: true,
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = "something";
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ const loader = wrapper.findComponent({ name: "loader" });
+ expect(loader.attributes("class")).toContain("right");
+ });
});
- // Assert
- const input = wrapper.find("input");
+ describe("baseInputButton checks", () => {
+ it("Should return input type checkbox if isMultiSelect is true", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isMultiSelect: true,
+ },
+ },
+ });
- expect(input.attributes().type).toEqual("checkbox");
- });
+ // Assert
+ const input = wrapper.find("input");
- it("Should return input type radio if isMultiSelect is false or not specified", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isMultiSelect: false,
- },
+ expect(input.attributes().type).toEqual("checkbox");
+ });
+
+ it("Should return input type radio if isMultiSelect is false or not specified", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isMultiSelect: false,
+ },
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("input");
+ expect(input.attributes().type).toEqual("radio");
+ });
+
+ it("(Radio) Should emit button value on selectedValue change", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isRadioHorizontal: true,
+ buttonLabel: "Windshield",
+ value: "List Card Checkbox",
+ groupID: "radio-demo-1",
+ groupName: "radio1",
+ buttonImage: "windshield-damage.svg",
+ isRequired: true,
+ isWide: false,
+ modelValue: "List Card Checkbox",
+ buttonID: "list-card-id",
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = "test";
+
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual("test");
+ });
+
+ it("(Checkbox) Should emit button value on selectedValue change", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isRadioHorizontal: true,
+ buttonLabel: "Windshield",
+ value: "List Card Checkbox",
+ groupID: "radio-demo-1",
+ groupName: "radio 1",
+ buttonImage: "windshield-damage.svg",
+ isRequired: true,
+ isWide: false,
+ modelValue: "List Card Checkbox",
+ buttonID: "list-card-id",
+ isMultiSelect: true,
+ },
+ },
+ });
+
+ // Act
+ wrapper.vm.selectedValue = ["test"];
+
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual(["test"]);
+ });
});
- // Assert
- const input = wrapper.find("input");
+ describe("styling/UI", () => {
+ test("has buttonLabel => displays buttonLabel", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ modelValue: "",
+ groupName: "groupName",
+ value: "myValue"
+ },
+ },
+ });
- expect(input.attributes().type).toEqual("radio");
- });
+ // Assert
+ const content = wrapper.find(".list-button-content");
+ expect(content.isVisible()).toBe(true);
+ expect(content.text()).toContain("Surprise!");
+ });
- it("Should return primary label text (buttonID)", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- buttonID: "List Card Checkbox",
- },
+ test("has buttonLabelSubCopy => displays buttonLabelSubCopy", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ buttonLabelSubCopy: "Super duper surprise :)",
+ modelValue: "",
+ groupName: "groupName",
+ value: "myValue"
+ },
+ },
+ });
+
+ // Assert
+ const content = wrapper.find(".list-button-content");
+ expect(content.isVisible()).toBe(true);
+ expect(content.text()).toContain("Super duper surprise :)");
+ });
+
+ test("has screenReaderOnlyText => displays screenReaderOnlyText", () => {
+ // Arrange/Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ buttonLabel: "Surprise!",
+ buttonLabelSubCopy: "Super duper surprise :)",
+ screenReaderOnlyText: "Tests are fun!",
+ modelValue: "",
+ groupName: "groupName",
+ value: "myValue"
+ },
+ },
+ });
+
+ // Assert
+ const content = wrapper.find(".list-button-content");
+ const screenReaderOnlyText = wrapper.find(".sr-only");
+ expect(content.isVisible()).toBe(true);
+ expect(screenReaderOnlyText.exists()).toBe(true);
+ expect(screenReaderOnlyText.text()).toContain("Tests are fun!");
+ });
+
+ it("Should return screen reader text", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ screenReaderOnlyText: "Screen Reader Only Text",
+ modelValue: "",
+ groupName: "groupName",
+ value: "myValue"
+ },
+ },
+ });
+
+ // Assert
+ const paragraph = wrapper.find("span.sr-only");
+
+ expect(paragraph.text()).toEqual("Screen Reader Only Text");
+ });
+
+ it("Should return text alignment class", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ textPosition: "text-center",
+ modelValue: "",
+ groupName: "groupName",
+ value: "myValue"
+ },
+ },
+ });
+
+ // Assert
+ const paragraph = wrapper.find("span.m-0");
+
+ expect(paragraph.attributes("class")).toContain("text-center");
+ });
+
+ it("Should return aria-required state", async () => {
+ // Act
+ const { wrapper } = setupMocks({
+ mockData: {
+ propsData: {
+ isRequired: true,
+ groupName: "groupName",
+ modelValue: "",
+ value: "myValue",
+ },
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("input");
+
+ expect(input.attributes()["aria-required"]).toEqual("true");
+ });
});
-
- // Assert
- const label = wrapper.find("label");
-
- expect(label.attributes().for).toEqual("List Card Checkbox");
- });
-
- it("Should return screen reader text", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- screenReaderOnlyText: "Screen Reader Only Text",
- },
- });
-
- // Assert
- const paragraph = wrapper.find("span.sr-only");
-
- expect(paragraph.text()).toEqual("Screen Reader Only Text");
- });
-
- it("Should return text alignment class", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- textPosition: "text-center",
- },
- });
-
- // Assert
- const paragraph = wrapper.find("span.m-0");
-
- expect(paragraph.attributes("class")).toContain("text-center");
- });
-
- it("Should return aria-required state", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isRequired: true,
- },
- });
-
- // Assert
- const input = wrapper.find("input");
-
- expect(input.attributes()["aria-required"]).toEqual("true");
- });
-
- it("Should return loader enabled true", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.exists()).toBe(true);
- });
-
- it("Should return loader color", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- loaderColor: "blue",
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.attributes("class")).toContain("blue");
- });
-
- it("Should return loader position", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- loaderPosition: "right",
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
- wrapper.vm.handleCheckChange = jest.fn();
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- const loader = wrapper.find("loader-stub");
-
- expect(loader.attributes("class")).toContain("right");
- });
-
- it("Should emit button value on click", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- value: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- modelValue: ["List Card Checkbox"],
- buttonID: 'list-card-id'
- },
- });
-
- wrapper.vm.handleCheckChange();
-
- // Assert
- expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: false, buttonId: 'list-card-id'}]);
-
- });
-
- it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- buttonID: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- modelValue: ["List Card Checkbox"],
- selectedValues: "Car-Front"
- },
- });
- // Assert
- expect(wrapper.componentVM.checkValue).toEqual(false);
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- selectingInitiatesLoad: false,
- },
- });
-
- // Assert
- wrapper.vm.handleInputChange();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
- it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- isMultiSelect: true,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listButton, {
- propsData: {
- selectingInitiatesLoad: false,
- isMultiSelect: false,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
});
+
+function setupMocks({ mockData }) {
+ const wrapper = mount(listButton, {
+ ...mockData,
+ mixins: [inputButtonWrapperMixin],
+ });
+
+ return { wrapper };
+}
diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue
index e51d5cc77..54ef98b35 100644
--- a/src/ux-components/list-button/list-button.vue
+++ b/src/ux-components/list-button/list-button.vue
@@ -1,242 +1,130 @@
-
-
-
-
+
+
+
+ {{ buttonLabel }}
+
+
+ {{ buttonLabelSubCopy }}
+
+
+ {{ screenReaderOnlyText }}
+
+
+
+
diff --git a/src/ux-components/list-card/list-card.spec.js b/src/ux-components/list-card/list-card.spec.js
index 4e9edf5dc..41d3555e2 100644
--- a/src/ux-components/list-card/list-card.spec.js
+++ b/src/ux-components/list-card/list-card.spec.js
@@ -1,12 +1,12 @@
-import { shallowMount } from "@vue/test-utils";
+import { mount } from "@vue/test-utils";
import listCard from "./list-card";
import { nextTick } from "vue";
import { GaActions } from "@/constants/analytics";
describe("list-card.vue", () => {
- it("Should return input type checkbox if isMultiSelect is true", async () => {
+ it("Should return input type checkbox if isMultiSelect is true", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isMultiSelect: true,
buttonLabel: "Windshield",
@@ -14,6 +14,7 @@ describe("list-card.vue", () => {
groupID: "checkbox-demo-1",
groupName: "Checkbox 1",
buttonImage: "windshield-damage.svg",
+ value: "test value",
},
});
@@ -22,9 +23,9 @@ describe("list-card.vue", () => {
expect(input.attributes().type).toEqual("checkbox");
});
- it("Should return primary label text", async () => {
+ it("Should return primary label text", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -32,6 +33,7 @@ describe("list-card.vue", () => {
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
+ value: "test value",
},
});
@@ -40,9 +42,9 @@ describe("list-card.vue", () => {
expect(paragraph.text()).toEqual("Windshield");
});
- it("Should return secondary (sub) label text", async () => {
+ it("Should return secondary (sub) label text", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -51,6 +53,7 @@ describe("list-card.vue", () => {
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
buttonLabelSubCopy: "Test",
+ value: "test value",
},
});
@@ -59,28 +62,9 @@ describe("list-card.vue", () => {
expect(paragraph.text()).toEqual("Test");
});
- it("Should return value used for various text settings including the label 'for' and input id", async () => {
+ it("Should return input group name used for radio or checkbox", () => {
// Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- buttonID: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- buttonLabelSubCopy: "Test",
- },
- });
-
- // Assert
- const label = wrapper.find("label");
- expect(label.attributes().for).toEqual("List Card Checkbox");
- });
-
- it("Should return input group name used for radio or checkbox", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -89,6 +73,7 @@ describe("list-card.vue", () => {
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
buttonLabelSubCopy: "Test",
+ value: "test value",
},
});
@@ -97,9 +82,9 @@ describe("list-card.vue", () => {
expect(input.attributes().name).toEqual("radio 1");
});
- it("Should return aria-required state", async () => {
+ it("Should return aria-required state", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -108,6 +93,7 @@ describe("list-card.vue", () => {
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
+ value: "test value",
},
});
@@ -116,9 +102,9 @@ describe("list-card.vue", () => {
expect(input.attributes()["aria-required"]).toEqual("true");
});
- it("Should return flex row classes if isWide is true", async () => {
+ it("Should return flex row classes if isWide is true", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -129,17 +115,21 @@ describe("list-card.vue", () => {
isRequired: true,
isWide: true,
buttonLabelSubCopy: "",
+ value: "test value",
},
});
// Assert
- const label = wrapper.find("label");
- expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4"]);
+ const label = wrapper.find(".list-card-content");
+ expect(label.exists()).toBe(true);
+ const labelClasses = wrapper.vm.labelClasses;
+ expect(labelClasses).toContain("flex-row");
+ expect(label.classes()).toContain("flex-row");
});
- it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is true", async () => {
+ it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is provided", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -150,17 +140,23 @@ describe("list-card.vue", () => {
isRequired: true,
isWide: true,
buttonLabelSubCopy: "Button Subcopy",
+ value: "test value",
},
});
// Assert
- const label = wrapper.find("label");
- expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4", "checkboxTop"]);
+ const label = wrapper.find(".list-card-content");
+ expect(label.exists()).toBe(true);
+ const labelClasses = wrapper.vm.labelClasses;
+ expect(labelClasses).toContain("flex-row");
+ expect(label.classes()).toContain("flex-row");
+ expect(labelClasses).toContain("checkboxTop");
+ expect(label.classes()).toContain("checkboxTop");
});
- it("Should return flex column classes if isWide is false", async () => {
+ it("Should return flex column classes if isWide is false", () => {
// Act
- const wrapper = shallowMount(listCard, {
+ const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
@@ -170,165 +166,15 @@ describe("list-card.vue", () => {
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
+ value: "test value",
},
});
// Assert
- const label = wrapper.find("label");
- expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-3"]);
+ const label = wrapper.find(".list-card-content");
+ expect(label.exists()).toBe(true);
+ const labelClasses = wrapper.vm.labelClasses;
+ expect(labelClasses).toContain("flex-column");
+ expect(label.classes()).toContain("flex-column");
});
-
- it("Should emit button value on click", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- value: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- buttonID: 'list-card-id',
- selectedValues: "List Card Checkbox"
- },
- });
- wrapper.vm.handleCheckChange();
- // Assert
- expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: true, buttonId: 'list-card-id'}]);
- });
-
- it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- isRadioHorizontal: true,
- buttonLabel: "Windshield",
- value: "List Card Checkbox",
- groupID: "radio-demo-1",
- groupName: "radio 1",
- buttonImage: "windshield-damage.svg",
- isRequired: true,
- isWide: false,
- selectedValues: "Car-Front"
- },
- });
- // Assert
- expect(wrapper.componentVM.checkValue).toEqual(false);
- });
-
- it("Should set an initial value for validation if selectedValues include the value", async () => {
- // Arrange
- const wrapper = shallowMount(listCard, {
- propsData: {
- value: "Windshield",
- groupName: "radio 1",
- selectedValues: ["Windshield"],
- },
- });
-
- // Assert
- expect(wrapper.vm.fieldOptions.initialValue).toEqual([ 'Windshield' ]);
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- selectingInitiatesLoad: false,
- },
- });
-
- // Assert
- wrapper.vm.handleInputChange();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
- it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- isMultiSelect: true,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
- });
-
- it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- propsData: {
- selectingInitiatesLoad: false,
- isMultiSelect: false,
- },
- });
-
- // Assert
- wrapper.vm.handleKeyupArrow();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- });
-
- it("Should run handleChange if triggerButton is triggered", async () => {
-
- // Act
- const wrapper = shallowMount(listCard, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- selectingInitiatesLoad: false,
- },
- });
-
- // Assert
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- expect(wrapper.vm.handleChange).toBeCalled;
- expect(wrapper.vm.handleCheckChange).not.toBeCalled;
- expect(wrapper.vm.displayLoader).not.toBeCalled;
- });
-
- it("Should run handleCheckChange and displayLoader if triggerButton is triggered and seletingInitiatesLoad is true", async () => {
- // Act
- const wrapper = shallowMount(listCard, {
- global: {
- mocks: {
- '$route': { query: { fmgPage: 'page-name' } },
- GaActions: GaActions,
- pushEventToGA: jest.fn(),
- }
- },
- propsData: {
- selectingInitiatesLoad: true,
- },
- });
-
- // Assert
- wrapper.vm.triggerButton();
-
- await nextTick();
-
- expect(wrapper.vm.handleCheckChange).toBeCalled;
- expect(wrapper.vm.displayLoader).toBeCalled;
- });
-
});
diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue
index c0c2a71c9..7e27a6476 100644
--- a/src/ux-components/list-card/list-card.vue
+++ b/src/ux-components/list-card/list-card.vue
@@ -1,400 +1,252 @@
-
-
-
-
+
diff --git a/src/ux-components/loader/loader.vue b/src/ux-components/loader/loader.vue
index 9b3473eb1..1fbd2c6c1 100644
--- a/src/ux-components/loader/loader.vue
+++ b/src/ux-components/loader/loader.vue
@@ -27,6 +27,7 @@ export default {