Merge branch 'develop' into feature/CSR-78
This commit is contained in:
commit
4e91469bf2
37 changed files with 1872 additions and 706 deletions
|
|
@ -18,7 +18,7 @@ module.exports = {
|
||||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
statements: 87,
|
statements: 89,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:vue/vue3-essential",
|
"plugin:vue/vue3-essential",
|
||||||
"eslint:recommended",
|
"eslint:recommended"
|
||||||
"@vue/prettier"
|
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "babel-eslint"
|
"parser": "babel-eslint"
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,83 @@ import { shallowMount } from "@vue/test-utils";
|
||||||
import buttonQuestion from "@/common-components/button-question/button-question";
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
|
||||||
describe("buttonQuestion.vue", () => {
|
describe("buttonQuestion.vue", () => {
|
||||||
it("Should render the 'questionText' prop value as a span value for the button question and the 'answer' values should render as text values for button components.", async () => {
|
it("Should show overflow classes on fieldset if isOverflowScrollable is true", async () => {
|
||||||
// Act
|
// Act
|
||||||
const wrapper = shallowMount(buttonQuestion);
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
await wrapper.setProps({
|
await wrapper.setProps({
|
||||||
questionText: "Question Text",
|
isOverflowScrollable: true,
|
||||||
answers: ["2023", "2022", "2021"],
|
|
||||||
modelValue: "2020",
|
|
||||||
});
|
});
|
||||||
wrapper.vm.chooseAnswer("2021");
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.find(".text-center").text()).toEqual("Question Text");
|
const fieldSet = wrapper.find('fieldset');
|
||||||
const buttonButtons = wrapper.findAllComponents('[data-test="button"]');
|
expect(fieldSet.classes()).toContain("overflow-scroll");
|
||||||
expect(buttonButtons.length).toBe(3);
|
|
||||||
expect(wrapper.props().modelValue).toBe("2020");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Fieldset classes should contain row if button type is listCard", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
|
await wrapper.setProps({
|
||||||
|
buttonType: "listCard",
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
const Div = wrapper.find('fieldset div');
|
||||||
|
expect(Div.classes()).toContain("row");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Fieldset classes should contain d-flex if button type is listButtonHorizontal", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
|
await wrapper.setProps({
|
||||||
|
buttonType: "listButtonHorizontal",
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
const Div = wrapper.find('fieldset div');
|
||||||
|
expect(Div.classes()).toContain("d-flex");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should trigger event modelValue change on select", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
|
await wrapper.setData({
|
||||||
|
modelValueAnswers: ["Windshield"],
|
||||||
|
chosenAnswer: "Windshield"
|
||||||
|
});
|
||||||
|
wrapper.setValue({ answer: wrapper.vm.chosenAnswer });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{answer: "Windshield"}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should trigger event modelValue change with an array of string values on select if checked is true and multiple options are chosen", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
|
await wrapper.setData({
|
||||||
|
modelValueAnswers: ["Windshield", "BackDoor"]
|
||||||
|
});
|
||||||
|
wrapper.vm.handleCheckedChanged(true);
|
||||||
|
// Assert
|
||||||
|
expect(typeof wrapper.emitted()["update:modelValue"][0]).toEqual('object');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should not trigger event modelValue change on select if checked is false", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion);
|
||||||
|
wrapper.setData({
|
||||||
|
modelValueAnswers: ["Front-door"]
|
||||||
|
})
|
||||||
|
const val = {isChecked : false, buttonId: "Front-door"}
|
||||||
|
wrapper.vm.handleCheckedChanged(val);
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([undefined]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,40 +4,36 @@
|
||||||
<span class="text-center fs-6 fw-bold w-100">{{ questionText }}</span>
|
<span class="text-center fs-6 fw-bold w-100">{{ questionText }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-100 d-flex justify-content-center">
|
<div class="w-100 d-flex justify-content-center">
|
||||||
<fieldset
|
<fieldset class="w-100" :class="getFieldSetClasses" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
|
||||||
class="w-100"
|
<legend class="sr-only">{{groupName}}</legend>
|
||||||
:class="getFieldSetClasses"
|
<div :class="getComponentWrapperClasses">
|
||||||
role="radiogroup"
|
<component
|
||||||
:aria-labelledby="groupName ? groupName + '-radio-group' : ''"
|
:is="buttonType"
|
||||||
>
|
v-for="answer in answers"
|
||||||
<legend class="sr-only">{{ groupName }}</legend>
|
:key="answer.Name ? answer.Name : answer"
|
||||||
<div :class="getComponentWrapperClasses">
|
@isChecked="handleCheckedChanged"
|
||||||
<component
|
:buttonID="answer.Name ? answer.Name : answer"
|
||||||
:is="buttonType"
|
:value="answer.Name ? answer.Name : answer"
|
||||||
v-for="answer in answers"
|
:buttonLabel="answer.Text ? answer.Text : answer"
|
||||||
:key="answer"
|
:buttonLabelSubCopy="answer.SubText"
|
||||||
@mouseup="chooseAnswer(answer.Name ? answer.Name : answer)"
|
:textPosition="textPosition"
|
||||||
@keyup.space="chooseAnswer(answer.Name ? answer.Name : answer)"
|
:isMultiSelect="isMultiSelect"
|
||||||
:buttonID="answer.Name ? answer.Name : answer"
|
:groupName="groupName"
|
||||||
:buttonLabel="answer.Text ? answer.Text : answer"
|
:loaderEnabled="loaderEnabled"
|
||||||
:buttonLabelSubCopy="answer.SubText"
|
:loaderColor="loaderColor"
|
||||||
:textPosition="textPosition"
|
:loaderPosition="loaderPosition"
|
||||||
:isMultiSelect="isMultiSelect"
|
:sizeInRem="sizeInRem"
|
||||||
:groupName="groupName"
|
:isWide="isWide"
|
||||||
:loaderEnabled="loaderEnabled"
|
:isRequired="isRequired"
|
||||||
:loaderColor="loaderColor"
|
:buttonImage="answer.AnswerImageUrl"
|
||||||
:loaderPosition="loaderPosition"
|
:buttonImageId="answer.ImageId"
|
||||||
:sizeInRem="sizeInRem"
|
:altText="answer.Name ? answer.Name : answer"
|
||||||
:isWide="isWide"
|
screenReaderOnlyText="(opens new window)"
|
||||||
:isRequired="isRequired"
|
:colLength="this.answers.length < 3 ? '' : '-4'"
|
||||||
:buttonImage="answer.AnswerImageUrl"
|
v-model="modelValue"
|
||||||
:buttonImageId="answer.ImageId"
|
data-test="button"
|
||||||
:altText="answer.Name ? answer.Name : answer"
|
/>
|
||||||
screenReaderOnlyText="(opens new window)"
|
</div>
|
||||||
:value="modelValue"
|
|
||||||
data-test="button"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -79,7 +75,7 @@ export default {
|
||||||
isRequired: Boolean,
|
isRequired: Boolean,
|
||||||
isOverflowScrollable: Boolean,
|
isOverflowScrollable: Boolean,
|
||||||
isWide: Boolean,
|
isWide: Boolean,
|
||||||
modelValue: String,
|
modelValue: Array,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
getFieldSetClasses() {
|
getFieldSetClasses() {
|
||||||
|
|
@ -96,16 +92,29 @@ export default {
|
||||||
case "listButtonHorizontal":
|
case "listButtonHorizontal":
|
||||||
classes = "d-flex flex-row p-0";
|
classes = "d-flex flex-row p-0";
|
||||||
break;
|
break;
|
||||||
case "listCard":
|
case 'listCard':
|
||||||
classes = "row g-2";
|
classes = 'row justify-content-center g-2'
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return classes;
|
return classes;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
modelValueAnswers: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
if(Array.isArray(this.answers) && this.answers.length === 1) {
|
||||||
|
this.modelValueAnswers.push(typeof(this.answers[0]) === 'object' ? this.answers[0].Name : this.answers[0]);
|
||||||
|
this.$emit("update:modelValue", this.modelValueAnswers);
|
||||||
|
};
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
chooseAnswer(answer) {
|
handleCheckedChanged(val) {
|
||||||
this.$emit("update:modelValue", answer);
|
// Add or remove item to array of data to emit
|
||||||
|
val.isChecked ? this.modelValueAnswers.push(val.buttonId) : this.modelValueAnswers.splice(this.modelValueAnswers.indexOf(val.buttonId), 1);
|
||||||
|
this.$emit("update:modelValue", this.modelValueAnswers.length ? this.modelValueAnswers : undefined);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
60
src/common-components/funnel-footer/funnel-footer.spec.js
Normal file
60
src/common-components/funnel-footer/funnel-footer.spec.js
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
import funnelFooter from "./funnel-footer";
|
||||||
|
|
||||||
|
describe("funnel-footer.vue", () => {
|
||||||
|
|
||||||
|
it("Should return footer-link class", async () => {
|
||||||
|
// Act
|
||||||
|
try {
|
||||||
|
global.document.getElementById = jest.fn().mockImplementation(()=> {
|
||||||
|
return {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = mount(funnelFooter, {
|
||||||
|
propsData: {
|
||||||
|
footer: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const link = wrapper.find("a");
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(link.attributes('class')).toContain("footer-link");
|
||||||
|
expect(global.document.getElementById).toBeCalled();
|
||||||
|
} catch(error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return link text", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = mount(funnelFooter, {
|
||||||
|
propsData: {
|
||||||
|
text: "Terms of use",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const link = wrapper.find("a");
|
||||||
|
|
||||||
|
expect(link.text()).toEqual("Terms of use");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return class btn-primary", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = mount(funnelFooter, {
|
||||||
|
propsData: {
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const input = wrapper.find("button");
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(input.attributes("class")).toContain("btn-primary");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
81
src/common-components/funnel-footer/funnel-footer.vue
Normal file
81
src/common-components/funnel-footer/funnel-footer.vue
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<div class="container-fluid g-2 footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 d-flex justify-content-center pb-2 fs-7">
|
||||||
|
© <span id="years"></span> Safelite Group
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" :style="`padding-bottom: ${paddingHeight}px`">
|
||||||
|
<div class="col d-flex justify-content-center justify-content-around text-center">
|
||||||
|
<textLink
|
||||||
|
footer=true
|
||||||
|
text="Terms of use"
|
||||||
|
href="https://www.safelite.com/terms-of-use"
|
||||||
|
/>
|
||||||
|
<textLink
|
||||||
|
footer=true
|
||||||
|
text="Privacy policy"
|
||||||
|
href="https://www.safelite.com/safelite-group-privacy-policy"
|
||||||
|
/>
|
||||||
|
<textLink
|
||||||
|
footer=true
|
||||||
|
text="Do not sell my information"
|
||||||
|
href="https://privacyportal-cdn.onetrust.com/dsarwebform/d3b95a93-e22e-4d4d-a806-482052406557/9e371601-eae3-4338-9430-b90b9036022b.html"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container-fluid fixed-bottom g-4 bg-light py-4" id="infoBox">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<buttonMain
|
||||||
|
isPrimary
|
||||||
|
buttonText="Review Appointment Details"
|
||||||
|
loaderColor="white"
|
||||||
|
sizeInRem="1"
|
||||||
|
isFloat
|
||||||
|
/>
|
||||||
|
<textLink
|
||||||
|
navigation=true
|
||||||
|
text="back"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import textLink from "@/ux-components/text-link/text-link";
|
||||||
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "funnelFooter",
|
||||||
|
components: {
|
||||||
|
textLink,
|
||||||
|
buttonMain
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
paddingHeight: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.paddingHeight = document.getElementById("infoBox").offsetHeight;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
window.addEventListener('resize', this.onResize);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
window.removeEventListener('resize', this.onResize);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onResize() {
|
||||||
|
this.paddingHeight = document.getElementById("infoBox").offsetHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setTimeout(function(){ // Give it a moment to set the date
|
||||||
|
document.getElementById('years').innerHTML += new Date().getFullYear();
|
||||||
|
}, 100);
|
||||||
|
</script>
|
||||||
|
|
@ -11,9 +11,12 @@ const storeActions = {
|
||||||
GET_EVOX_IMAGE: "getEvoxImage",
|
GET_EVOX_IMAGE: "getEvoxImage",
|
||||||
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
|
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
|
||||||
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin",
|
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin",
|
||||||
// EVENT BUS
|
|
||||||
ADD_EVENT_TO_BUS: "addEventToBus",
|
// DEPENDENCY MUTATIONS
|
||||||
REMOVE_EVENT_FROM_BUS: "removeEventFromBus",
|
RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
|
||||||
|
RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
|
||||||
|
RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
|
||||||
|
RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { storeActions };
|
export { storeActions };
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,23 @@
|
||||||
const storeMutations = {
|
const storeMutations = {
|
||||||
|
|
||||||
|
// VEHICLE MUTATIONS
|
||||||
UPDATE_YEAR: "updateYear",
|
UPDATE_YEAR: "updateYear",
|
||||||
UPDATE_MAKE: "updateMake",
|
UPDATE_MAKE: "updateMake",
|
||||||
UPDATE_MODEL: "updateModel",
|
UPDATE_MODEL: "updateModel",
|
||||||
UPDATE_STYLE: "updateStyle",
|
UPDATE_STYLE: "updateStyle",
|
||||||
UPDATE_VEHICLE: "updateVehicle",
|
UPDATE_CAR_ID: "updateCarId",
|
||||||
|
UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory",
|
||||||
|
|
||||||
|
// EVENT BUS MUTATIONS
|
||||||
|
ADD_EVENT_TO_BUS: "addEventToBus",
|
||||||
|
REMOVE_EVENT_FROM_BUS: "removeEventFromBus",
|
||||||
|
|
||||||
|
// DEPENDENCY MUTATIONS
|
||||||
|
RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
|
||||||
|
RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
|
||||||
|
RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
|
||||||
|
RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { storeMutations };
|
export { storeMutations };
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
import { storeMutations } from "@/constants/store-mutations.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// Adds event to the bus given its category, subcategory, and eventValue;
|
// Adds event to the bus given its category, subcategory, and eventValue;
|
||||||
addEventToBus(category, subCategory, eventValue) {
|
addEventToBus(category, subCategory, eventValue) {
|
||||||
store.commit(storeActions.ADD_EVENT_TO_BUS, {
|
store.commit(storeMutations.ADD_EVENT_TO_BUS, {
|
||||||
category: category,
|
category: category,
|
||||||
subCategory: subCategory,
|
subCategory: subCategory,
|
||||||
eventValue: eventValue,
|
eventValue: eventValue,
|
||||||
|
|
@ -15,7 +15,7 @@ export default {
|
||||||
readAndPopEventFromBus(category, subCategory) {
|
readAndPopEventFromBus(category, subCategory) {
|
||||||
const event = store.getters.eventBusItem(category, subCategory);
|
const event = store.getters.eventBusItem(category, subCategory);
|
||||||
|
|
||||||
store.commit(storeActions.REMOVE_EVENT_FROM_BUS, {
|
store.commit(storeMutations.REMOVE_EVENT_FROM_BUS, {
|
||||||
category: category,
|
category: category,
|
||||||
subCategory: subCategory,
|
subCategory: subCategory,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,31 @@
|
||||||
<buttonBack backButtonAccessibleText="Back button label" />
|
<buttonBack backButtonAccessibleText="Back button label" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<h4 class="m-0 p-2 bg-light rounded">Links</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col my-3">
|
||||||
|
<textLink
|
||||||
|
navigation=true
|
||||||
|
text="Navigation Link"
|
||||||
|
/><br><br>
|
||||||
|
<textLink
|
||||||
|
text="Default Link"
|
||||||
|
/><br><br>
|
||||||
|
<textLink
|
||||||
|
textSmall=true
|
||||||
|
text="Small Link"
|
||||||
|
/><br><br>
|
||||||
|
<textLink
|
||||||
|
footer=true
|
||||||
|
text="Footer Link"
|
||||||
|
href="https://google.com"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row my-4">
|
<div class="row my-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h4 class="m-0 p-2 bg-light rounded">List Card</h4>
|
<h4 class="m-0 p-2 bg-light rounded">List Card</h4>
|
||||||
|
|
@ -60,7 +85,7 @@
|
||||||
/>
|
/>
|
||||||
<listCard
|
<listCard
|
||||||
isMultiSelect
|
isMultiSelect
|
||||||
buttonImage="side-window-damage-right-all.svg"
|
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
|
||||||
buttonLabel="Windshield"
|
buttonLabel="Windshield"
|
||||||
altText=""
|
altText=""
|
||||||
buttonID="List Card Checkbox 2"
|
buttonID="List Card Checkbox 2"
|
||||||
|
|
@ -177,7 +202,7 @@
|
||||||
<listCard
|
<listCard
|
||||||
isMultiSelect
|
isMultiSelect
|
||||||
isWide
|
isWide
|
||||||
buttonImage="side-window-damage-right-all.svg"
|
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
|
||||||
buttonLabel="Side Window"
|
buttonLabel="Side Window"
|
||||||
altText=""
|
altText=""
|
||||||
buttonID="List Card Horizontal Checkbox b"
|
buttonID="List Card Horizontal Checkbox b"
|
||||||
|
|
@ -807,95 +832,109 @@
|
||||||
<h4 class="m-0 p-2 bg-light rounded">Button Question</h4>
|
<h4 class="m-0 p-2 bg-light rounded">Button Question</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<buttonQuestion
|
<div class="row">
|
||||||
:answers="checkboxAnswers"
|
<div class="col">
|
||||||
:isMultiSelect="true"
|
<buttonQuestion
|
||||||
ariaLabelBy="checkbox"
|
:answers="checkboxAnswers"
|
||||||
groupName="checkbox-list"
|
:isMultiSelect="true"
|
||||||
questionText="List Button as checkbox"
|
ariaLabelBy="checkbox"
|
||||||
/>
|
groupName="checkbox-list"
|
||||||
<buttonQuestion
|
questionText="List Button as checkbox"
|
||||||
:answers="radioAnswers"
|
/>
|
||||||
ariaLabelBy="radio"
|
<buttonQuestion
|
||||||
groupName="radio-list"
|
:answers="radioAnswers"
|
||||||
questionText="List Button as radio"
|
ariaLabelBy="radio"
|
||||||
/>
|
groupName="radio-list"
|
||||||
<buttonQuestion
|
questionText="List Button as radio"
|
||||||
:answers="horizontalCheckboxAnswers"
|
/>
|
||||||
buttonType="listButtonHorizontal"
|
<buttonQuestion
|
||||||
:isMultiSelect="true"
|
:answers="horizontalCheckboxAnswers"
|
||||||
isColumn
|
buttonType="listButtonHorizontal"
|
||||||
ariaLabelBy="checkbox"
|
:isMultiSelect="true"
|
||||||
groupName="checkbox-list-horizontal"
|
isColumn
|
||||||
questionText="List Button Horizontal as checkbox"
|
ariaLabelBy="checkbox"
|
||||||
/>
|
groupName="checkbox-list-horizontal"
|
||||||
<buttonQuestion
|
questionText="List Button Horizontal as checkbox"
|
||||||
:answers="horizontalRadioAnswers"
|
/>
|
||||||
buttonType="listButtonHorizontal"
|
<buttonQuestion
|
||||||
isColumn
|
:answers="horizontalRadioAnswers"
|
||||||
ariaLabelBy="radio"
|
buttonType="listButtonHorizontal"
|
||||||
groupName="radio-list-horizontal"
|
isColumn
|
||||||
questionText="List Button Horizontal as radio"
|
ariaLabelBy="radio"
|
||||||
sizeInRem="1"
|
groupName="radio-list-horizontal"
|
||||||
/>
|
questionText="List Button Horizontal as radio"
|
||||||
<buttonQuestion
|
sizeInRem="1"
|
||||||
:answers="listCardCheckBox"
|
/>
|
||||||
buttonType="listCard"
|
<buttonQuestion
|
||||||
isMultiSelect
|
:answers="listCardCheckBox"
|
||||||
ariaLabelBy="check_card"
|
buttonType="listCard"
|
||||||
groupName="check-list-card"
|
isMultiSelect
|
||||||
questionText="List Card as checkbox"
|
ariaLabelBy="check_card"
|
||||||
/>
|
groupName="check-list-card"
|
||||||
<buttonQuestion
|
questionText="List Card as checkbox"
|
||||||
:answers="listCardRadio"
|
/>
|
||||||
buttonType="listCard"
|
<buttonQuestion
|
||||||
ariaLabelBy="radio_card"
|
:answers="listCardRadio"
|
||||||
groupName="radio-card"
|
buttonType="listCard"
|
||||||
questionText="List Card as radio"
|
ariaLabelBy="radio_card"
|
||||||
/>
|
groupName="radio-card"
|
||||||
<buttonQuestion
|
questionText="List Card as radio"
|
||||||
isMultiSelect
|
/>
|
||||||
isWide
|
<buttonQuestion
|
||||||
:answers="listCardCheckBoxHorizontal"
|
isMultiSelect
|
||||||
buttonType="listCard"
|
isWide
|
||||||
ariaLabelBy="horizontal_check_card"
|
:answers="listCardCheckBoxHorizontal"
|
||||||
groupName="horizontal_check-card"
|
buttonType="listCard"
|
||||||
questionText="List Card Horizontal as checkbox"
|
ariaLabelBy="horizontal_check_card"
|
||||||
/>
|
groupName="horizontal_check-card"
|
||||||
<buttonQuestion
|
questionText="List Card Horizontal as checkbox"
|
||||||
isMultiSelect
|
/>
|
||||||
isWide
|
<buttonQuestion
|
||||||
:answers="listCardCheckBoxHorizontalSubText"
|
isMultiSelect
|
||||||
buttonType="listCard"
|
isWide
|
||||||
ariaLabelBy="horizontal_check_card-st"
|
:answers="listCardCheckBoxHorizontalSubText"
|
||||||
groupName="horizontal_check-card-st"
|
buttonType="listCard"
|
||||||
questionText="With Subtext"
|
ariaLabelBy="horizontal_check_card-st"
|
||||||
/>
|
groupName="horizontal_check-card-st"
|
||||||
<buttonQuestion
|
questionText="With Subtext"
|
||||||
isWide
|
/>
|
||||||
:answers="listRadioHorizontal"
|
<buttonQuestion
|
||||||
buttonType="listCard"
|
isWide
|
||||||
ariaLabelBy="horizontal_radio_card"
|
:answers="listRadioHorizontal"
|
||||||
groupName="horizontal_cradio-card"
|
buttonType="listCard"
|
||||||
questionText="List Card Horizontal as radio"
|
ariaLabelBy="horizontal_radio_card"
|
||||||
/>
|
groupName="horizontal_cradio-card"
|
||||||
<buttonQuestion
|
questionText="List Card Horizontal as radio"
|
||||||
isWide
|
/>
|
||||||
:answers="listRadioHorizontalSubText"
|
<buttonQuestion
|
||||||
buttonType="listCard"
|
isWide
|
||||||
ariaLabelBy="horizontal_radio_card-st"
|
:answers="listRadioHorizontalSubText"
|
||||||
groupName="horizontal_cradio-card-st"
|
buttonType="listCard"
|
||||||
questionText="With Subtext"
|
ariaLabelBy="horizontal_radio_card-st"
|
||||||
/>
|
groupName="horizontal_cradio-card-st"
|
||||||
<buttonQuestion
|
questionText="With Subtext"
|
||||||
isMultiSelect
|
/>
|
||||||
isRow
|
<buttonQuestion
|
||||||
:answers="listCardGroup"
|
isMultiSelect
|
||||||
buttonType="listCard"
|
isRow
|
||||||
ariaLabelBy="horizontal_radio_card-group"
|
:answers="listCardGroup"
|
||||||
groupName="horizontal_cradio-card-group"
|
buttonType="listCard"
|
||||||
questionText="In column layout"
|
ariaLabelBy="horizontal_radio_card-group"
|
||||||
/>
|
groupName="horizontal_cradio-card-group"
|
||||||
|
questionText="In column layout"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row my-4">
|
||||||
|
<div class="col">
|
||||||
|
<h4 class="m-0 p-2 bg-light rounded">Funnel Footer</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row my-2">
|
||||||
|
<div class="col">
|
||||||
|
<funnelFooter/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -911,6 +950,7 @@ import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-bu
|
||||||
import checkbox from "@/ux-components/checkbox/checkbox";
|
import checkbox from "@/ux-components/checkbox/checkbox";
|
||||||
import buttonQuestion from "@/common-components/button-question/button-question";
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
import textLink from "@/ux-components/text-link/text-link";
|
import textLink from "@/ux-components/text-link/text-link";
|
||||||
|
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -925,6 +965,7 @@ export default {
|
||||||
funnelHeader,
|
funnelHeader,
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
textLink,
|
textLink,
|
||||||
|
funnelFooter
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -947,7 +988,7 @@ export default {
|
||||||
Text: "List Card CB",
|
Text: "List Card CB",
|
||||||
SubText: "checkbox",
|
SubText: "checkbox",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listCardRadio: [
|
listCardRadio: [
|
||||||
|
|
@ -956,7 +997,7 @@ export default {
|
||||||
Text: "List Card R",
|
Text: "List Card R",
|
||||||
SubText: "Radio",
|
SubText: "Radio",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listCardCheckBoxHorizontalSubText: [
|
listCardCheckBoxHorizontalSubText: [
|
||||||
|
|
@ -965,7 +1006,7 @@ export default {
|
||||||
Text: "List Card CBHst",
|
Text: "List Card CBHst",
|
||||||
SubText: "With Subtext",
|
SubText: "With Subtext",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listCardCheckBoxHorizontal: [
|
listCardCheckBoxHorizontal: [
|
||||||
|
|
@ -973,7 +1014,7 @@ export default {
|
||||||
Name: "List-Card-CBH",
|
Name: "List-Card-CBH",
|
||||||
Text: "List Card CBH",
|
Text: "List Card CBH",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listRadioHorizontalSubText: [
|
listRadioHorizontalSubText: [
|
||||||
|
|
@ -982,7 +1023,7 @@ export default {
|
||||||
Text: "List Card RHst",
|
Text: "List Card RHst",
|
||||||
SubText: "With Subtext",
|
SubText: "With Subtext",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listRadioHorizontal: [
|
listRadioHorizontal: [
|
||||||
|
|
@ -990,7 +1031,7 @@ export default {
|
||||||
Name: "List-Card-RH",
|
Name: "List-Card-RH",
|
||||||
Text: "List Card RH",
|
Text: "List Card RH",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listCardGroup: [
|
listCardGroup: [
|
||||||
|
|
@ -999,20 +1040,20 @@ export default {
|
||||||
Text: "Side Window",
|
Text: "Side Window",
|
||||||
SubText: "With Subtext",
|
SubText: "With Subtext",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Side-Window-2",
|
Name: "Side-Window-2",
|
||||||
Text: "Side Window",
|
Text: "Side Window",
|
||||||
SubText: "With Subtext that is more than one line",
|
SubText: "With Subtext that is more than one line",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Side-Window-3",
|
Name: "Side-Window-3",
|
||||||
Text: "Side Window",
|
Text: "Side Window",
|
||||||
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
|
||||||
AnswerImageUrl: "side-window-damage-right-all.svg",
|
AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import store from "@/store";
|
||||||
|
jest.mock("@/store", () => { return {}; }, {virtual: true});
|
||||||
|
|
||||||
|
describe("damage-location-question.vue", () => {
|
||||||
|
test("Selected location option is emitted upon selection.", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
|
||||||
|
const locationToSelect = ["Backseat"];
|
||||||
|
|
||||||
|
//Act
|
||||||
|
wrapper.setValue({ modelValue: locationToSelect });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("damage-location-question.vue", () => {
|
||||||
|
test("Answers to display filtered by data from api.", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, cmsContent, damageOptions } = setupMocks({ dataFromStoreApi: {
|
||||||
|
driverSideOptions: {
|
||||||
|
availableReplacementOptions: ['Quarter', 'Front']
|
||||||
|
},
|
||||||
|
windshieldOptions: {
|
||||||
|
availableReplacementOptions: ['Single']
|
||||||
|
},
|
||||||
|
backGlassOptions: {
|
||||||
|
availableReplacementOptions: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-SideDoor' } ])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
modelValueProp = ["Windshield", "SideDoor"],
|
||||||
|
isMultiSelect = false,
|
||||||
|
groupName = "damageQuestion",
|
||||||
|
cmsQuestionText = "CMS text goes here",
|
||||||
|
cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-SideDoor"}, {Name: "car-RearWindow"}],
|
||||||
|
dataFromStoreApi = [],
|
||||||
|
}) {
|
||||||
|
|
||||||
|
//Mock store
|
||||||
|
store.dispatch = jest.fn(() => dataFromStoreApi);
|
||||||
|
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
store: {
|
||||||
|
dispatch: store.dispatch,
|
||||||
|
getters: store.getters,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Mock props
|
||||||
|
mountOptions.propsData = {
|
||||||
|
modelValue: modelValueProp,
|
||||||
|
isMultiSelect: isMultiSelect,
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallowMount(damageLocationQuestion, mountOptions);
|
||||||
|
|
||||||
|
//Mock CMS content
|
||||||
|
const cmsContent = {
|
||||||
|
groupName: groupName,
|
||||||
|
QuestionText: cmsQuestionText,
|
||||||
|
Answers: cmsAnswers,
|
||||||
|
};
|
||||||
|
const damageOptions = dataFromStoreApi;
|
||||||
|
return { wrapper, cmsContent, damageOptions };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<template>
|
||||||
|
<div class="replace-options-question">
|
||||||
|
<buttonQuestion
|
||||||
|
v-if="answersToDisplay.length > 1"
|
||||||
|
:questionText="questionText"
|
||||||
|
:isMultiSelect="isMultiSelect"
|
||||||
|
:answers="answersToDisplay"
|
||||||
|
:groupName="groupName"
|
||||||
|
buttonType="listCard"
|
||||||
|
v-model="modelValue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
name: "damageLocationQuestion",
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
questionText: String,
|
||||||
|
answersFromCms: Array,
|
||||||
|
damageOptions: Object,
|
||||||
|
groupName: String,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isMultiSelect: Boolean,
|
||||||
|
modelValue: Array,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initializeComponent(cmsContent, damageOptions, groupName){
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.questionText = cmsContent.QuestionText;
|
||||||
|
this.answersFromCms = cmsContent.Answers;
|
||||||
|
this.damageOptions = damageOptions;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
damageOptionsMap(){
|
||||||
|
return {
|
||||||
|
Windshield: true,
|
||||||
|
SideDoor: this.damageOptions.driverSideOptions.availableReplacementOptions || this.damageOptions.passengerSideOptions.availableReplacementOption ? true : false,
|
||||||
|
RearWindow: this.damageOptions.backGlassOptions.availableReplacementOption ? true : false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
answersToDisplay(){
|
||||||
|
return Array.isArray(this.answersFromCms)
|
||||||
|
? this.answersFromCms.filter(ans =>
|
||||||
|
{
|
||||||
|
const name = ans.Name.split('-');
|
||||||
|
return name[0].toUpperCase() === store.getters.vehicle.category && this.damageOptionsMap[name[1]];
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
modelValue(val) {
|
||||||
|
this.$emit("update:modelValue", val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import store from "@/store";
|
||||||
|
jest.mock("@/store", () => { return {}; }, {virtual: true});
|
||||||
|
|
||||||
|
describe("replace-options-question.vue", () => {
|
||||||
|
test("Selected damage option is emitted upon selection.", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
|
||||||
|
const damageToSelect = ["Backseat"];
|
||||||
|
|
||||||
|
//Act
|
||||||
|
wrapper.setValue({ modelValue: damageToSelect });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("replace-options-question.vue", () => {
|
||||||
|
test("Answers to display filtered by data from api.", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, cmsContent, replaceOptions } = setupMocks({ dataFromStoreApi: ["Windshield", "FrontDoor"]});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-FrontDoor' } ])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
modelValueProp = ["Windshield"],
|
||||||
|
isAvailale = true,
|
||||||
|
isMultiSelect = false,
|
||||||
|
filterByVehicleCategory = false,
|
||||||
|
groupName = "damageQuestion",
|
||||||
|
cmsQuestionText = "CMS text goes here",
|
||||||
|
cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-BackDoor"}, {Name: "car-FrontDoor"}],
|
||||||
|
dataFromStoreApi = [],
|
||||||
|
}) {
|
||||||
|
|
||||||
|
//Mock store
|
||||||
|
store.dispatch = jest.fn(() => dataFromStoreApi);
|
||||||
|
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
store: {
|
||||||
|
dispatch: store.dispatch,
|
||||||
|
getters: store.getters,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Mock props
|
||||||
|
mountOptions.propsData = {
|
||||||
|
modelValue: modelValueProp,
|
||||||
|
isAvailable: isAvailale,
|
||||||
|
isMultiSelect: isMultiSelect,
|
||||||
|
filterByVehicleCategory: filterByVehicleCategory
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallowMount(replaceOptionsQuestion, mountOptions);
|
||||||
|
|
||||||
|
//Mock CMS content
|
||||||
|
const cmsContent = {
|
||||||
|
groupName: groupName,
|
||||||
|
QuestionText: cmsQuestionText,
|
||||||
|
Answers: cmsAnswers,
|
||||||
|
};
|
||||||
|
const replaceOptions = dataFromStoreApi;
|
||||||
|
return { wrapper, cmsContent, replaceOptions };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<template>
|
||||||
|
<transition name="fade">
|
||||||
|
<div class="replace-options-question">
|
||||||
|
<buttonQuestion
|
||||||
|
v-if="isAvailable && answersToDisplay.length > 1"
|
||||||
|
:questionText="questionText"
|
||||||
|
:isMultiSelect="isMultiSelect"
|
||||||
|
:answers="answersToDisplay"
|
||||||
|
:groupName="groupName"
|
||||||
|
buttonType="listCard"
|
||||||
|
v-model="modelValue"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
name: "replaceOptionsQuestion",
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
questionText: String,
|
||||||
|
answersFromCms: Array,
|
||||||
|
replaceOptions: Array,
|
||||||
|
groupName: String,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isMultiSelect: Boolean,
|
||||||
|
isAvailable: Boolean,
|
||||||
|
filterByVehicleCategory: Boolean,
|
||||||
|
modelValue: Array,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initializeComponent(cmsContent, replaceOptions, groupName){
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.questionText = cmsContent.QuestionText;
|
||||||
|
this.answersFromCms = cmsContent.Answers;
|
||||||
|
this.replaceOptions = replaceOptions;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
answersToDisplay(){
|
||||||
|
return Array.isArray(this.answersFromCms)
|
||||||
|
? this.answersFromCms.filter(ans =>
|
||||||
|
{
|
||||||
|
const name = ans.Name.split('-');
|
||||||
|
return this.filterByVehicleCategory ? name[0].toUpperCase() === store.getters.vehicle.category : name[0].toUpperCase() === store.getters.vehicle.category && this.replaceOptions.includes(name[1])
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
modelValue(val) {
|
||||||
|
this.$emit("update:modelValue", val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -3,6 +3,8 @@ import vehicleDamage from "@/layouts/vehicle-damage/vehicle-damage.vue";
|
||||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
|
||||||
|
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
|
@ -11,6 +13,8 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
|
@ -24,6 +28,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
|
||||||
// Mock Store
|
// Mock Store
|
||||||
jest.mock("@/store", () => ({
|
jest.mock("@/store", () => ({
|
||||||
|
commit: jest.fn(),
|
||||||
|
dispatch: jest.fn(),
|
||||||
getters: {
|
getters: {
|
||||||
vehicle: {
|
vehicle: {
|
||||||
carId: "C00000000",
|
carId: "C00000000",
|
||||||
|
|
@ -136,6 +142,28 @@ describe("vehicle-damage.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("vehicle-damage.vue", () => {
|
||||||
|
test("Call invalidation, ResetPartsAndDeps should be called", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleDamage.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "vehicle-damage" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.resetDependentState();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS)
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
pageHeaderWidgetHeaderText = {},
|
pageHeaderWidgetHeaderText = {},
|
||||||
mountOptionsMockData = {},
|
mountOptionsMockData = {},
|
||||||
|
|
@ -144,7 +172,9 @@ function setupMocks({
|
||||||
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
|
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
|
||||||
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation(() => {
|
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
data: ["Front Window", "Back Window", "Side Window"],
|
driverSideOptions: {
|
||||||
|
availableReplacementOptions: ["Front", "Back", "Side"],
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const apiResponses = {
|
const apiResponses = {
|
||||||
|
|
@ -159,7 +189,11 @@ function setupMocks({
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
damageOptions: ["Front Window", "Back Window", "Side Window"],
|
damageOptions: {
|
||||||
|
driverSideOptions: {
|
||||||
|
availableReplacementOptions: ["Front", "Back", "Side"],
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
const apiPromise = Promise.resolve(apiResponses);
|
||||||
|
|
@ -180,6 +214,15 @@ function setupMocks({
|
||||||
initializeComponent: jest.fn(),
|
initializeComponent: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const driverSideOptions = replaceOptionsQuestion
|
||||||
|
driverSideOptions.methods = {
|
||||||
|
initializeComponent: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
damageLocationQuestion.methods = {
|
||||||
|
initializeComponent: jest.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
const wrapper = shallowMount(vehicleDamage, mountOptions);
|
const wrapper = shallowMount(vehicleDamage, mountOptions);
|
||||||
|
|
||||||
|
|
@ -197,5 +240,17 @@ function setupMocks({
|
||||||
funnelSubHeaderWrapper.vm.initializeComponent =
|
funnelSubHeaderWrapper.vm.initializeComponent =
|
||||||
funnelSubHeader.methods.initializeComponent;
|
funnelSubHeader.methods.initializeComponent;
|
||||||
|
|
||||||
|
const driverSideOptionsWrapper = wrapper.findComponent({
|
||||||
|
name: "replaceOptionsQuestion",
|
||||||
|
});
|
||||||
|
driverSideOptionsWrapper.vm.initializeComponent =
|
||||||
|
replaceOptionsQuestion.methods.initializeComponent;
|
||||||
|
|
||||||
|
const damageLocationQuestionWrapper = wrapper.findComponent({
|
||||||
|
name: "damageLocationQuestion",
|
||||||
|
});
|
||||||
|
damageLocationQuestionWrapper.vm.initializeComponent =
|
||||||
|
damageLocationQuestion.methods.initializeComponent;
|
||||||
|
|
||||||
return { wrapper, apiPromise };
|
return { wrapper, apiPromise };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container-fluid shadow rounded-3 p-0 position-relative">
|
<div class="container-fluid shadow rounded-3 p-2 position-relative">
|
||||||
<funnelHeader ref="funnelHeader" />
|
<funnelHeader ref="funnelHeader" />
|
||||||
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
|
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
|
||||||
<funnelSubHeader ref="funnelSubHeader" :hasSubText=true />
|
<funnelSubHeader ref="funnelSubHeader" :hasSubText=true />
|
||||||
|
<damageLocationQuestion ref="damageLocation" isMultiSelect v-model="damageLocationQuestionData" />
|
||||||
|
<replaceOptionsQuestion ref="driverSideOptions" isAvailable isMultiSelect v-model="driverSideOptionsData" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -11,12 +13,15 @@
|
||||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import replaceOptionsQuestion from"@/layouts/vehicle-damage/replace-options-question/replace-options-question";
|
||||||
|
import damageLocationQuestion from"@/layouts/vehicle-damage/damage-location-question/damage-location-question";
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-damage",
|
name: "vehicle-damage",
|
||||||
|
|
@ -54,18 +59,38 @@ export default {
|
||||||
vm.$refs.funnelSubHeader.initializeComponent(
|
vm.$refs.funnelSubHeader.initializeComponent(
|
||||||
resultMap.cmsContent.FunnelSubHeaderWidget
|
resultMap.cmsContent.FunnelSubHeaderWidget
|
||||||
);
|
);
|
||||||
// use resultMap.damageOptions for damage options
|
vm.$refs.driverSideOptions.initializeComponent(
|
||||||
|
resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions, 'DriverSideReplaceOptionsQuestion'
|
||||||
|
);
|
||||||
|
vm.$refs.damageLocation.initializeComponent(
|
||||||
|
resultMap.cmsContent.DamageLocationQuestion, resultMap.damageOptions, 'DamageLocationQuestion'
|
||||||
|
);
|
||||||
|
|
||||||
|
// for damageOptions and cms content data
|
||||||
|
//console.log(resultMap)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
damageLocationQuestionData: [],
|
||||||
|
driverSideOptionsData: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return store.getters.vehicle.carId !== null;
|
return store.getters.vehicle.carId !== null;
|
||||||
},
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
funnelHeader,
|
funnelHeader,
|
||||||
vehicleBanner,
|
vehicleBanner,
|
||||||
funnelSubHeader,
|
funnelSubHeader,
|
||||||
|
replaceOptionsQuestion,
|
||||||
|
damageLocationQuestion,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
:loaderEnabled="true"
|
:loaderEnabled="true"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
|
isRequired=true
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: Array,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,23 @@
|
||||||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
// Supporting Files
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
|
||||||
|
// Components
|
||||||
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
|
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
|
||||||
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
||||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
import store from "@/store";
|
||||||
import { nextTick } from "vue";
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
|
|
||||||
jest.mock("@/store", () => ({
|
jest.mock("@/store", () => ({
|
||||||
|
commit: jest.fn(),
|
||||||
|
dispatch: jest.fn(),
|
||||||
getters: {
|
getters: {
|
||||||
vehicle: {
|
vehicle: {
|
||||||
year: 2019,
|
year: 2019,
|
||||||
|
|
@ -27,9 +35,6 @@ jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
settleAllPromises: jest.fn(),
|
settleAllPromises: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.resetModules();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("vehicle-make.vue", () => {
|
describe("vehicle-make.vue", () => {
|
||||||
test("Make question component is initized with api data", async (done) => {
|
test("Make question component is initized with api data", async (done) => {
|
||||||
|
|
@ -190,13 +195,40 @@ describe("vehicle-make.vue", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("vehicle-make.vue", () => {
|
||||||
|
test("Year set, call invalidation, model, style, carId, category should be null", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleMake.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "vehicle-make" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.resetDependentState();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
|
||||||
|
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
vehicleMakeQuestionCmsContent = {},
|
vehicleMakeQuestionCmsContent = {},
|
||||||
makeQuestionInitialData = {},
|
makeQuestionInitialData = {},
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,15 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-make",
|
name: "vehicle-make",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedMake: null,
|
selectedMake: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
@ -75,17 +78,31 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
// route to move backwards
|
// route to move backwards
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return store.getters.vehicle.year !== null;
|
return store.getters.vehicle.year !== null;
|
||||||
},
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
// Set
|
||||||
|
store.commit(storeMutations.UPDATE_MODEL, null);
|
||||||
|
store.commit(storeMutations.UPDATE_STYLE, null);
|
||||||
|
store.commit(storeMutations.UPDATE_CAR_ID, null);
|
||||||
|
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
||||||
|
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
|
||||||
|
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
selectedMake(make) {
|
selectedMake(make) {
|
||||||
this.$store.commit(this.storeMutations.UPDATE_MAKE, make);
|
this.$store.commit(this.storeMutations.UPDATE_MAKE, make);
|
||||||
this.$router.navigate(
|
this.$router.navigateAfterSave(
|
||||||
this.navigationScenarios.SELECTED_MAKE,
|
this.navigationScenarios.SELECTED_MAKE,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
:loaderEnabled="true"
|
:loaderEnabled="true"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
|
isRequired=true
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: Array,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
|
@ -24,6 +27,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
|
||||||
// Mock Store
|
// Mock Store
|
||||||
jest.mock("@/store", () => ({
|
jest.mock("@/store", () => ({
|
||||||
|
commit: jest.fn(),
|
||||||
|
dispatch: jest.fn(),
|
||||||
getters: {
|
getters: {
|
||||||
vehicle: {
|
vehicle: {
|
||||||
make: "Acura",
|
make: "Acura",
|
||||||
|
|
@ -182,6 +187,33 @@ describe("vehicle-model.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("vehicle-model.vue", () => {
|
||||||
|
test("Year set, call invalidation, style, carId, category should be null", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleModel.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "vehicle-model" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.resetDependentState();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
|
||||||
|
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
buttonQuestionContent = {},
|
buttonQuestionContent = {},
|
||||||
modelQuestionInitialData = {},
|
modelQuestionInitialData = {},
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
||||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
|
|
@ -31,7 +33,7 @@ export default {
|
||||||
name: "vehicle-model",
|
name: "vehicle-model",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedModel: null,
|
selectedModel: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
@ -77,17 +79,30 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
// route to move backwards
|
// route to move backwards
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return store.getters.vehicle.make !== null;
|
return store.getters.vehicle.make !== null;
|
||||||
},
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
// Set
|
||||||
|
store.commit(storeMutations.UPDATE_STYLE, null);
|
||||||
|
store.commit(storeMutations.UPDATE_CAR_ID, null);
|
||||||
|
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
||||||
|
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
|
||||||
|
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
selectedModel(model) {
|
selectedModel(model) {
|
||||||
this.$store.commit(this.storeMutations.UPDATE_MODEL, model);
|
this.$store.commit(this.storeMutations.UPDATE_MODEL, model);
|
||||||
this.$router.navigate(
|
this.$router.navigateAfterSave(
|
||||||
this.navigationScenarios.SELECTED_MODEL,
|
this.navigationScenarios.SELECTED_MODEL,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
:loaderEnabled="true"
|
:loaderEnabled="true"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
|
isRequired=true
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: Array,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,14 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-style",
|
name: "vehicle-style",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedStyle: null,
|
selectedStyle: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
@ -77,7 +78,10 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
// route to move backwards
|
// route to move backwards
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
},
|
},
|
||||||
setVehicle() {
|
setVehicle() {
|
||||||
return this.dispatchNonBlockingStoreAction(
|
return this.dispatchNonBlockingStoreAction(
|
||||||
|
|
@ -93,13 +97,18 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return store.getters.vehicle.model !== null;
|
return store.getters.vehicle.model !== null;
|
||||||
},
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
|
||||||
|
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
selectedStyle(style) {
|
selectedStyle(style) {
|
||||||
this.$store.commit(this.storeMutations.UPDATE_STYLE, style);
|
this.$store.commit(this.storeMutations.UPDATE_STYLE, style);
|
||||||
this.setVehicle().then(() => {
|
this.setVehicle().then(() => {
|
||||||
this.$router.navigate(
|
this.$router.navigateAfterSave(
|
||||||
this.navigationScenarios.SELECTED_STYLE,
|
this.navigationScenarios.SELECTED_STYLE,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,35 @@
|
||||||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
import { shallowMount, flushPromises } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
|
||||||
import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
|
import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
|
||||||
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
||||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
|
||||||
import { nextTick } from "vue";
|
import store from "@/store";
|
||||||
|
|
||||||
|
jest.mock("@/store", () => ({
|
||||||
|
commit: jest.fn(),
|
||||||
|
dispatch: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
settleAllPromises: jest.fn(),
|
settleAllPromises: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Mock fetchCmsContentForPage
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
describe("vehicle-year.vue", () => {
|
describe("vehicle-year.vue", () => {
|
||||||
test("Year question component is initized with api data", async (done) => {
|
test("Year question component is initized with api data", async (done) => {
|
||||||
//Arrange
|
//Arrange
|
||||||
|
|
@ -123,6 +140,34 @@ describe("vehicle-year.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("vehicle-year.vue", () => {
|
||||||
|
test("Year set, call invalidation, make, model, style, carId, category should be null", async () => {
|
||||||
|
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleYear.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "vehicle-year" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.resetDependentState();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MAKE, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
|
||||||
|
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
|
||||||
|
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
|
||||||
|
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
vehicleYearQuestionCmsContent = {},
|
vehicleYearQuestionCmsContent = {},
|
||||||
yearQuestionInitialData = {},
|
yearQuestionInitialData = {},
|
||||||
|
|
@ -146,7 +191,9 @@ function setupMocks({
|
||||||
yearQuestionInitialData: yearQuestionInitialData,
|
yearQuestionInitialData: yearQuestionInitialData,
|
||||||
};
|
};
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
const apiPromise = Promise.resolve(apiResponses);
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiPromise);
|
settleAllPromises.mockImplementation(() => apiPromise);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
//Mock year question methods
|
//Mock year question methods
|
||||||
yearQuestion.methods = {
|
yearQuestion.methods = {
|
||||||
|
|
@ -162,6 +209,7 @@ function setupMocks({
|
||||||
funnelSubHeader.methods = {
|
funnelSubHeader.methods = {
|
||||||
initializeComponent: jest.fn(),
|
initializeComponent: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
const wrapper = shallowMount(vehicleYear, mountOptions);
|
const wrapper = shallowMount(vehicleYear, mountOptions);
|
||||||
const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" });
|
const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" });
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,15 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import eventBus from "@/helpers/event-bus/event-bus";
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-year",
|
name: "vehicle-year",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedYear: null,
|
selectedYear: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
@ -73,8 +75,9 @@ export default {
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
selectedYear(year) {
|
selectedYear(year) {
|
||||||
|
|
||||||
this.$store.commit(this.storeMutations.UPDATE_YEAR, year);
|
this.$store.commit(this.storeMutations.UPDATE_YEAR, year);
|
||||||
this.$router.navigate(
|
this.$router.navigateAfterSave(
|
||||||
this.navigationScenarios.SELECTED_YEAR,
|
this.navigationScenarios.SELECTED_YEAR,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
@ -84,6 +87,19 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
resetDependentState() {
|
||||||
|
|
||||||
|
// Set
|
||||||
|
store.commit(storeMutations.UPDATE_MAKE, null);
|
||||||
|
store.commit(storeMutations.UPDATE_MODEL, null);
|
||||||
|
store.commit(storeMutations.UPDATE_STYLE, null);
|
||||||
|
store.commit(storeMutations.UPDATE_CAR_ID, null);
|
||||||
|
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
||||||
|
|
||||||
|
// Invokes
|
||||||
|
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
|
||||||
|
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
yearQuestion,
|
yearQuestion,
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,9 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: Array,
|
||||||
},
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
components: {
|
components: {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -45,16 +45,16 @@ const routes = [
|
||||||
// If we already have our route, go to it.
|
// If we already have our route, go to it.
|
||||||
if (router.hasRoute(to.query.fmgPage)) {
|
if (router.hasRoute(to.query.fmgPage)) {
|
||||||
// Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function.
|
// Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function.
|
||||||
const arePagePrerequisitesValid = router
|
const component = router
|
||||||
.getRoutes()
|
.getRoutes()
|
||||||
.filter((x) => x.name === to.query.fmgPage)[0]
|
.filter((x) => x.name === to.query.fmgPage)[0].components;
|
||||||
.components.default.methods.arePagePrerequisitesValid();
|
|
||||||
|
|
||||||
if (!arePagePrerequisitesValid) {
|
if (!arePagePrerequisitesValid(component)) {
|
||||||
await GoToFunnelStartOn404(next);
|
await GoToFunnelStartOn404(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
return next({ name: to.query.fmgPage, query: to.query, params: to.params });
|
|
||||||
|
return next({ name: to.query.fmgPage, query: to.query, params: to.params });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get route info for the given url. Names will have a 1:1 relationship with names in the Cms.
|
// Get route info for the given url. Names will have a 1:1 relationship with names in the Cms.
|
||||||
|
|
@ -74,7 +74,7 @@ const routes = [
|
||||||
.filter((x) => x.name === routeData[0].name)[0]
|
.filter((x) => x.name === routeData[0].name)[0]
|
||||||
.components.default();
|
.components.default();
|
||||||
|
|
||||||
if (!nextComponent.default.methods.arePagePrerequisitesValid()) {
|
if (!arePagePrerequisitesValid(nextComponent)) {
|
||||||
await GoToFunnelStartOn404(next);
|
await GoToFunnelStartOn404(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,23 +102,36 @@ const router = createRouter({
|
||||||
|
|
||||||
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
|
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
|
||||||
|
|
||||||
|
router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
|
||||||
|
navigate(scenario, currentRoute, false, optionalQuery, optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
|
||||||
|
navigate(scenario, currentRoute, true, optionalQuery, optionalParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRIVATE FUNCTIONS
|
||||||
|
|
||||||
// Navigate to the next route, depending on the scenario.
|
// Navigate to the next route, depending on the scenario.
|
||||||
router.navigate = (
|
function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}) {
|
||||||
scenario,
|
|
||||||
currentRoute,
|
|
||||||
optionalQuery = {},
|
|
||||||
optionalParams = {}
|
|
||||||
) => {
|
|
||||||
if (!scenario) {
|
if (!scenario) {
|
||||||
console.error("No scenario provided. Please review the routing table.");
|
console.error("No scenario provided. Please review the routing table.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match our maps up and navigate if we have a destination.
|
// Match our maps up and navigate if we have a destination.
|
||||||
const matchingScenarioMap = router.getNavigationMap(scenario, currentRoute);
|
const matchingScenarioMap = getNavigationMap(scenario, currentRoute);
|
||||||
|
|
||||||
if (matchingScenarioMap.destinationFmgPageValue !== undefined) {
|
if (matchingScenarioMap.destinationFmgPageValue !== undefined) {
|
||||||
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one.
|
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one.
|
||||||
|
|
||||||
|
// If we need to do invalidation
|
||||||
|
const currentComponent = currentRoute.matched[0].components;
|
||||||
|
|
||||||
|
if (invalidateOnSave) {
|
||||||
|
resetDependentState(currentComponent);
|
||||||
|
}
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
name: "root",
|
name: "root",
|
||||||
query: Object.assign(optionalQuery, {
|
query: Object.assign(optionalQuery, {
|
||||||
|
|
@ -132,7 +145,7 @@ router.navigate = (
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get navigation map depending on the scenario and the current 'page' you're on.
|
// Get navigation map depending on the scenario and the current 'page' you're on.
|
||||||
router.getNavigationMap = (scenario, currentRoute) => {
|
function getNavigationMap(scenario, currentRoute) {
|
||||||
const fmgPageValue = currentRoute.query.fmgPage;
|
const fmgPageValue = currentRoute.query.fmgPage;
|
||||||
const matchedQueryValue = routingTable
|
const matchedQueryValue = routingTable
|
||||||
.filter(
|
.filter(
|
||||||
|
|
@ -197,4 +210,14 @@ async function GoToFunnelStartOn404(next) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks arePagePrerequisitesValid on the component passed in.
|
||||||
|
function arePagePrerequisitesValid(component) {
|
||||||
|
return component.default.methods.arePagePrerequisitesValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset dependant state on route change.
|
||||||
|
function resetDependentState(component) {
|
||||||
|
return component.default.methods.resetDependentState();
|
||||||
|
}
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ const navigationScenarios = {
|
||||||
SELECTED_MODEL: "SELECTED_MODEL",
|
SELECTED_MODEL: "SELECTED_MODEL",
|
||||||
SELECTED_MAKE: "SELECTED_MAKE",
|
SELECTED_MAKE: "SELECTED_MAKE",
|
||||||
SELECTED_STYLE: "SELECTED_STYLE",
|
SELECTED_STYLE: "SELECTED_STYLE",
|
||||||
VEHICLE_DAMAGE: "VEHICLE_DAMAGE",
|
|
||||||
CLICKED_BACK: "CLICKED_BACK",
|
CLICKED_BACK: "CLICKED_BACK",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,231 @@ import { endpoints } from "@/constants/endpoints.js";
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
import createPersistedState from "vuex-persistedstate";
|
import createPersistedState from "vuex-persistedstate";
|
||||||
import globalMethods from "@/global-methods";
|
import globalMethods from "@/global-methods";
|
||||||
import eventBus from "../helpers/event-bus/event-bus";
|
|
||||||
|
|
||||||
|
|
||||||
|
// Export State
|
||||||
|
export const state = {
|
||||||
|
order: {
|
||||||
|
vehicle: {
|
||||||
|
year: null,
|
||||||
|
make: null,
|
||||||
|
model: null,
|
||||||
|
style: null,
|
||||||
|
carId: null,
|
||||||
|
category: null,
|
||||||
|
imageUrl: null,
|
||||||
|
imageVifNumber: null,
|
||||||
|
imageColor: null,
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: null,
|
||||||
|
numberOfChips: null,
|
||||||
|
glassToReplace: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
applicationUser: {
|
||||||
|
eventBus: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export Mutations
|
||||||
|
export const mutations = {
|
||||||
|
// VEHICLE MUTATIONS
|
||||||
|
updateYear(state, year) {
|
||||||
|
state.order.vehicle.year = year;
|
||||||
|
},
|
||||||
|
updateMake(state, make) {
|
||||||
|
state.order.vehicle.make = make;
|
||||||
|
},
|
||||||
|
updateModel(state, model) {
|
||||||
|
state.order.vehicle.model = model;
|
||||||
|
},
|
||||||
|
updateStyle(state, style) {
|
||||||
|
state.order.vehicle.style = style;
|
||||||
|
},
|
||||||
|
updateCarId(state, carId) {
|
||||||
|
state.order.vehicle.carId = carId;
|
||||||
|
},
|
||||||
|
updateVehicleCategory(state, category) {
|
||||||
|
state.order.vehicle.category = category;
|
||||||
|
},
|
||||||
|
|
||||||
|
// EVENT BUS MUTATIONS
|
||||||
|
addEventToBus(state, event) {
|
||||||
|
state.applicationUser.eventBus.push(event);
|
||||||
|
},
|
||||||
|
removeEventFromBus(state, eventData) {
|
||||||
|
const matchedEvent = state.applicationUser.eventBus.find(
|
||||||
|
({ category, subCategory }) =>
|
||||||
|
category === eventData.category &&
|
||||||
|
subCategory === eventData.subCategory
|
||||||
|
);
|
||||||
|
const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
|
||||||
|
|
||||||
|
// If the item exists, remove it.
|
||||||
|
if (itemIndex > -1) {
|
||||||
|
state.applicationUser.eventBus.splice(itemIndex, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// DEPENDENCY MUTATIONS
|
||||||
|
resetVehicleAndDependencies(state) {
|
||||||
|
state.order.vehicle.year = null;
|
||||||
|
state.order.vehicle.make = null;
|
||||||
|
state.order.vehicle.model = null;
|
||||||
|
state.order.vehicle.style = null;
|
||||||
|
state.order.vehicle.carId = null;
|
||||||
|
state.order.vehicle.category = null;
|
||||||
|
},
|
||||||
|
resetDamageAndDependencies(state) {
|
||||||
|
state.order.damage.isRepair = null;
|
||||||
|
state.order.damage.numberOfChips = null;
|
||||||
|
state.order.damage.windshieldGlassToReplace = null;
|
||||||
|
state.order.damage.driverSideGlassToReplace = null;
|
||||||
|
state.order.damage.passengerSideGlassToReplace = null;
|
||||||
|
state.order.damage.rearGlassToReplace = null;
|
||||||
|
|
||||||
|
},
|
||||||
|
resetRegistrationAndDependencies(state) {
|
||||||
|
|
||||||
|
},
|
||||||
|
resetPartsAndDependencies(state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export Getters
|
||||||
|
export const getters = {
|
||||||
|
vehicle: (state) => state.order.vehicle,
|
||||||
|
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
|
||||||
|
const matchedEvent = state.applicationUser.eventBus.find(
|
||||||
|
({ category, subCategory }) =>
|
||||||
|
category === eventCategory && subCategory === eventSubCategory
|
||||||
|
);
|
||||||
|
|
||||||
|
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
|
||||||
|
},
|
||||||
|
eventBus: (state) => state.applicationUser.eventBus,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export Actions
|
||||||
|
export const actions = {
|
||||||
|
// Vehicle API Actions
|
||||||
|
getVehicleYears(context) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleYears.method,
|
||||||
|
endpoint: endpoints.GetVehicleYears.url,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lookupVehicleByYmms(context, { year, make, model, style }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.LookupVehicleByYmms.method,
|
||||||
|
endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
lookupVehicleByVin(context, { vin }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.LookupVehicleByVin.method,
|
||||||
|
endpoint: endpoints.LookupVehicleByVin.url,
|
||||||
|
payload: {
|
||||||
|
vin: vin, // EX "1J4GW58S4XC541166"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getVehicleMakes(context, { year }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleMakes.method,
|
||||||
|
endpoint: `${endpoints.GetVehicleMakes.url}/${year}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getVehicleModels(context, { year, make }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleModels.method,
|
||||||
|
endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getVehicleStyles(context, { year, make, model }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleStyles.method,
|
||||||
|
endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setVehicle(context, { year, make, model, style }) {
|
||||||
|
return globalMethods
|
||||||
|
.callHttpClient({
|
||||||
|
methods: endpoints.GetVehicle.method,
|
||||||
|
endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`,
|
||||||
|
payload: {},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId);
|
||||||
|
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category);
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getDamageOptions(context, { carId }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
methods: endpoints.GetDamageOptions.method,
|
||||||
|
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// DEPENDENCY ACTIONS
|
||||||
|
resetVehicleAndDependencies(context) {
|
||||||
|
context.commit(storeMutations.RESET_VEHICLE_AND_DEPS);
|
||||||
|
context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
|
||||||
|
context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
},
|
||||||
|
resetDamageAndDependencies(context) {
|
||||||
|
context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
|
||||||
|
context.commit(storeMutations.RESET_PARTS_AND_DEPS);
|
||||||
|
},
|
||||||
|
resetRegistrationAndDependencies(context) {
|
||||||
|
context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
context.commit(storeMutations.RESET_PARTS_AND_DEPS)
|
||||||
|
},
|
||||||
|
resetPartsAndDependencies(context) {
|
||||||
|
context.commit(storeMutations.RESET_PARTS_AND_DEPS);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Content API Actions
|
||||||
|
getRouteInfo(context, { pageName }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetRouteInfo.method,
|
||||||
|
endpoint: endpoints.GetRouteInfo.url,
|
||||||
|
payload: {
|
||||||
|
pageName: pageName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getHomepageName(context) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetHomepageInfo.method,
|
||||||
|
endpoint: endpoints.GetHomepageInfo.url,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getPageData(context, { pageName }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetPageData.method,
|
||||||
|
endpoint: `${endpoints.GetPageData.url}/${pageName}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEvoxImage(context, { relativeUrl }) {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetPageData.method,
|
||||||
|
endpoint: relativeUrl,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
plugins: [createPersistedState()],
|
plugins: [createPersistedState()],
|
||||||
|
|
@ -12,175 +236,8 @@ export default createStore({
|
||||||
// * The CMS can reference the fields by name
|
// * The CMS can reference the fields by name
|
||||||
// * Return users may have a previous "version" of the model, and we don't want
|
// * Return users may have a previous "version" of the model, and we don't want
|
||||||
// them to have a breaking experience, because the model might have changed.
|
// them to have a breaking experience, because the model might have changed.
|
||||||
state: {
|
state,
|
||||||
order: {
|
mutations,
|
||||||
vehicle: {
|
getters,
|
||||||
year: null,
|
actions,
|
||||||
make: null,
|
|
||||||
model: null,
|
|
||||||
style: null,
|
|
||||||
carId: null,
|
|
||||||
category: null,
|
|
||||||
imageUrl: null,
|
|
||||||
imageVifNumber: null,
|
|
||||||
imageColor: null,
|
|
||||||
damage: {
|
|
||||||
isRepair: null,
|
|
||||||
numberOfChips: null,
|
|
||||||
glassToReplace: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
applicationUser: {
|
|
||||||
eventBus: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// See IMPORTANT note at top of "state" declaration.
|
|
||||||
|
|
||||||
mutations: {
|
|
||||||
updateYear(state, year) {
|
|
||||||
state.order.vehicle.year = year;
|
|
||||||
},
|
|
||||||
updateMake(state, make) {
|
|
||||||
state.order.vehicle.make = make;
|
|
||||||
},
|
|
||||||
updateModel(state, model) {
|
|
||||||
state.order.vehicle.model = model;
|
|
||||||
},
|
|
||||||
updateStyle(state, style) {
|
|
||||||
state.order.vehicle.style = style;
|
|
||||||
},
|
|
||||||
updateVehicle(state, data) {
|
|
||||||
state.order.vehicle.carId = data.carId;
|
|
||||||
state.order.vehicle.category = data.category;
|
|
||||||
state.order.vehicle.imageUrl = data.imageUrl;
|
|
||||||
state.order.vehicle.imageVifNumber = data.imageVifNumber;
|
|
||||||
state.order.vehicle.imageColor = data.imageVifColor;
|
|
||||||
},
|
|
||||||
addEventToBus(state, event) {
|
|
||||||
state.applicationUser.eventBus.push(event);
|
|
||||||
},
|
|
||||||
removeEventFromBus(state, eventData) {
|
|
||||||
const matchedEvent = state.applicationUser.eventBus.find(
|
|
||||||
({ category, subCategory }) =>
|
|
||||||
category === eventData.category &&
|
|
||||||
subCategory === eventData.subCategory
|
|
||||||
);
|
|
||||||
const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
|
|
||||||
|
|
||||||
// If the item exists, remove it.
|
|
||||||
if (itemIndex > -1) {
|
|
||||||
state.applicationUser.eventBus.splice(itemIndex, 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
getters: {
|
|
||||||
vehicle: (state) => state.order.vehicle,
|
|
||||||
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
|
|
||||||
const matchedEvent = state.applicationUser.eventBus.find(
|
|
||||||
({ category, subCategory }) =>
|
|
||||||
category === eventCategory && subCategory === eventSubCategory
|
|
||||||
);
|
|
||||||
|
|
||||||
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
|
|
||||||
},
|
|
||||||
eventBus: (state) => state.applicationUser.eventBus,
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
// Vehicle API Actions
|
|
||||||
getVehicleYears(context) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetVehicleYears.method,
|
|
||||||
endpoint: endpoints.GetVehicleYears.url,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
lookupVehicleByYmms(context, { year, make, model, style }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.LookupVehicleByYmms.method,
|
|
||||||
endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
lookupVehicleByVin(context, { vin }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.LookupVehicleByVin.method,
|
|
||||||
endpoint: endpoints.LookupVehicleByVin.url,
|
|
||||||
payload: {
|
|
||||||
vin: vin, // EX "1J4GW58S4XC541166"
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getVehicleMakes(context, { year }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetVehicleMakes.method,
|
|
||||||
endpoint: `${endpoints.GetVehicleMakes.url}/${year}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getVehicleModels(context, { year, make }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetVehicleModels.method,
|
|
||||||
endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getVehicleStyles(context, { year, make, model }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetVehicleStyles.method,
|
|
||||||
endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setVehicle(context, { year, make, model, style }) {
|
|
||||||
return globalMethods
|
|
||||||
.callHttpClient({
|
|
||||||
methods: endpoints.GetVehicle.method,
|
|
||||||
endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`,
|
|
||||||
payload: {},
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE, response.data);
|
|
||||||
return response;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getDamageOptions(context, { carId }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
methods: endpoints.GetDamageOptions.method,
|
|
||||||
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Content API Actions
|
|
||||||
getRouteInfo(context, { pageName }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetRouteInfo.method,
|
|
||||||
endpoint: endpoints.GetRouteInfo.url,
|
|
||||||
payload: {
|
|
||||||
pageName: pageName,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getHomepageName(context) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetHomepageInfo.method,
|
|
||||||
endpoint: endpoints.GetHomepageInfo.url,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getPageData(context, { pageName }) {
|
|
||||||
return globalMethods.callHttpClient({
|
|
||||||
method: endpoints.GetPageData.method,
|
|
||||||
endpoint: `${endpoints.GetPageData.url}/${pageName}`,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getEvoxImage(context, { relativeUrl }) {
|
|
||||||
return globalMethods.callMockHttpClient({
|
|
||||||
method: endpoints.GetPageData.method,
|
|
||||||
endpoint: relativeUrl,
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,328 +1,483 @@
|
||||||
import store from "./index";
|
|
||||||
import globalMethods from "@/global-methods";
|
import globalMethods from "@/global-methods";
|
||||||
|
import { mutations, state, actions, getters } from "@/store";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
|
||||||
describe("Actions", () => {
|
// Mock global method
|
||||||
it("Should return list of years retrieved", async () => {
|
globalMethods.callHttpClient = jest.fn();
|
||||||
|
|
||||||
|
|
||||||
|
describe("Mutations", () => {
|
||||||
|
|
||||||
|
it("Updates vehicle year in state", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let years = [];
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateYear(storeState, "2019");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.year).toEqual("2019");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Updates vehicle make in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateMake(storeState, "Acura");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.make).toEqual("Acura");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Updates vehicle model in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateModel(storeState, "ILX");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.model).toEqual("ILX");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Updates vehicle style in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateStyle(storeState, "4 DOOR SEDAN");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Updates vehicle carId in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateCarId(storeState, "C0000001");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.carId).toEqual("C0000001");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Updates vehicle vehicle category in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateVehicleCategory(storeState, "CAR");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.order.vehicle.category).toEqual("CAR");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Remove item to eventBus in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const event = { category: "CategoryOne", subCategory: "SubCategoryOne" }
|
||||||
|
|
||||||
|
// Act / Assert
|
||||||
|
mutations.addEventToBus(storeState, event);
|
||||||
|
expect(storeState.applicationUser.eventBus).toEqual([event]);
|
||||||
|
|
||||||
|
// Act / Assert
|
||||||
|
mutations.removeEventFromBus(storeState, event);
|
||||||
|
expect(storeState.applicationUser.eventBus).toEqual([]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Adds item to eventBus in state", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.addEventToBus(storeState, { EventOne: "ValueOne" });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.applicationUser.eventBus).toEqual([{ EventOne: "ValueOne" }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resetVehicleAndDependencies, should set fields to null", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
mutations.updateYear(storeState, "2019");
|
||||||
|
mutations.updateMake(storeState, "Acura");
|
||||||
|
mutations.updateModel(storeState, "ILX");
|
||||||
|
mutations.updateStyle(storeState, "4 DOOR SEDAN");
|
||||||
|
mutations.updateCarId(storeState, "C0000001");
|
||||||
|
mutations.updateVehicleCategory(storeState, "CAR");
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(storeState.order.vehicle.year).toEqual("2019");
|
||||||
|
expect(storeState.order.vehicle.make).toEqual("Acura");
|
||||||
|
expect(storeState.order.vehicle.model).toEqual("ILX");
|
||||||
|
expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN");
|
||||||
|
expect(storeState.order.vehicle.carId).toEqual("C0000001");
|
||||||
|
expect(storeState.order.vehicle.category).toEqual("CAR");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.resetVehicleAndDependencies(storeState);
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(storeState.order.vehicle.year).toEqual(null);
|
||||||
|
expect(storeState.order.vehicle.make).toEqual(null);
|
||||||
|
expect(storeState.order.vehicle.model).toEqual(null);
|
||||||
|
expect(storeState.order.vehicle.style).toEqual(null);
|
||||||
|
expect(storeState.order.vehicle.carId).toEqual(null);
|
||||||
|
expect(storeState.order.vehicle.category).toEqual(null);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resetDamageAndDependencies, should set fields to null", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
storeState.order.damage = {
|
||||||
|
isRepair: true,
|
||||||
|
numberOfChips: 2,
|
||||||
|
windshieldGlassToReplace: "Front",
|
||||||
|
driverSideGlassToReplace: "Rear",
|
||||||
|
passengerSideGlassToReplace: "Rear",
|
||||||
|
rearGlassToReplace: "Slider"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(storeState.order.damage.isRepair).toEqual(true);
|
||||||
|
expect(storeState.order.damage.numberOfChips).toEqual(2);
|
||||||
|
expect(storeState.order.damage.windshieldGlassToReplace).toEqual("Front");
|
||||||
|
expect(storeState.order.damage.driverSideGlassToReplace).toEqual("Rear");
|
||||||
|
expect(storeState.order.damage.passengerSideGlassToReplace).toEqual("Rear");
|
||||||
|
expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.resetDamageAndDependencies(storeState);
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
expect(storeState.order.damage.isRepair).toEqual(null);
|
||||||
|
expect(storeState.order.damage.numberOfChips).toEqual(null);
|
||||||
|
expect(storeState.order.damage.windshieldGlassToReplace).toEqual(null);
|
||||||
|
expect(storeState.order.damage.driverSideGlassToReplace).toEqual(null);
|
||||||
|
expect(storeState.order.damage.passengerSideGlassToReplace).toEqual(null);
|
||||||
|
expect(storeState.order.damage.rearGlassToReplace).toEqual(null);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Actions", () => {
|
||||||
|
it("getVehicleYears action, should return years array", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient = jest.fn();
|
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({ data: [2023, 2022, 2021] });
|
return Promise.resolve({ data: [2023, 2022, 2021] });
|
||||||
});
|
});
|
||||||
await store.dispatch("getVehicleYears").then((response) => {
|
|
||||||
years = response.data;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(years[0]).toBe(2023);
|
const response = await actions.getVehicleYears(context)
|
||||||
|
|
||||||
|
expect(response.data).toEqual([2023, 2022, 2021]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return list of makes retrieved", async () => {
|
it("lookupVehicleByYmms action, should return car data", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let makes = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({ data: ["Baic", "Honda", "Ford"] });
|
return Promise.resolve({ data: { carId: "C00000001" } });
|
||||||
});
|
|
||||||
await store.dispatch("getVehicleMakes", { year: 2023 }).then((response) => {
|
|
||||||
makes = response.data;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(makes[0]).toBe("Baic");
|
const response = await actions.lookupVehicleByYmms(context, "2019", "Acura", "ILX", "4 DOOR SEDAN")
|
||||||
|
|
||||||
|
expect(response.data).toEqual({ carId: "C00000001" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return list of models retrieved", async () => {
|
it("lookupVehicleByVin action, should return car data", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let models = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({ data: ["BJ40 (MEX)", "Civic", "Accord"] });
|
return Promise.resolve({ data: { carId: "C00000001" } });
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getVehicleModels", { year: 2023, make: "Baic" })
|
|
||||||
.then((response) => {
|
|
||||||
models = response.data;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(models[0]).toBe("BJ40 (MEX)");
|
const response = await actions.lookupVehicleByVin(context, "12345678901234567")
|
||||||
|
|
||||||
|
expect(response.data).toEqual({ carId: "C00000001" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return list of styles retrieved", async () => {
|
it("getVehicleMakes action, should return makes list", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let styles = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({ data: ["4 DOOR UTILITY", "2 DOOR"] });
|
return Promise.resolve({ data: ["Acura", "Honda"] });
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getVehicleStyles", {
|
|
||||||
year: 2023,
|
|
||||||
make: "Baic",
|
|
||||||
model: "BJ40 (MEX)",
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
styles = response.data;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(styles[0]).toBe("4 DOOR UTILITY");
|
const response = await actions.getVehicleMakes(context, "2019")
|
||||||
|
|
||||||
|
expect(response.data).toEqual(["Acura", "Honda"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return list of damage options retrieved", async () => {
|
it("getVehicleModels action, should return models list", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let damageOptions = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({ data: ["Front Window", "Rear Window"] });
|
return Promise.resolve({ data: ["ILX", "RDX"] });
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getDamageOptions", {
|
|
||||||
carId: "CR00070154",
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
damageOptions = response.data;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(damageOptions[0]).toBe("Front Window");
|
const response = await actions.getVehicleModels(context, "2019", "Acura")
|
||||||
|
|
||||||
|
expect(response.data).toEqual(["ILX", "RDX"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return data from url retrieved", async () => {
|
it("getVehicleStyles action, should return models list", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let routeInfo = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({ data: { style: "4 DOOR SEDAN" } });
|
||||||
data: {
|
|
||||||
Result: "Route Info Data",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getRouteInfo", { pageName: "vehicle-year" })
|
|
||||||
.then((response) => {
|
|
||||||
routeInfo = response.data.Result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(routeInfo).toBe("Route Info Data");
|
const response = await actions.getVehicleStyles(context, "2019", "Acura", "ILX")
|
||||||
|
|
||||||
|
expect(response.data).toEqual({ style: "4 DOOR SEDAN" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return page data from url retrieved", async () => {
|
it("setVehicle action, should get vehicle data and set carId and vehicle category", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let pageData = [];
|
const context = state;
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
context.commit = commit;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({ data: { carId: "C00000000", category: "CAR" } });
|
||||||
data: {
|
|
||||||
Result: "Page Info Data",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getPageData", { pageName: "vehicle-year" })
|
|
||||||
.then((response) => {
|
|
||||||
pageData = response.data.Result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(pageData).toBe("Page Info Data");
|
const response = await actions.setVehicle(context, "C00000000")
|
||||||
|
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, "C00000000");
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, "CAR");
|
||||||
|
expect(response.data).toEqual({ carId: "C00000000", category: "CAR" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return data from url retrieved", async () => {
|
it("getDamageOptions action", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let returnData = [];
|
const context = state;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({ data: ["Windshield", "DriversFrontDoor"] });
|
||||||
data: {
|
|
||||||
Result: "2018 Honda Civic",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("lookupVehicleByYmms", {
|
const response = await actions.getDamageOptions(context, "C00000000")
|
||||||
year: "2018",
|
|
||||||
make: "Honda",
|
|
||||||
model: "Civic",
|
|
||||||
style: "2 Door",
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
returnData = response.data.Result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(returnData).toBe("2018 Honda Civic");
|
expect(response.data).toEqual(["Windshield", "DriversFrontDoor"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return vehicle data from url retrieved", async () => {
|
it("resetVehicleAndDependencies action", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
let returnData = [];
|
const context = state;
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
context.commit = commit;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
await actions.resetVehicleAndDependencies(context)
|
||||||
|
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_AND_DEPS);
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resetDamageAndDependencies action", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
context.commit = commit;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await actions.resetDamageAndDependencies(context)
|
||||||
|
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resetRegistrationAndDependencies action", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
context.commit = commit;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await actions.resetRegistrationAndDependencies(context)
|
||||||
|
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resetPartsAndDependencies action", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
const commit = jest.fn();
|
||||||
|
|
||||||
|
context.commit = commit;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await actions.resetPartsAndDependencies(context)
|
||||||
|
|
||||||
|
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("getRouteInfo action, returns route info", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
|
||||||
globalMethods.callHttpClient.mockImplementation(() => {
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({ data: { Widget: "Data" } });
|
||||||
data: {
|
|
||||||
Result: "2021 Honda Civic",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("lookupVehicleByVin", { vin: "12345678" })
|
|
||||||
.then((response) => {
|
|
||||||
returnData = response.data.Result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(returnData).toBe("2021 Honda Civic");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should return vehicle image data from url retrieved", async () => {
|
|
||||||
// Arrange
|
|
||||||
let returnData = [];
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
globalMethods.callMockHttpClient = jest.fn();
|
const response = await actions.getRouteInfo(context, "vehicle-year")
|
||||||
globalMethods.callMockHttpClient.mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
expect(response.data).toEqual({ Widget: "Data" });
|
||||||
Result: "2008_honda_civic.jpg",
|
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
it("getHomepageName action, returns homepage name", async () => {
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
|
||||||
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
|
return Promise.resolve({ data: { Name: "vehicle-year" } });
|
||||||
});
|
});
|
||||||
await store
|
|
||||||
.dispatch("getEvoxImage", { relativeUrl: "evox_image.com" })
|
|
||||||
.then((response) => {
|
|
||||||
returnData = response.data.Result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(returnData).toBe("2008_honda_civic.jpg");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Mutations", () => {
|
|
||||||
it("Should update the year property in the store", () => {
|
|
||||||
// Act
|
// Act
|
||||||
store.commit("updateYear", 2020);
|
const response = await actions.getHomepageName(context)
|
||||||
|
|
||||||
|
|
||||||
|
expect(response.data).toEqual({ Name: "vehicle-year" });
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.state.order.vehicle.year).toBe(2020);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should update the make property in the store", () => {
|
it("getPageData action, returns page data", async () => {
|
||||||
// Act
|
|
||||||
store.commit("updateMake", "Honda");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.state.order.vehicle.make).toBe("Honda");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should update the model property in the store", () => {
|
|
||||||
// Act
|
|
||||||
store.commit("updateModel", "Civic");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.state.order.vehicle.model).toBe("Civic");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should update the style property in the store", () => {
|
|
||||||
// Act
|
|
||||||
store.commit("updateStyle", "2 Door");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.state.order.vehicle.style).toBe("2 Door");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should update the carID and category propertys in the store", () => {
|
|
||||||
// Arrange
|
// Arrange
|
||||||
const carData = {
|
const context = state;
|
||||||
carId: "123abc",
|
|
||||||
category: "car",
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
};
|
return Promise.resolve({ data: { Results: [{ Widget: "Data" }] } });
|
||||||
// Act
|
});
|
||||||
store.commit("updateVehicle", carData);
|
|
||||||
|
// Act
|
||||||
|
const response = await actions.getPageData(context, "vehicle-year")
|
||||||
|
|
||||||
|
|
||||||
|
expect(response.data).toEqual({ Results: [{ Widget: "Data" }] });
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.state.order.vehicle.carId).toBe("123abc");
|
|
||||||
expect(store.state.order.vehicle.category).toBe("car");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add event onto bus and update state", () => {
|
it("getEvoxImage action, returns image url", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const event = {
|
const context = state;
|
||||||
category: "TestCategoryOne",
|
|
||||||
subCategory: "TestSubCategoryOne",
|
globalMethods.callHttpClient.mockImplementation(() => {
|
||||||
eventValue: "TestEventValueOne",
|
return Promise.resolve({ data: { imageUrl: "https://test.com" } });
|
||||||
};
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
store.commit("addEventToBus", event);
|
const response = await actions.getEvoxImage(context, { relativeUrl: "https://relativeurl.com" });
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(store.state.applicationUser.eventBus[0].category).toBe(
|
expect(response.data).toEqual({ imageUrl: "https://test.com" });
|
||||||
"TestCategoryOne"
|
|
||||||
);
|
|
||||||
expect(store.state.applicationUser.eventBus[0].subCategory).toBe(
|
|
||||||
"TestSubCategoryOne"
|
|
||||||
);
|
|
||||||
expect(store.state.applicationUser.eventBus[0].eventValue).toBe(
|
|
||||||
"TestEventValueOne"
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Getters", () => {
|
describe("Getters", () => {
|
||||||
it("Should validate vehicle getter", () => {
|
it("Vehicle getter, should return vehicle data", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const vehicle = store.getters.vehicle;
|
const storeState = state;
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(typeof vehicle).toBe("object");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should get item from bus via getter", () => {
|
|
||||||
// Arrange
|
|
||||||
const event = {
|
|
||||||
category: "TestCategoryOne",
|
|
||||||
subCategory: "TestSubCategoryOne",
|
|
||||||
eventValue: "TestEventValueOne",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
store.commit("addEventToBus", event);
|
mutations.updateYear(storeState, "2019");
|
||||||
|
mutations.updateMake(storeState, "Acura");
|
||||||
|
mutations.updateModel(storeState, "ILX");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const returnedEventValue = store.getters.eventBusItem(
|
expect(getters.vehicle(storeState).year).toEqual("2019");
|
||||||
event.category,
|
expect(getters.vehicle(storeState).make).toEqual("Acura");
|
||||||
event.subCategory
|
expect(getters.vehicle(storeState).model).toEqual("ILX");
|
||||||
);
|
|
||||||
expect(returnedEventValue).toBe("TestEventValueOne");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should get eventbus from getter, should have length > 0", () => {
|
it("Get event bus item by event category and eventSubCategory", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const event = {
|
const storeState = state;
|
||||||
category: "TestCategoryOne",
|
const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" };
|
||||||
subCategory: "TestSubCategoryOne",
|
|
||||||
eventValue: "TestEventValueOne",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
store.commit("addEventToBus", event);
|
mutations.addEventToBus(storeState, event);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
//expect(storeState.applicationUser.eventBus).toEqual([event]);
|
||||||
|
expect(getters.eventBusItem(storeState)(event.category, event.subCategory)).toEqual(event.eventValue);
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(store.getters.eventBus.length).toBeGreaterThan(0);
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
it("Get event bus", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
storeState.applicationUser.eventBus = [];
|
||||||
|
|
||||||
|
const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.addEventToBus(storeState, event);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(getters.eventBus(storeState)).toEqual([event]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<button
|
<button :disabled="isDisabled" :aria-disabled="isDisabled" class="btn d-flex align-items-center py-3 px-4" :class="[isPrimary ? 'btn-primary' : 'btn-secondary',isFloat ? 'float-end' : '']" @click="clicked()">
|
||||||
:disabled="isDisabled"
|
|
||||||
:aria-disabled="isDisabled"
|
|
||||||
class="btn d-flex align-items-center py-3 px-4"
|
|
||||||
:class="isPrimary ? 'btn-primary' : 'btn-secondary'"
|
|
||||||
@click="clicked()"
|
|
||||||
>
|
|
||||||
<span class="m-0">{{ this.buttonText }}</span>
|
<span class="m-0">{{ this.buttonText }}</span>
|
||||||
<loader
|
<loader
|
||||||
class="ms-2"
|
class="ms-2"
|
||||||
|
|
@ -27,6 +21,7 @@ export default {
|
||||||
loaderColor: String,
|
loaderColor: String,
|
||||||
loaderPosition: String,
|
loaderPosition: String,
|
||||||
sizeInRem: [Number, String],
|
sizeInRem: [Number, String],
|
||||||
|
isFloat: Boolean
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -55,6 +50,7 @@ export default {
|
||||||
border-radius: $border-radius-lg;
|
border-radius: $border-radius-lg;
|
||||||
color: $white;
|
color: $white;
|
||||||
transition: all 150ms linear;
|
transition: all 150ms linear;
|
||||||
|
white-space: nowrap;
|
||||||
&:hover {
|
&:hover {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
270deg,
|
270deg,
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,44 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"
|
class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"
|
||||||
@mouseup="handleClick(value)"
|
@mouseup="handleClick(value)"
|
||||||
@keyup.space="handleClick(value)"
|
@keyup.space="handleClick(value)"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
:id="buttonID"
|
:id="buttonID"
|
||||||
:name="groupName"
|
:name="groupName"
|
||||||
:value="buttonID"
|
:value="buttonID"
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
:data-focus-target="groupName"
|
:data-focus-target="groupName"
|
||||||
|
v-model="checkValue"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
:for="buttonID"
|
:for="buttonID"
|
||||||
:aria-labelledby="buttonID"
|
:aria-labelledby="buttonID"
|
||||||
class="d-flex flex-column justify-content-center py-3 px-4"
|
class="d-flex flex-column justify-content-center py-3 px-4"
|
||||||
>
|
>
|
||||||
<span class="m-0" :class="textPosition">{{ buttonLabel }}</span>
|
<span
|
||||||
<span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">{{
|
class="m-0"
|
||||||
buttonLabelSubCopy
|
:class="textPosition"
|
||||||
}}</span>
|
>
|
||||||
<span v-if="screenReaderOnlyText" class="sr-only">{{
|
{{buttonLabel}}
|
||||||
screenReaderOnlyText
|
</span>
|
||||||
}}</span>
|
<span
|
||||||
<loader
|
v-if="buttonLabelSubCopy"
|
||||||
v-if="isLoaderDisplayed && !isMultiSelect"
|
class="m-0 small"
|
||||||
:style="{ width: `${sizeInRem}rem`, height: `${sizeInRem}rem` }"
|
:class="textPosition"
|
||||||
:class="[loaderColor, loaderPosition]"
|
>
|
||||||
|
{{buttonLabelSubCopy}}
|
||||||
|
</span>
|
||||||
|
<span v-if="screenReaderOnlyText" class="sr-only">
|
||||||
|
{{screenReaderOnlyText}}
|
||||||
|
</span>
|
||||||
|
<loader
|
||||||
|
v-if="isLoaderDisplayed && !isMultiSelect"
|
||||||
|
:style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}"
|
||||||
|
:class="[loaderColor, loaderPosition]"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -59,10 +69,12 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
|
modelValue: false,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoaderDisplayed: false,
|
isLoaderDisplayed: false,
|
||||||
|
checkValue: Boolean,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -76,6 +88,11 @@ export default {
|
||||||
this.handleChange(value);
|
this.handleChange(value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
checkValue(){
|
||||||
|
this.$emit('isChecked', {isChecked: this.checkValue, buttonId: this.buttonID});
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
loader,
|
loader,
|
||||||
},
|
},
|
||||||
|
|
@ -125,6 +142,7 @@ export default {
|
||||||
background: $white;
|
background: $white;
|
||||||
transition: all 150ms linear;
|
transition: all 150ms linear;
|
||||||
border: 1px solid $gray-500;
|
border: 1px solid $gray-500;
|
||||||
|
border-radius: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 0 0 4px $blue-100;
|
box-shadow: 0 0 0 4px $blue-100;
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,43 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="list-group list-button d-flex flex-column w-100 mb-2"
|
class="list-group list-button d-flex flex-column w-100 mb-2"
|
||||||
@mouseup="handleClick(value)"
|
@mouseup="handleClick(value)"
|
||||||
@keyup.space="handleClick(value)"
|
@keyup.space="handleClick(value)"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
:id="buttonID"
|
:id="buttonID"
|
||||||
:name="groupName"
|
:name="groupName"
|
||||||
:value="buttonID"
|
:value="buttonID"
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
:data-focus-target="groupName"
|
:data-focus-target="groupName"
|
||||||
/>
|
v-model="checkValue"
|
||||||
<label
|
>
|
||||||
tabindex="-1"
|
<label
|
||||||
:for="buttonID"
|
tabindex="-1"
|
||||||
:aria-labelledby="buttonID"
|
:for="buttonID"
|
||||||
|
:aria-labelledby="buttonID"
|
||||||
class="d-flex flex-column justify-content-center py-3 px-4"
|
class="d-flex flex-column justify-content-center py-3 px-4"
|
||||||
>
|
>
|
||||||
<span class="m-0" :class="textPosition">{{ buttonLabel }}</span>
|
<span
|
||||||
<span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">{{
|
class="m-0"
|
||||||
buttonLabelSubCopy
|
:class="textPosition"
|
||||||
}}</span>
|
>
|
||||||
<span v-if="screenReaderOnlyText" class="sr-only">{{
|
{{ buttonLabel }}
|
||||||
screenReaderOnlyText
|
</span>
|
||||||
}}</span>
|
<span
|
||||||
|
v-if="buttonLabelSubCopy"
|
||||||
|
class="m-0 small"
|
||||||
|
:class="textPosition"
|
||||||
|
>
|
||||||
|
{{ buttonLabelSubCopy }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-if="screenReaderOnlyText"
|
||||||
|
class="sr-only"
|
||||||
|
>
|
||||||
|
{{ screenReaderOnlyText }}
|
||||||
|
</span>
|
||||||
<loader
|
<loader
|
||||||
v-if="isLoaderDisplayed && !isMultiSelect"
|
v-if="isLoaderDisplayed && !isMultiSelect"
|
||||||
:style="{ width: `${sizeInRem}rem`, height: `${sizeInRem}rem` }"
|
:style="{ width: `${sizeInRem}rem`, height: `${sizeInRem}rem` }"
|
||||||
|
|
@ -52,18 +65,23 @@ export default {
|
||||||
loaderEnabled: Boolean,
|
loaderEnabled: Boolean,
|
||||||
loaderColor: String,
|
loaderColor: String,
|
||||||
loaderPosition: String,
|
loaderPosition: String,
|
||||||
sizeInRem: [Number, String],
|
sizeInRem: [Number,String],
|
||||||
value: {
|
value: {
|
||||||
// Field initial value
|
// Field initial value
|
||||||
type: String,
|
type: [String, Number],
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
|
modelValue: [Array, String],
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoaderDisplayed: false,
|
isLoaderDisplayed: false,
|
||||||
|
checkValue: Boolean,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
created(){
|
||||||
|
this.checkValue = this.modelValue ? this.modelValue.includes(this.buttonID) : false;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
displayLoader() {
|
displayLoader() {
|
||||||
this.isLoaderDisplayed = true;
|
this.isLoaderDisplayed = true;
|
||||||
|
|
@ -75,6 +93,11 @@ export default {
|
||||||
this.handleChange(value);
|
this.handleChange(value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
checkValue(){
|
||||||
|
this.$emit('isChecked', {isChecked: this.checkValue, buttonId: this.buttonID});
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
loader,
|
loader,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ describe("list-card.vue", () => {
|
||||||
groupID: "checkbox-demo-1",
|
groupID: "checkbox-demo-1",
|
||||||
groupName: "Checkbox 1",
|
groupName: "Checkbox 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -31,6 +32,7 @@ describe("list-card.vue", () => {
|
||||||
groupID: "radio-demo-1",
|
groupID: "radio-demo-1",
|
||||||
groupName: "radio 1",
|
groupName: "radio 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -51,6 +53,7 @@ describe("list-card.vue", () => {
|
||||||
groupName: "radio 1",
|
groupName: "radio 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
buttonLabelSubCopy: "Test",
|
buttonLabelSubCopy: "Test",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -71,6 +74,7 @@ describe("list-card.vue", () => {
|
||||||
groupName: "radio 1",
|
groupName: "radio 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
buttonLabelSubCopy: "Test",
|
buttonLabelSubCopy: "Test",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -91,6 +95,7 @@ describe("list-card.vue", () => {
|
||||||
groupName: "radio 1",
|
groupName: "radio 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
buttonLabelSubCopy: "Test",
|
buttonLabelSubCopy: "Test",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -111,6 +116,7 @@ describe("list-card.vue", () => {
|
||||||
groupName: "radio 1",
|
groupName: "radio 1",
|
||||||
buttonImage: "windshield-damage.svg",
|
buttonImage: "windshield-damage.svg",
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -119,4 +125,70 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
expect(input.attributes()["aria-required"]).toEqual("true");
|
expect(input.attributes()["aria-required"]).toEqual("true");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should return flex row classes if isWide is true", async () => {
|
||||||
|
// 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",
|
||||||
|
isRequired: true,
|
||||||
|
isWide: true,
|
||||||
|
buttonLabelSubCopy: "",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const label = wrapper.find("label");
|
||||||
|
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-r", "ps-3", "pe-8"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is true", async () => {
|
||||||
|
// 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",
|
||||||
|
isRequired: true,
|
||||||
|
isWide: true,
|
||||||
|
buttonLabelSubCopy: "Button Subcopy",
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const label = wrapper.find("label");
|
||||||
|
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-r", "ps-3", "pe-8", "checkboxTop"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return flex column classes if isWide is false", async () => {
|
||||||
|
// 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",
|
||||||
|
isRequired: true,
|
||||||
|
isWide: false,
|
||||||
|
modelValue: ["List Card Checkbox"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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-2"]);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,38 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Heavily documented below -->
|
<div :class="'col' + colLength">
|
||||||
<div class="col">
|
<div class="list-card w-100 rounded-3 d-flex align-items-center h-100"
|
||||||
<div
|
:class="isWide ? 'horizontal' : ''"
|
||||||
class="list-card w-100 rounded-3 d-flex align-items-center h-100"
|
@mouseup="handleChange(value)"
|
||||||
:class="isWide ? 'horizontal' : ''"
|
@keyup.space="handleChange(value)">
|
||||||
@mouseup="handleClick(value)"
|
<input
|
||||||
@keyup.space="handleClick(value)"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
>
|
:id="buttonID"
|
||||||
<input
|
:name="groupName"
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:value="buttonID"
|
||||||
:id="buttonID"
|
:aria-required="isRequired"
|
||||||
:name="groupName"
|
:data-focus-target="groupName"
|
||||||
:value="buttonID"
|
v-model="checkValue"
|
||||||
:aria-required="isRequired"
|
/>
|
||||||
:data-focus-target="groupName"
|
<label
|
||||||
/>
|
:for="buttonID"
|
||||||
<label
|
class="d-flex w-100 align-items-center px-2 h-100"
|
||||||
:for="buttonID"
|
:class="getLabelClasses" tabindex="-1"
|
||||||
class="d-flex w-100 align-items-center px-2 h-100"
|
|
||||||
:class="getLabelClasses"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:id="buttonImageId"
|
:id="buttonImageId"
|
||||||
:class="!isWide ? 'order-1' : 'ms-auto order-3'"
|
:class="!isWide ? 'order-1' : 'ms-auto order-3'"
|
||||||
v-bind:src="require(`@/assets/img/icons/${buttonImage}`)"
|
:src="buttonImage"
|
||||||
:alt="altText"
|
:alt="altText"
|
||||||
/>
|
/>
|
||||||
<p
|
<p
|
||||||
v-if="!isWide"
|
v-if="!isWide"
|
||||||
class="small order-3"
|
class="small order-3"
|
||||||
:class="isMultiSelect ? 'm-0' : 'mt-2 mb-0'"
|
:class="isMultiSelect ? 'm-0' : 'mt-2 mb-0'"
|
||||||
>
|
>
|
||||||
{{ buttonLabel }}
|
{{buttonLabel}}
|
||||||
</p>
|
</p>
|
||||||
<p v-if="buttonLabelSubCopy && !isWide" class="fs-7 m-0 order-4">
|
<p v-if="buttonLabelSubCopy && !isWide" class="fs-7 m-0 order-4">
|
||||||
{{ buttonLabelSubCopy }}
|
{{buttonLabelSubCopy}}
|
||||||
</p>
|
</p>
|
||||||
<div v-if="isWide" class="order-2">
|
<div v-if="isWide" class="order-2">
|
||||||
<p class="m-0 small">{{ buttonLabel }}</p>
|
<p class="m-0 small">{{ buttonLabel }}</p>
|
||||||
|
|
@ -72,6 +69,16 @@ export default {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
|
colLength: String,
|
||||||
|
modelValue: [Array, String],
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
checkValue: Boolean,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
this.checkValue = this.modelValue.includes(this.buttonID);
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
getLabelClasses() {
|
getLabelClasses() {
|
||||||
|
|
@ -86,6 +93,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
checkValue(){
|
||||||
|
this.$emit('isChecked', {isChecked: this.checkValue, buttonId: this.buttonID});
|
||||||
|
}
|
||||||
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { groupName, value } = toRefs(props);
|
const { groupName, value } = toRefs(props);
|
||||||
const inputType = props.isMultiSelect ? "checkbox" : "radio";
|
const inputType = props.isMultiSelect ? "checkbox" : "radio";
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- Navigation Text Link -->
|
<a v-if="navigation" @click="handleClick" class="navigation-link" :href="href">{{text}}</a>
|
||||||
<a
|
<a v-else-if="footer" @click="handleClick" class="footer-link" :href="href" target="_blank">{{text}}</a>
|
||||||
v-if="navigation"
|
<a v-else-if="textSmall" @click="handleClick" class="small" :href="href">{{text}}</a>
|
||||||
@click="handleClick"
|
<a v-else @click="handleClick" :href="href">{{text}}</a>
|
||||||
class="navigation-link"
|
|
||||||
:href="href"
|
|
||||||
>{{ text }}</a
|
|
||||||
>
|
|
||||||
<!-- Footer Text Link -->
|
|
||||||
<a
|
|
||||||
v-else-if="footer"
|
|
||||||
@click="handleClick"
|
|
||||||
class="footer-link"
|
|
||||||
:href="href"
|
|
||||||
target="_blank"
|
|
||||||
>{{ text }}</a
|
|
||||||
>
|
|
||||||
<!-- Small Text Link -->
|
|
||||||
<a v-else-if="textSmall" @click="handleClick" class="small" :href="href">{{
|
|
||||||
text
|
|
||||||
}}</a>
|
|
||||||
<!-- Default Text Link -->
|
|
||||||
<a v-else @click="handleClick" :href="href">{{ text }}</a>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -66,9 +47,12 @@ a {
|
||||||
color: $black;
|
color: $black;
|
||||||
border-bottom: 1px solid $black;
|
border-bottom: 1px solid $black;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
|
display: inline-flex;
|
||||||
|
text-transform: capitalize;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
&.footer-link {
|
&.footer-link {
|
||||||
color: $gray-500;
|
color: $gray-600;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue