CSR-296: create/clean up unit tests

This commit is contained in:
Adam Caouette 2022-02-22 13:11:46 -05:00
parent 51660aa968
commit b14f2c7359
5 changed files with 216 additions and 90 deletions

View file

@ -1,76 +1,128 @@
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from "@vue/test-utils";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question"; import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import store from "@/store"; import store from "@/store";
jest.mock("@/store", () => { return {}; }, {virtual: true}); jest.mock("@/store", () => { return {}; }, {virtual: true});
describe("replace-options-question.vue", () => { describe("replace-options-question.vue", () => {
test("Selected damage option is emitted upon selection.", async () => { 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", () => { //Arrange
test("Answers to display filtered by data from api.", async () => { const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
const damageToSelect = ["Backseat"];
//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: 'car-Windshield' }, { Name: 'car-FrontDoor' } ])
});
});
function setupMocks({ //Act
modelValueProp = ["Windshield"], wrapper.setValue({ modelValue: damageToSelect });
isAvailale = true, await wrapper.vm.$nextTick();
isMultiSelect = false,
filterByVehicleCategory = false, //Assert
groupName = "damageQuestion", expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
cmsQuestionText = "CMS text goes here", });
cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-BackDoor"}, {Name: "car-FrontDoor"}], });
dataFromStoreApi = [],
}) { describe("replace-options-question.vue", () => {
test("Answers to display filtered by data from api.", async () => {
//Mock store
store.dispatch = jest.fn(() => dataFromStoreApi); //Arrange
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} }; const { wrapper, cmsContent, replaceOptions } = setupMocks({ dataFromStoreApi: ["Windshield", "FrontDoor"], filterByVehicleCategory: true});
const mountOptions = getMountOptions({
store: { //Act
dispatch: store.dispatch, replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
getters: store.getters,
//Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-FrontDoor' } ])
});
});
describe("replace-options-question.vue", () => {
test("when updateSelectedValues method is called with a single answerToDisplay it will 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);
//Assert
expect(wrapper.vm.selectedValues).toStrictEqual(['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 //Mock store
mountOptions.propsData = { store.dispatch = jest.fn(() => dataFromStoreApi);
modelValue: modelValueProp, store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
isAvailable: isAvailale, const mountOptions = getMountOptions({
isMultiSelect: isMultiSelect, store: {
filterByVehicleCategory: filterByVehicleCategory dispatch: store.dispatch,
}; getters: store.getters,
},
const wrapper = shallowMount(replaceOptionsQuestion, mountOptions); });
//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 wrapper = shallowMount(replaceOptionsQuestion, mountOptions);
const cmsContent = {
groupName: groupName, //Mock CMS content
QuestionText: cmsQuestionText, const cmsContent = {
Answers: cmsAnswers, groupName: groupName,
}; QuestionText: cmsQuestionText,
const replaceOptions = dataFromStoreApi; Answers: cmsAnswers,
return { wrapper, cmsContent, replaceOptions }; };
} const replaceOptions = dataFromStoreApi;
return { wrapper, cmsContent, replaceOptions };
}

View file

@ -1,6 +1,6 @@
<template> <template>
<transition name="fade"> <transition name="fade">
<div class="replace-options-question" :class="this.answersToDisplay.length < 2 ? 'd-noneXXX' : ''"> <div class="replace-options-question">
<buttonQuestion <buttonQuestion
v-if="isAvailable && answersToDisplay.length > 0" v-if="isAvailable && answersToDisplay.length > 0"
isWide isWide
@ -51,6 +51,15 @@ export default ({
this.answersFromCms = cmsContent.Answers; this.answersFromCms = cmsContent.Answers;
this.replaceOptions = replaceOptions; this.replaceOptions = replaceOptions;
}, },
updateSelectedValues() {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
const newSelectedValues = this.selectedValues;
newSelectedValues.push(this.answersToDisplay[0].Name);
console.log('YES, ONLY ONE, newSelectedValues: ', newSelectedValues)
this.selectedValues = newSelectedValues;
}
},
}, },
computed: { computed: {
selectedValues: { selectedValues: {
@ -71,12 +80,11 @@ export default ({
: []; : [];
}, },
}, },
mounted(){ watch: {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER isAvailable(val) {
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) { console.log('CHANGE DETECTED in isAvailable, val: ', val)
const newSelectedValues = this.selectedValues; // CHECK TO UPDATE SELECTED VALUES WHEN ISAVAILABLE IS TRUE
newSelectedValues.push(this.answersToDisplay[0].Name); val && this.updateSelectedValues();
this.selectedValues = newSelectedValues;
} }
}, },
components: { components: {

View file

@ -165,22 +165,61 @@ 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 = ["Car-RearWindow"];
//Assert
expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true);
});
});
function setupMocks({ function setupMocks({
pageHeaderWidgetHeaderText = {}, pageHeaderWidgetHeaderText = {},
mountOptionsMockData = {}, mountOptionsMockData = {
router: {
navigate: jest.fn(),
},
},
}) { }) {
//Mock api responses //Mock api responses
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation(() => {
return Promise.resolve({
driverSideOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
windshieldOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
});
});
const apiResponses = { const apiResponses = {
cmsContent: { cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
@ -199,7 +238,10 @@ function setupMocks({
}, },
windshieldOptions: { windshieldOptions: {
availableReplacementOptions: ["Front", "Back", "Side"], availableReplacementOptions: ["Front", "Back", "Side"],
} },
backGlassOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
}, },
}; };
@ -268,6 +310,12 @@ function setupMocks({
windshieldOptionsWrapper.vm.initializeComponent = windshieldOptionsWrapper.vm.initializeComponent =
replaceOptionsQuestion.methods.initializeComponent; replaceOptionsQuestion.methods.initializeComponent;
const backGlassOptionsWrapper = wrapper.findAllComponents({
name: "replaceOptionsQuestion",
}).at(2);
backGlassOptionsWrapper.vm.initializeComponent =
replaceOptionsQuestion.methods.initializeComponent;
const damageLocationQuestionWrapper = wrapper.findComponent({ const damageLocationQuestionWrapper = wrapper.findComponent({
name: "damageLocationQuestion", name: "damageLocationQuestion",
}); });

View file

@ -23,7 +23,7 @@
/> />
<replaceOptionsQuestion <replaceOptionsQuestion
ref="backGlassOptions" ref="backGlassOptions"
isAvailable :isAvailable="isRearWindowDamageLocation"
v-model="selectedRearReplaceOptions" v-model="selectedRearReplaceOptions"
groupName="BackGlassReplaceOptionsQuestion" groupName="BackGlassReplaceOptionsQuestion"
/> />
@ -101,6 +101,20 @@ export default {
); );
}); });
}, },
computed: {
isRearWindowDamageLocation() {
if (this.selectedDamageLocations) {
const myTest = this.selectedDamageLocations.some(selectedDamages =>
{
const categoryAndGlass = selectedDamages.split('-'); //ie: "Suv-Windshield" Splits the answers into [0]"Suv" [1]"Windshield"
return Boolean(categoryAndGlass[1].toUpperCase() === "REARWINDOW");
});
return myTest;
} else {
return false;
}
},
},
data(){ data(){
return { return {
selectedDamageLocations: [], selectedDamageLocations: [],

View file

@ -85,12 +85,16 @@ export default {
return "flex-column pt-4 pb-2"; return "flex-column pt-4 pb-2";
} }
}, },
checkValue() { },
if(this.selectedButtonIDs){ data(){
return this.isMultiSelect ? this.selectedButtonIDs.includes(this.buttonID) : this.selectedButtonIDs[0]; return {
} checkValue: Boolean,
return false; }
}, },
created(){
if(this.selectedButtonIDs){
this.checkValue = this.isMultiSelect ? this.selectedButtonIDs.includes(this.buttonID) : this.selectedButtonIDs[0];
}
}, },
methods: { methods: {
handleCheckChange(newValue, oldValue){ handleCheckChange(newValue, oldValue){