Merge branch 'develop' into feature/v-model_refactoring

This commit is contained in:
Max 2022-02-03 12:42:46 -05:00
commit 2db0567072
15 changed files with 227 additions and 40 deletions

View file

@ -1,9 +1,7 @@
<template> <template>
<div class="current_car_info-text"> <div class="current_car_info-text">
<div <div class="d-flex align-items-center justify-content-center container-fluid overflow-hidden">
class="d-flex align-items-center justify-content-center container-fluid overflow-hidden" <h5 class="text-center fw-normal mb-0" :class="hasSubText ? 'dark-header' : 'light-header'">
>
<h5 class="text-center fw-normal mb-0">
<span> <span>
{{ text }} {{ text }}
</span> </span>
@ -14,9 +12,7 @@
/> />
</h5> </h5>
</div> </div>
<div <div class="d-flex align-items-center justify-content-center container-fluid overflow-hidden">
class="d-flex align-items-center justify-content-center container-fluid overflow-hidden"
>
<p class="text-center small fw-normal mb-0"> <p class="text-center small fw-normal mb-0">
<span> <span>
{{ subText }} {{ subText }}
@ -40,6 +36,7 @@ export default {
props: { props: {
hasBackButton: Boolean, hasBackButton: Boolean,
backButtonAccessibleText: String, backButtonAccessibleText: String,
hasSubText: Boolean
}, },
components: { components: {
buttonBack, buttonBack,
@ -58,11 +55,22 @@ export default {
<style lang="scss"> <style lang="scss">
h5 { h5 {
color: $gray-550;
line-height: 32px; line-height: 32px;
button { button {
color: inherit; color: inherit;
} }
} }
.dark-header {
color: $black;
}
.light-header {
color: $gray-550;
}
p.small {
color: $gray-550
}
</style> </style>

View file

@ -1,24 +1,120 @@
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from "@vue/test-utils";
import vehicleBanner from "./vehicle-banner"; import vehicleBanner from "./vehicle-banner";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
import { vehicleCategories } from "@/constants/vehicle-categories.js";
jest.mock(
"@/store",
() => {
return {};
},
{ virtual: true }
);
describe("vehicleBanner", () => { describe("vehicleBanner", () => {
test("renders the blurrycar image", async () => { test("renders the blurrycar image", async () => {
// Arrange // Arrange
const { wrapper, cmsContent } = setupMocks({ displayGenericVehicleImageProp: true, imageUrlValue: "NULL" });
// Act
const wrapper = shallowMount(vehicleBanner); //Act
await wrapper.setData({
vehicleImageSrc: "image_url",
});
wrapper.vm.initializeComponent(cmsContent); wrapper.vm.initializeComponent(cmsContent);
// Assert // Assert
expect(wrapper.find("img").attributes("class")).toContain("blurrycar"); expect(wrapper.vm.vehicleImageToDisplay).toEqual( "image_url");
expect(wrapper.find("img").attributes("class")).toContain("vehicle-image");
wrapper.unmount(); wrapper.unmount();
}); });
}); });
//Mock CMS content describe("vehicleBanner", () => {
const cmsContent = { test("renders expected vehicle image", async () => {
GenericVehicleImage: "image_url", // Arrange
}; const { wrapper, cmsContent } = setupMocks({ displayGenericVehicleImageProp: false, imageUrlValue: "url_to_vehicle_image" });
//Act
wrapper.vm.initializeComponent(cmsContent);
// Assert
expect(wrapper.vm.vehicleImageToDisplay).toEqual( "url_to_vehicle_image");
expect(wrapper.find("img").attributes("class")).toContain("vehicle-image");
wrapper.unmount();
});
});
describe("vehicleBanner", () => {
test("should render car icon when imageUrl is null and category is default", async () => {
// Arrange
const { wrapper, cmsContent } = setupMocks({ displayGenericVehicleImageProp: false, imageUrlValue: "NULL" });
//Act
wrapper.vm.initializeComponent(cmsContent);
var iconUrl = wrapper.vm.vehicleImageToDisplay;
// Assert
expect(iconUrl).toEqual( "car_icon_url");
wrapper.unmount();
});
});
const params = [["CAR", "car_icon_url"],
["TRUCK", "truck_icon_url"],
["VAN", "van_icon_url"],
["COMMERCIAL VAN", "commercial_van_icon_url"],
["SUV", "suv_icon_url"],
["OTHER", "car_icon_url"]];
describe("vehicleBanner", () => {
test.each(params)("renders an icon instead of an image for %s and %s", async (category, expectedIcon) => {
// Arrange
const { wrapper, cmsContent } = setupMocks({ displayGenericVehicleImageProp: false, imageUrlValue: expectedIcon, categoryValue: category });
//Act
wrapper.vm.initializeComponent(cmsContent);
var vehicleIcon = wrapper.vm.getUnmatchedVehicleIcon();
// Assert
expect(wrapper.vm.carUnmatchedVehicleIcon).toEqual(cmsContent.CarUnmatchedVehicleIcon);
expect(wrapper.vm.truckUnmatchedVehicleIcon).toEqual(cmsContent.TruckUnmatchedVehicleIcon);
expect(wrapper.vm.vanUnmatchedVehicleIcon).toEqual(cmsContent.VanUnmatchedVehicleIcon);
expect(wrapper.vm.commercialUnmatchedVehicleIcon).toEqual(cmsContent.CommercialVanUnmatchedVehicleIcon);
expect(wrapper.vm.suvUnmatchedVehicleIcon).toEqual(cmsContent.SuvUnmatchedVehicleIcon);
expect(store.getters.vehicle.category).toEqual(category);
expect(wrapper.vm.vehicleImageToDisplay).toEqual(vehicleIcon);
expect(wrapper.find("img").attributes("class")).toContain("vehicle-image");
wrapper.unmount();
});
});
function setupMocks({
displayGenericVehicleImageProp,
imageUrlValue,
categoryValue = "CAR"
}) {
//Mock store
store.dispatch = jest.fn(() => dataFromStoreApi);
store.getters = { vehicle: { category: categoryValue, imageUrl: imageUrlValue } };
const mountOptions = getMountOptions({
store: {
dispatch: store.dispatch,
getters: store.getters,
},
});
//Mock props
mountOptions.propsData = { displayGenericVehicleImage: displayGenericVehicleImageProp };
const wrapper = shallowMount(vehicleBanner, mountOptions);
//Mock CMS content
const cmsContent = {
GenericVehicleImage: "image_url",
CarUnmatchedVehicleIcon: "car_icon_url",
TruckUnmatchedVehicleIcon: "truck_icon_url",
VanUnmatchedVehicleIcon: "van_icon_url",
CommercialVanUnmatchedVehicleIcon: "commercial_van_icon_url",
SuvUnmatchedVehicleIcon: "suv_icon_url",
};
return { wrapper, cmsContent };
}

View file

@ -1,8 +1,8 @@
<template> <template>
<div class="vehicle_banner mb-3 text-center"> <div class="vehicle_banner mb-3 text-center">
<img <img
class="vehicle-image img-fluid blurrycar" class="vehicle-image img-fluid"
:src="vehicleImageSrc" :src="vehicleImageToDisplay"
alt="" alt=""
/> />
</div> </div>
@ -11,21 +11,70 @@
<script> <script>
export default { export default {
name: "vehicle-banner", name: "vehicle-banner",
props: {
displayGenericVehicleImage: {
type: Boolean,
required: true
}
},
data() { data() {
return { return {
vehicleImageSrc: "", vehicleImageSrc: '',
}; genericVehicleImage: '',
carUnmatchedVehicleIcon: '',
truckUnmatchedVehicleIcon: '',
vanUnmatchedVehicleIcon: '',
commercialUnmatchedVehicleIcon: '',
suvUnmatchedVehicleIcon: ''
}
}, },
computed: {
vehicleImageToDisplay(){
if (this.displayGenericVehicleImage){
return this.genericVehicleImage;
}
if (this.$store.getters.vehicle.imageUrl === null || this.$store.getters.vehicle.imageUrl === "NULL"){
return this.getUnmatchedVehicleIcon();
}
return this.$store.getters.vehicle.imageUrl;
}
},
methods: { methods: {
initializeComponent(cmsContent) { initializeComponent(cmsContent) {
this.vehicleImageSrc = cmsContent.GenericVehicleImage; this.genericVehicleImage = cmsContent.GenericVehicleImage;
this.carUnmatchedVehicleIcon = cmsContent.CarUnmatchedVehicleIcon;
this.truckUnmatchedVehicleIcon = cmsContent.TruckUnmatchedVehicleIcon;
this.vanUnmatchedVehicleIcon = cmsContent.VanUnmatchedVehicleIcon;
this.commercialUnmatchedVehicleIcon = cmsContent.CommercialVanUnmatchedVehicleIcon;
this.suvUnmatchedVehicleIcon = cmsContent.SuvUnmatchedVehicleIcon;
}, },
}, getUnmatchedVehicleIcon(){
switch(this.$store.getters.vehicle.category){
case this.vehicleCategories.CAR:
return this.carUnmatchedVehicleIcon;
case this.vehicleCategories.SUV:
return this.suvUnmatchedVehicleIcon;
case this.vehicleCategories.TRUCK:
return this.truckUnmatchedVehicleIcon;
case this.vehicleCategories.VAN:
return this.vanUnmatchedVehicleIcon;
case this.vehicleCategories.COMMERCIALVAN:
return this.commercialUnmatchedVehicleIcon;
default:
return this.carUnmatchedVehicleIcon;
}
}
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.vehicle-image { .vehicle-image {
max-width: 290px; max-width: 290px;
object-fit: cover;
width: 100%;
height: 118px;
} }
</style> </style>

View file

@ -7,6 +7,9 @@ const storeMutations = {
UPDATE_STYLE: "updateStyle", UPDATE_STYLE: "updateStyle",
UPDATE_CAR_ID: "updateCarId", UPDATE_CAR_ID: "updateCarId",
UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory", UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory",
UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl",
UPDATE_VEHICLE_IMAGE_VIF_NUMBER: "updateVehicleImageVifNumber",
UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
// EVENT BUS MUTATIONS // EVENT BUS MUTATIONS
ADD_EVENT_TO_BUS: "addEventToBus", ADD_EVENT_TO_BUS: "addEventToBus",

View file

@ -0,0 +1,11 @@
const vehicleCategories = {
CAR: "CAR",
TRUCK: "TRUCK",
VAN: "VAN",
COMMERCIALVAN: "COMMERCIAL VAN",
SUV: "SUV",
MOTORHOME: "MOTOR HOME",
SEMI: "SEMI",
};
export { vehicleCategories };

View file

@ -1,6 +1,7 @@
import { storeActions } from "@/constants/store-actions"; import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations.js"; import { storeMutations } from "@/constants/store-mutations.js";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js";
import { vehicleCategories } from "@/constants/vehicle-categories.js";
export function getMountOptions(mockData) { export function getMountOptions(mockData) {
// Define our mocks to attached to the 'global' object for Vue/Jest. // Define our mocks to attached to the 'global' object for Vue/Jest.
@ -23,6 +24,7 @@ export function getMountOptions(mockData) {
mocks.storeActions = storeActions; mocks.storeActions = storeActions;
mocks.storeMutations = storeMutations; mocks.storeMutations = storeMutations;
mocks.navigationScenarios = navigationScenarios; mocks.navigationScenarios = navigationScenarios;
mocks.vehicleCategories = vehicleCategories;
// Mock $store and $router when accessing this.$store/$router // Mock $store and $router when accessing this.$store/$router
mocks.$store = mockData.store; mocks.$store = mockData.store;

View file

@ -2,7 +2,7 @@
<div class="container-fluid container-shadow p-2 rounded-3"> <div class="container-fluid container-shadow p-2 rounded-3">
<div class="row my-3"> <div class="row my-3">
<div class="col"> <div class="col">
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=true />
</div> </div>
</div> </div>
<div class="row my-4"> <div class="row my-4">

View file

@ -822,7 +822,8 @@
<div class="row my-3"> <div class="row my-3">
<div class="col"> <div class="col">
<vehicleBanner <vehicleBanner
vehicleImageSrc="https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3" vehicleImageSrc="https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3"
:displayGenericVehicleImage=true
/> />
</div> </div>
</div> </div>

View file

@ -1,10 +1,8 @@
<template> <template>
<div class="container-fluid shadow rounded-3 p-2 position-relative"> <div class="container-fluid shadow rounded-3 p-2 position-relative">
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
<funnelSubHeader <funnelSubHeader ref="funnelSubHeader" :hasSubText=true />
ref="funnelSubHeader"
/>
<damageLocationQuestion ref="damageLocation" isMultiSelect v-model="damageLocationQuestionData" /> <damageLocationQuestion ref="damageLocation" isMultiSelect v-model="damageLocationQuestionData" />
<replaceOptionsQuestion ref="driverSideOptions" isAvailable isMultiSelect v-model="driverSideOptionsData" /> <replaceOptionsQuestion ref="driverSideOptions" isAvailable isMultiSelect v-model="driverSideOptionsData" />
</div> </div>

View file

@ -3,12 +3,12 @@
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<div class="select-car"> <div class="select-car">
<div class="select-car-form rounded text-center"> <div class="select-car-form rounded text-center">
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=true />
<funnelSubHeader <funnelSubHeader
ref="funnelSubHeader" ref="funnelSubHeader"
:hasBackButton="true" :hasBackButton="true"
backButtonAccessibleText="Change Vehicle Year" backButtonAccessibleText="Change Vehicle Year"
@click-event="backButtonAction" @click-event="backButtonAction"
/> />
<makeQuestion v-model="selectedMake" ref="makeQuestion" /> <makeQuestion v-model="selectedMake" ref="makeQuestion" />
</div> </div>

View file

@ -3,7 +3,7 @@
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<div class="select-car"> <div class="select-car">
<div class="select-car-form rounded text-center"> <div class="select-car-form rounded text-center">
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=true />
<funnelSubHeader <funnelSubHeader
ref="funnelSubHeader" ref="funnelSubHeader"
:hasBackButton="true" :hasBackButton="true"

View file

@ -3,7 +3,7 @@
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<div class="select-car"> <div class="select-car">
<div class="select-car-form rounded text-center"> <div class="select-car-form rounded text-center">
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=true />
<funnelSubHeader <funnelSubHeader
ref="funnelSubHeader" ref="funnelSubHeader"
:hasBackButton="true" :hasBackButton="true"

View file

@ -3,7 +3,7 @@
<funnelHeader ref="funnelHeader" /> <funnelHeader ref="funnelHeader" />
<div class="select-car"> <div class="select-car">
<div class="select-car-form rounded text-center"> <div class="select-car-form rounded text-center">
<vehicleBanner ref="vehicleBanner" /> <vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=true />
<funnelSubHeader ref="funnelSubHeader" /> <funnelSubHeader ref="funnelSubHeader" />
<yearQuestion v-model="selectedYear" ref="yearQuestion" /> <yearQuestion v-model="selectedYear" ref="yearQuestion" />
</div> </div>

View file

@ -3,6 +3,7 @@ import { storeActions } from "@/constants/store-actions.js";
import { storeMutations } from "@/constants/store-mutations.js"; import { storeMutations } from "@/constants/store-mutations.js";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
import { widgetNames } from "@/constants/widget-names.js"; import { widgetNames } from "@/constants/widget-names.js";
import { vehicleCategories } from "@/constants/vehicle-categories.js";
export default { export default {
data() { data() {
@ -31,6 +32,9 @@ export default {
widgetNames() { widgetNames() {
return widgetNames; return widgetNames;
}, },
vehicleCategories() {
return vehicleCategories;
},
}, },
}; };

View file

@ -16,6 +16,9 @@ export const state = {
style: null, style: null,
carId: null, carId: null,
category: null, category: null,
imageUrl: null,
imageVifNumber: null,
imageColor: null,
}, },
damage: { damage: {
isRepair: null, isRepair: null,
@ -49,6 +52,15 @@ export const mutations = {
updateVehicleCategory(state, category) { updateVehicleCategory(state, category) {
state.order.vehicle.category = category; state.order.vehicle.category = category;
}, },
updateVehicleImageUrl(state, imageUrl) {
state.order.vehicle.imageUrl = imageUrl;
},
updateVehicleImageVifNumber(state, imageVifNumber) {
state.order.vehicle.imageVifNumber = imageVifNumber;
},
updateVehicleImageColor(state, imageColor) {
state.order.vehicle.imageColor = imageColor;
},
// EVENT BUS MUTATIONS // EVENT BUS MUTATIONS
addEventToBus(state, event) { addEventToBus(state, event) {
@ -165,6 +177,9 @@ export const actions = {
.then((response) => { .then((response) => {
context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId); context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId);
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category);
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, response.data.imageUrl);
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, response.data.imageVifNumber);
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, response.data.imageVifColor);
return response; return response;
}); });
}, },