Merge branch 'develop' into feature/CSR-297
This commit is contained in:
commit
b0d17ffad5
12 changed files with 593 additions and 83 deletions
|
|
@ -4,7 +4,7 @@
|
|||
<span class="text-center fs-6 fw-bold w-100">{{ questionText }}</span>
|
||||
</div>
|
||||
<div class="w-100 d-flex justify-content-center">
|
||||
<fieldset class="w-100" :class="getFieldSetClasses" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
|
||||
<fieldset class="w-100" :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
|
||||
<legend class="sr-only">{{groupName}}</legend>
|
||||
<div :class="getComponentWrapperClasses">
|
||||
<component
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
import { shallowMount } from "@vue/test-utils";
|
||||
import dropdownQuestion from "./dropdown-question";
|
||||
import { nextTick } from "vue";
|
||||
|
||||
describe("dropdownQuestion.vue", () => {
|
||||
|
||||
it("Should return aria-disabled state", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(dropdownQuestion, {
|
||||
propsData: {
|
||||
isDisabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("select");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes()["aria-disabled"]).toEqual("true");
|
||||
});
|
||||
|
||||
it("Should render a text input", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(dropdownQuestion, {
|
||||
propsData: {
|
||||
name: "test",
|
||||
label: "unit test label",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("select");
|
||||
|
||||
expect(input.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it("Should return input id", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(dropdownQuestion, {
|
||||
propsData: {
|
||||
inputId: "input ID",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("select");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes().id).toEqual("input ID");
|
||||
});
|
||||
|
||||
it("Should return label text", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(dropdownQuestion, {
|
||||
propsData: {
|
||||
labelText: "label text",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const label = wrapper.find("label");
|
||||
|
||||
expect(label.text()).toEqual("label text");
|
||||
});
|
||||
|
||||
it("Should return input id", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(dropdownQuestion, {
|
||||
propsData: {
|
||||
inputId: "input ID",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("select");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes().id).toEqual("input ID");
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<div class="dropdown-question">
|
||||
<label :for="inputId" class="form-label">{{labelText}}</label>
|
||||
<select class="form-select" aria-label="Default select example" :id="inputId" :aria-disabled="isDisabled" :disabled="isDisabled" :aria-required="isRequired">
|
||||
<option selected>Placeholder</option>
|
||||
<option value="1">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<p class="mt-1 mb-0">There has been an error!</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "dropdownQuestion",
|
||||
props: {
|
||||
isDisabled: Boolean,
|
||||
modelValue: String,
|
||||
labelText: String,
|
||||
inputId: String,
|
||||
isRequired: Boolean,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.dropdown-question {
|
||||
.form-label {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
.form-select {
|
||||
color: $gray-500;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8.89' xml:space='preserve'%3e%3cpath d='M8 8.89c-.24 0-.46-.09-.63-.26L.26 1.53a.901.901 0 0 1 0-1.27C.43.1.66 0 .9 0s.47.1.64.26L8 6.74 14.47.27c.17-.17.4-.27.64-.27s.47.1.63.27c.17.17.26.4.26.64s-.1.47-.27.63l-7.1 7.09a.86.86 0 0 1-.63.26z' fill='%231474a2'/%3e%3c/svg%3e");
|
||||
border: 1px solid $gray-500;
|
||||
border-radius: .5rem;
|
||||
min-height: 3rem;
|
||||
option[selected] {
|
||||
color: $gray-500;
|
||||
background-color: red;
|
||||
}
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
box-shadow: 0 0 0 2px $blue;
|
||||
}
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
background-color: $gray-100;
|
||||
filter: grayscale(100%);
|
||||
&:hover {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
border: 1px solid $gray-500;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 0 0 4px $blue-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import { shallowMount } from "@vue/test-utils";
|
||||
import textboxQuestion from "./textbox-question";
|
||||
import { nextTick } from "vue";
|
||||
|
||||
describe("textboxQuestion.vue", () => {
|
||||
|
||||
it("Should return aria-disabled state", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
propsData: {
|
||||
isDisabled: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("input");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes()["aria-disabled"]).toEqual("true");
|
||||
});
|
||||
|
||||
it("Should render a text input", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
propsData: {
|
||||
name: "test",
|
||||
label: "unit test label",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("input");
|
||||
|
||||
expect(input.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it("Should return input id", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
propsData: {
|
||||
inputId: "input ID",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("input");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes().id).toEqual("input ID");
|
||||
});
|
||||
|
||||
it("Should return label text", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
propsData: {
|
||||
labelText: "label text",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const label = wrapper.find("label");
|
||||
|
||||
expect(label.text()).toEqual("label text");
|
||||
});
|
||||
|
||||
it("Should return input id", async () => {
|
||||
// Act
|
||||
const wrapper = shallowMount(textboxQuestion, {
|
||||
propsData: {
|
||||
inputId: "input ID",
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
const input = wrapper.find("input");
|
||||
|
||||
// Expect
|
||||
expect(input.attributes().id).toEqual("input ID");
|
||||
});
|
||||
|
||||
});
|
||||
52
src/common-components/textbox-question/textbox-question.vue
Normal file
52
src/common-components/textbox-question/textbox-question.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<template>
|
||||
<div class="textbox-question">
|
||||
<label :for="inputId" class="form-label">{{labelText}}</label>
|
||||
<input type="text" class="form-control" :id="inputId" :placeholder="placeholderText" :aria-disabled="isDisabled" :disabled="isDisabled" :aria-required="isRequired">
|
||||
<p class="mt-1 mb-0">There has been an error!</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "textboxQuestion",
|
||||
props: {
|
||||
isDisabled: Boolean,
|
||||
modelValue: String,
|
||||
labelText: String,
|
||||
placeholderText: String,
|
||||
inputId: String,
|
||||
isRequired: Boolean,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.textbox-question {
|
||||
.form-label {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
.form-control {
|
||||
border: 1px solid $gray-500;
|
||||
border-radius: .5rem;
|
||||
min-height: 3rem;
|
||||
&::placeholder {
|
||||
color: $gray-500;
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 2px $blue;
|
||||
}
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
background-color: $gray-100;
|
||||
&:hover {
|
||||
box-shadow: 0 0 0 4px transparent;
|
||||
border: 1px solid $gray-500;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border: 1px solid transparent;
|
||||
box-shadow: 0 0 0 4px $blue-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +1,74 @@
|
|||
<template>
|
||||
<div class="container-fluid container-shadow p-2 rounded-3">
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Text Input</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
labelText="Text Input Label"
|
||||
placeholderText="Placeholder"
|
||||
inputID="test-text-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h6 class="my-4">Disabled</h6>
|
||||
<textboxQuestion
|
||||
labelText="Text Input Label"
|
||||
placeholderText="Disabled"
|
||||
inputID="test-text-input"
|
||||
isDisabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h6 class="my-4">With Error (class="has-error"):</h6>
|
||||
<textboxQuestion
|
||||
labelText="Text Input Label"
|
||||
placeholderText="Placeholder"
|
||||
inputID="test-text-input"
|
||||
class="has-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Dropdown Input (Select)</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<dropdownQuestion
|
||||
labelText="Dropdown Label"
|
||||
inputID="test-dropdown-input-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h6 class="my-4">Disabled</h6>
|
||||
<dropdownQuestion
|
||||
labelText="Dropdown Label"
|
||||
inputID="test-dropdown-input-2"
|
||||
isDisabled
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h6 class="my-4">With Error (class="has-error"):</h6>
|
||||
<dropdownQuestion
|
||||
labelText="Dropdown Label"
|
||||
inputID="test-dropdown-input-3"
|
||||
class="has-error"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
<h4 class="m-0 p-2 bg-light rounded">Checkbox</h4>
|
||||
|
|
@ -1040,6 +1109,8 @@
|
|||
import checkbox from "@/ux-components/checkbox/checkbox";
|
||||
import radio from "@/ux-components/radio/radio";
|
||||
import textLink from "@/ux-components/text-link/text-link";
|
||||
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
||||
import dropdownQuestion from "@/common-components/dropdown-question/dropdown-question";
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
|
|
@ -1051,7 +1122,9 @@
|
|||
listButtonHorizontal,
|
||||
checkbox,
|
||||
radio,
|
||||
textLink
|
||||
textLink,
|
||||
textboxQuestion,
|
||||
dropdownQuestion,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,76 +1,124 @@
|
|||
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 { nextTick } from "vue";
|
||||
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"]}]);
|
||||
});
|
||||
});
|
||||
test("Selected damage option is emitted upon selection.", async () => {
|
||||
|
||||
describe("replace-options-question.vue", () => {
|
||||
test("Answers to display filtered by data from api.", async () => {
|
||||
|
||||
//Arrange
|
||||
const { wrapper, cmsContent, replaceOptions } = setupMocks({ dataFromStoreApi: ["Windshield", "FrontDoor"], filterByVehicleCategory: true});
|
||||
|
||||
//Act
|
||||
replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'FrontDoor' } ])
|
||||
});
|
||||
});
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
|
||||
const damageToSelect = ["Backseat"];
|
||||
|
||||
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,
|
||||
//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"], filterByVehicleCategory: true});
|
||||
|
||||
//Act
|
||||
replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'FrontDoor' } ])
|
||||
});
|
||||
});
|
||||
|
||||
describe("replace-options-question.vue", () => {
|
||||
test("when updateSelectedValues method is called with a single answerToDisplay it will call to update this.selectedValues", async () => {
|
||||
|
||||
//Arrange
|
||||
const { wrapper, cmsContent, replaceOptions
|
||||
} = setupMocks({
|
||||
modelValueProp: [],
|
||||
});
|
||||
wrapper.setData({answersFromCms: [
|
||||
{
|
||||
"Name": "Stationary",
|
||||
},
|
||||
});
|
||||
{
|
||||
"Name": "Slider",
|
||||
}
|
||||
]});
|
||||
wrapper.setData({replaceOptions: ["Stationary"]});
|
||||
|
||||
//Act
|
||||
wrapper.vm.$options.methods.updateSelectedValues.call(wrapper.vm);
|
||||
|
||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([['Stationary']]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("replace-options-question.vue", () => {
|
||||
test("when isAvailable is true, will run updateSelectedValues method", async () => {
|
||||
|
||||
//Arrange
|
||||
const { wrapper, cmsContent, replaceOptions } = setupMocks({ isAvailable: false, methodsToMock: ["updateSelectedValues"] });
|
||||
|
||||
//Act
|
||||
wrapper.vm.$options.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
|
||||
wrapper.vm.$options.watch.isAvailable.call(wrapper.vm, true);
|
||||
|
||||
//Assert
|
||||
expect(replaceOptionsQuestion.methods.updateSelectedValues).toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({
|
||||
modelValueProp = ["Windshield"],
|
||||
isAvailable = true,
|
||||
isMultiSelect = false,
|
||||
filterByVehicleCategory = false,
|
||||
groupName = "damageQuestion",
|
||||
cmsQuestionText = "CMS text goes here",
|
||||
cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-BackDoor"}, {Name: "car-FrontDoor"}],
|
||||
dataFromStoreApi = [],
|
||||
methodsToMock = [],
|
||||
}) {
|
||||
|
||||
//Mock props
|
||||
mountOptions.propsData = {
|
||||
modelValue: modelValueProp,
|
||||
isAvailable: isAvailale,
|
||||
isMultiSelect: isMultiSelect,
|
||||
filterByVehicleCategory: filterByVehicleCategory
|
||||
};
|
||||
|
||||
const wrapper = shallowMount(replaceOptionsQuestion, mountOptions);
|
||||
//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: isAvailable,
|
||||
isMultiSelect: isMultiSelect,
|
||||
filterByVehicleCategory: filterByVehicleCategory
|
||||
};
|
||||
|
||||
//Mock methods
|
||||
methodsToMock.forEach((methodName) => {
|
||||
replaceOptionsQuestion.methods[methodName] = jest.fn();
|
||||
});
|
||||
|
||||
//Mock CMS content
|
||||
const cmsContent = {
|
||||
groupName: groupName,
|
||||
QuestionText: cmsQuestionText,
|
||||
Answers: cmsAnswers,
|
||||
};
|
||||
const replaceOptions = dataFromStoreApi;
|
||||
return { wrapper, cmsContent, replaceOptions };
|
||||
}
|
||||
const wrapper = shallowMount(replaceOptionsQuestion, mountOptions);
|
||||
|
||||
//Mock CMS content
|
||||
const cmsContent = {
|
||||
groupName: groupName,
|
||||
QuestionText: cmsQuestionText,
|
||||
Answers: cmsAnswers,
|
||||
};
|
||||
const replaceOptions = dataFromStoreApi;
|
||||
return { wrapper, cmsContent, replaceOptions };
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<transition name="fade" mode="out-in">
|
||||
<div v-if="isAvailable && this.answersToDisplay.length > 0" class="replace-options-question" :class="this.answersToDisplay.length < 2 ? 'd-none' : ''" aria-live="polite">
|
||||
<div v-if="isAvailable && this.answersToDisplay.length > 0" class="replace-options-question" aria-live="polite">
|
||||
<buttonQuestion
|
||||
isWide
|
||||
:questionText="questionText"
|
||||
isMultiSelect
|
||||
:isMultiSelect="isMultiSelect"
|
||||
:answers="answersToDisplay"
|
||||
:groupName="groupName"
|
||||
buttonType="listCard"
|
||||
|
|
@ -42,6 +42,7 @@ export default ({
|
|||
filterByVehicleCategory: Boolean,
|
||||
groupName: String,
|
||||
modelValue: Array,
|
||||
isMultiSelect: Boolean,
|
||||
},
|
||||
methods: {
|
||||
initializeComponent(cmsContent, replaceOptions){
|
||||
|
|
@ -49,6 +50,12 @@ export default ({
|
|||
this.answersFromCms = cmsContent.Answers;
|
||||
this.replaceOptions = replaceOptions;
|
||||
},
|
||||
updateSelectedValues() {
|
||||
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
|
||||
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {
|
||||
this.selectedValues = [this.answersToDisplay[0].Name];
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
selectedValues: {
|
||||
|
|
@ -75,11 +82,10 @@ export default ({
|
|||
});
|
||||
},
|
||||
},
|
||||
mounted(){
|
||||
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {
|
||||
const newSelectedValues = this.selectedValues;
|
||||
newSelectedValues.push(this.answersToDisplay[0].Name);
|
||||
this.selectedValues = newSelectedValues;
|
||||
watch: {
|
||||
isAvailable(val) {
|
||||
// CHECK TO UPDATE SELECTED VALUES WHEN ISAVAILABLE IS TRUE
|
||||
val && this.updateSelectedValues();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
|||
import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options";
|
||||
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
|
||||
import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options";
|
||||
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
|
||||
|
||||
// Supporting Files
|
||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||
|
|
@ -166,9 +167,57 @@ describe("vehicle-damage.vue", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("vehicle-damage.vue", () => {
|
||||
test("BackButtonAction triggers a router.navigate change", async () => {
|
||||
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
//Act
|
||||
vehicleDamage.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "vehicle-damage" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
wrapper.vm.backButtonAction();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("vehicle-damage.vue", () => {
|
||||
test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => {
|
||||
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
//Act
|
||||
vehicleDamage.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "vehicle-damage" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
wrapper.vm.selectedDamageLocations = ["RearWindow"];
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({
|
||||
pageHeaderWidgetHeaderText = {},
|
||||
mountOptionsMockData = {},
|
||||
mountOptionsMockData = {
|
||||
router: {
|
||||
navigate: jest.fn(),
|
||||
},
|
||||
},
|
||||
}) {
|
||||
//Mock api responses
|
||||
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
|
||||
|
|
@ -194,6 +243,9 @@ function setupMocks({
|
|||
windshieldOptions: {
|
||||
availableReplacementOptions: ["Single", "Driver", "Passenger"],
|
||||
},
|
||||
backGlassOptions: {
|
||||
availableReplacementOptions: ["Front", "Back", "Side"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -227,6 +279,10 @@ function setupMocks({
|
|||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
replaceOptionsQuestion.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
funnelFooter.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
}
|
||||
|
|
@ -259,6 +315,12 @@ function setupMocks({
|
|||
funnelSubHeaderWrapper.vm.initializeComponent =
|
||||
funnelSubHeader.methods.initializeComponent;
|
||||
|
||||
const backGlassOptionsWrapper = wrapper.findComponent({
|
||||
name: "replaceOptionsQuestion",
|
||||
});
|
||||
backGlassOptionsWrapper.vm.initializeComponent =
|
||||
replaceOptionsQuestion.methods.initializeComponent;
|
||||
|
||||
const damageLocationQuestionWrapper = wrapper.findComponent({
|
||||
name: "damageLocationQuestion",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,12 +3,28 @@
|
|||
<funnelHeader ref="funnelHeader" />
|
||||
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
|
||||
<funnelSubHeader ref="funnelSubHeader" />
|
||||
<damageLocationQuestion ref="damageLocation" v-model="selectedDamageLocations" groupName="DamageLocationQuestion" />
|
||||
<windshieldOptions ref="windshieldOptions"
|
||||
<damageLocationQuestion
|
||||
ref="damageLocation"
|
||||
v-model="selectedDamageLocations"
|
||||
groupName="DamageLocationQuestion"
|
||||
/>
|
||||
<windshieldOptions
|
||||
ref="windshieldOptions"
|
||||
v-model="selectedWindshieldOptions"
|
||||
:selectedDamageLocations="selectedDamageLocations"
|
||||
/>
|
||||
<sideDoorOptions ref="sideDoorOptions" groupName="SideDoorSideQuestion" v-model="sideDoorOptionsData" :selectedDamageLocations="selectedDamageLocations" />
|
||||
<sideDoorOptions
|
||||
ref="sideDoorOptions"
|
||||
groupName="SideDoorSideQuestion"
|
||||
v-model="sideDoorOptionsData"
|
||||
:selectedDamageLocations="selectedDamageLocations"
|
||||
/>
|
||||
<replaceOptionsQuestion
|
||||
ref="backGlassOptions"
|
||||
:isAvailable="isRearWindowDamageLocation"
|
||||
v-model="selectedRearReplaceOptions"
|
||||
groupName="BackGlassReplaceOptionsQuestion"
|
||||
/>
|
||||
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -22,6 +38,7 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
|
|||
import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options";
|
||||
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
|
||||
import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options";
|
||||
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
|
||||
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
|
|
@ -77,11 +94,22 @@ export default {
|
|||
resultMap.cmsContent.WindshieldDamageTypeQuestion, resultMap.cmsContent.WindshieldChipCountQuestion,
|
||||
resultMap.cmsContent.WindshieldReplaceOptionsQuestion, resultMap.damageOptions.windshieldOptions.availableReplacementOptions
|
||||
);
|
||||
vm.$refs.backGlassOptions.initializeComponent(
|
||||
resultMap.cmsContent.RearReplaceOptionsQuestion, resultMap.damageOptions.backGlassOptions.availableReplacementOptions
|
||||
);
|
||||
vm.$refs.funnelFooter.initializeComponent(
|
||||
resultMap.cmsContent.FunnelFooterWidget
|
||||
);
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
isRearWindowDamageLocation() {
|
||||
return this.selectedDamageLocations.some(selectedDamages =>
|
||||
{
|
||||
return selectedDamages.toUpperCase() === "REARWINDOW";
|
||||
});
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
selectedDamageLocations: [],
|
||||
|
|
@ -90,7 +118,8 @@ export default {
|
|||
selectedDriverSideReplacOptions: [],
|
||||
selectedPassengerSideReplaceOptions: []
|
||||
},
|
||||
selectedWindshieldOptions: []
|
||||
selectedWindshieldOptions: [],
|
||||
selectedRearReplaceOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -117,6 +146,7 @@ export default {
|
|||
sideDoorOptions,
|
||||
damageLocationQuestion,
|
||||
windshieldOptions,
|
||||
replaceOptionsQuestion,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
.fade-enter-active{
|
||||
transition: opacity 0.6s ease;
|
||||
}
|
||||
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
.has-error {
|
||||
&.list-button,
|
||||
&.list-card {
|
||||
border: 1px solid transparent;
|
||||
border: 1px solid $red;
|
||||
color: $red;
|
||||
label {
|
||||
border: 1px solid $red;
|
||||
box-shadow: 0 0 1px $red;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,19 @@
|
|||
border: 1px solid $blue;
|
||||
}
|
||||
}
|
||||
&.textbox-question,
|
||||
&.dropdown-question {
|
||||
p {
|
||||
color: $red;
|
||||
}
|
||||
input,
|
||||
select {
|
||||
border: 1px solid $red;
|
||||
&:focus {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-test-error {
|
||||
|
|
|
|||
Loading…
Reference in a new issue