CSR-120 Several updates and refactoring

This commit is contained in:
Adam Caouette 2021-11-22 19:13:31 -05:00
parent a3fd8159d8
commit f80d01a44a
9 changed files with 195 additions and 379 deletions

View file

@ -0,0 +1,61 @@
import { shallowMount, enableAutoUnmount } from '@vue/test-utils';
import vehicleBanner from './vehicle-banner';
import { getMountOptions } from "@/helpers/unit-test-helper.js"
describe('vehicleBanner', () => {
// Arrange
const mountOptions = getMountOptions({
actionList: [
{
actionName: "lookupVehicleByYmms",
data: [
{
CarId: "CR00068434"
}
]
},
{
actionName: "lookupVehicleByVin",
data: [
{
CarId: "CR00068434"
}
]
},
{
actionName: "getEvoxImage",
data: {
imgSrc: "https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg"
}
}
]
});
enableAutoUnmount(afterEach)
// Act
const wrapper = shallowMount(vehicleBanner, {
...mountOptions
});
// Assert
it('renders the blurrycar image when vehicleImageSrc is not present', () => {
expect(wrapper.find('img').attributes('class')).toContain('blurrycar');
});
// Assert
it('does not render the blurrycar image when vehicleImageSrc exists', async () => {
await wrapper.setData({ 'vehicleImageSrc': 'https://s3.amazonaws.com/safelite-lab-vehicle-images/Evox/8963_cc0320_032_UG_white_2014_Ford_Focus_18029225538399034889.jpg' });
setTimeout(() => {
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
}, 500);
});
// Assert
it('does not render the blurrycar image when passedCarId is set', async () => {
await wrapper.setProps({ 'passedCarId': 'CR00068434' });
setTimeout(() => {
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
}, 500);
});
});

View file

@ -0,0 +1,92 @@
<template>
<div class="vehicle_banner mb-3">
<img
class="vehicle-image img-fluid"
:src="vehicleImageSrc"
v-if="vehicleImageSrc"
alt=""
/>
<img
class="vehicle-image img-fluid blurrycar"
src='@/assets/img/blurrycar.png'
alt=""
v-else
/>
</div>
</template>
<script>
export default {
name: "vehicle-banner",
computed: {
vin () {
return this.$store.state.order.vehicle.vin;
},
ymms () {
return {
year: this.$store.state.order.vehicle.year,
make: this.$store.state.order.vehicle.make,
model: this.$store.state.order.vehicle.model,
style: this.$store.state.order.vehicle.style
}
}
},
props: {
passedCarId: String
},
data() {
return {
years: [],
carId: '',
vehicleImageSrc: '',
};
},
created() {
if (this.passedCarId && this.passedCarId.length > 0) {
this.getVehicleImage(this.passedCarId)
} else if (this.vin && this.vin.length > 0) {
this.getCarIdWithVin(this.vin)
} else if (!Object.values(this.ymms).includes(null) && !Object.values(this.ymms).includes('')) {
this.getCarIdWithYmms(this.ymms)
}
},
methods: {
getCarIdWithYmms(ymms) { // retrieve carId with YMMS object
console.log('ymms: ', ymms)
this.dispatchNonBlockingStoreAction(this.storeActions.LOOKUP_VEHICLE_BY_YMMS, ymms).then((response) => {
console.log('response1: ', response);
console.log('response1.data: ', response.data);
console.log('response1.data[0]: ', response.data[0]);
console.log('response1.data[0].CarId: ', response.data[0].CarId);
const carId = response.data[0].CarId;
console.log('carId: ', carId);
this.getVehicleImage(carId)
}).catch(error => {
console.debug(`An error has occurred: ${error}`);
});
},
getCarIdWithVin(vin) { // retrieve carId with VIN string
this.dispatchNonBlockingStoreAction(this.storeActions.LOOKUP_VEHICLE_BY_VIN, vin).then((response) => {
console.log('response2: ', response);
const carId = response.data[0].CarId;
console.log('carId: ', carId);
this.getVehicleImage(carId)
}).catch(error => {
console.debug(`An error has occurred: ${error}`);
});
},
async getVehicleImage(carId) { // look up evox with carId
const evoxResponse = await this.dispatchNonBlockingStoreAction(this.storeActions.GET_EVOX_IMAGE, {relativeUrl: "https://mockey.qa.sagaws.net/service/evox-image?carId=" + carId});
if (evoxResponse.data && evoxResponse.data.imgSrc) {
this.vehicleImageSrc = evoxResponse.data.imgSrc;
}
}
}
}
</script>
<style lang="scss" scoped>
.vehicle-image {
max-width: 290px;
}
</style>

View file

@ -1,52 +0,0 @@
import { mount, enableAutoUnmount, flushPromises } from '@vue/test-utils';
import vehicleBanner from './vehicleBanner';
import { nextTick } from 'vue';
import { getMountOptions } from "@/helpers/unit-test-helper.js"
describe('vehicleBanner', () => {
// Arrange
const mountOptions = getMountOptions({
actionList: [
{
actionName: "getMockPageData",
data: {
imgData: ""
}
}
]
});
enableAutoUnmount(afterEach)
// Act
const wrapper = mount(vehicleBanner, {
...mountOptions
});
// Assert
it('renders the blurrycar image when no vehicleImageSrc is found', () => {
expect(wrapper.find('img').attributes('class')).toContain('blurrycar');
});
it('renders the blurrycar image when isBlurred is true', async () => {
await wrapper.setData("test string");
await wrapper.setProps({ isBlurred: true });
// timeout needed for image call to have time to return with a vehicleSrcImage
setTimeout(() => {
expect(wrapper.find('img').attributes('class')).toContain('blurrycar');
}, 500);
});
it('renders an actual car image when vehicleImageSrc is found and isBlurred is false', async () => {
await wrapper.setData("test string");
await wrapper.setProps({ isBlurred: false});
await flushPromises(); // including this doesn't appear to matter
await nextTick(); // including this doesn't appear to matter
// timeout needed for image call to have time to return with a vehicleSrcImage
setTimeout(() => {
expect(wrapper.find('img').attributes('class')).not.toContain('blurrycar');
}, 500);
});
});

View file

@ -1,57 +0,0 @@
<template>
<div class="vehicle_banner mb-3">
<h4>vehicleImageSrc: {{vehicleImageSrc}}</h4>
<img
class="vehicle-image img-fluid"
:class="carId"
:src="vehicleImageSrc"
v-if="!isBlurred && vehicleImageSrc"
/>
<img
class="vehicle-image img-fluid blurrycar"
src='@/assets/img/blurrycar.png'
v-else
/>
</div>
</template>
<script>
import store from "@/store";
import { mapState } from "vuex";
import { storeActions } from "@/constants/storeActions";
export default {
name: "vehicle-banner",
computed: {
...mapState(["carImg", "vehicleImageSrc"]),
},
props: {
isBlurred: {
type: Boolean,
default: false
},
carId: String
},
created() {
const carId = this.carId || '';
this.getVehicleImage(carId);
},
methods: {
getVehicleImage(carId) {
this.dispatchNonBlockingStoreAction(storeActions.GET_PAGE_DATA, {relativeUrl: "https://mockey.qa.sagaws.net/service/evox-image?carId=" + carId})
.then( (response) => {
const imgData = response.data;
store.commit('updateVehicleImage', imgData);
}, error => {
store.commit('updateVehicleImage', '');
});
}
},
};
</script>
<style lang="scss" scoped>
.vehicle-image {
max-width: 290px;
}
</style>

View file

@ -23,6 +23,14 @@ const endpoints = {
url: "/content/api/v1/content",
method: "GET",
},
LookupVehicleByYmms: {
url: "/vehicle/api/v1/vehicle/Lookup",
method: "GET",
},
LookupVehicleByVin: {
url: "/vehicle/api/v1/vehicle/Lookup",
method: "POST",
},
};
export { endpoints };

View file

@ -5,6 +5,9 @@ const storeActions = {
GET_VEHICLE_MAKES: "getVehicleMakes",
GET_VEHICLE_MODELS: "getVehicleModels",
GET_VEHICLE_STYLES: "getVehicleStyles",
GET_EVOX_IMAGE: "getEvoxImage",
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin"
};
export { storeActions };

View file

@ -78,21 +78,13 @@
<h6>h6 Heading</h6>
</div>
</div>
<div class="my-3">
<div class="select-car">
<div class="select-car-form">
<radioQuestion questionText="What year is your vehicle?" :answers="this.years" />
</div>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<vehicle-banner
:isBlurred="true"
carId="00test00"
<div class="row my-3">
<div class="d-flex align-items-center">
<vehicleBanner
passedCarId=""
/>
<vehicle-banner
carId="00test00"
<vehicleBanner
passedCarId="CR00068434"
/>
</div>
</div>
@ -105,7 +97,7 @@ import buttonSecondary from "@/ux-components/button-secondary/button-secondary";
import radioCard from "@/ux-components/radio-card/radio-card";
import listButton from "@/ux-components/list-button/list-button";
import radioList from "@/ux-components/radio-list/radio-list";
import vehicleBanner from "@/commonComponents/vehicleBanner/vehicleBanner";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
export default {
name: "App",
components: {
@ -114,6 +106,7 @@ export default {
radioCard,
listButton,
radioList,
vehicleBanner
},
data() {
return {

View file

@ -1,255 +0,0 @@
<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">Radio Card</h4>
</div>
</div>
<div class="row g-2">
<radioCard
radioLabel="Windshield"
radioImage="windshield-damage.svg"
altText="Windshield"
groupName="damageKey"
radioID="windshield"
/>
<radioCard
radioLabel="Side Window"
radioImage="side-window-damage.svg"
altText="Side Window"
groupName="damageKey"
radioID="sidewindow"
/>
<radioCard
radioLabel="Back Glass"
radioImage="back-glass-damage.svg"
altText="Back Glass"
groupName="damageKey"
radioID="backglass"
/>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Buttons</h4>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<buttonPrimary
buttonText="Primary"
/>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<buttonSecondary
buttonText="Secondary"
/>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">List Button</h4>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<listButton
buttonText="List Button"
errorText="Test error message"
/>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Radio Button Group</h4>
</div>
</div>
<div class="row">
<!-- The role="radiogroup" and aria-labelledby must be included in the parent component for the radio group -->
<div role="radiogroup" aria-labelledby="select-year-radio-group" class="col my-3 d-flex align-items-center flex-column">
<!-- The h3 and id must be included. The id must match the aria-labelledby of the parent div. -->
<h3 class="visually-hidden" id="select-year-radio-group">Select Vehicle Year</h3>
<radioList
groupName="demo"
ariaLabelBy="vehicle-year"
radioID="2021"
errorMessage="Test error message"
/>
<radioList
groupName="demo"
ariaLabelBy="vehicle-year"
radioID="2020"
errorMessage="Test error message"
/>
<radioList
groupName="demo"
ariaLabelBy="vehicle-year"
radioID="2019"
errorMessage="Test error message"
/>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Text Link</h4>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<a href="#">Text Link</a>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Typogrophy</h4>
</div>
</div>
<div class="row my-2">
<div class="col">
<p>This is default body copy font size/weight</p>
<p class="small">This is small body copy using <code>.small</code> class</p>
<p><small>This is also small using <code>&lt;small&gt;</code> tag</small></p>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Headings</h4>
</div>
</div>
<div class="row my-2">
<div class="col">
<h1>h1 Heading</h1>
</div>
</div>
<div class="row my-2">
<div class="col">
<h2>h2 Heading</h2>
</div>
</div>
<div class="row my-2">
<div class="col">
<h3>h3 Heading</h3>
</div>
</div>
<div class="row my-2">
<div class="col">
<h4>h4 Heading</h4>
</div>
</div>
<div class="row my-2">
<div class="col">
<h5>h5 Heading</h5>
</div>
</div>
<div class="row my-2">
<div class="col">
<h6>h6 Heading</h6>
</div>
</div>
<div class="row">
<div class="col my-3 d-flex align-items-center">
<vehicle-banner
:isBlurred="true"
carId="00test00"
/>
<vehicle-banner
carId="00test00"
/>
</div>
</div>
<div class="row my-4">
<div class="col">
<h4 class="m-0 p-2 bg-light rounded">Alerts</h4>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-success"
alertHeadline="Dismissible Alert"
alertCopy="This is an example of a DISMISSIBLE alert. It will fade away and content around it will shift when dismissed."
v-bind:isDismissible = "true"
/>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-danger"
alertHeadline="NON-Dismissible Alert"
alertCopy="This is an example of a NON-DISMISSIBLE alert."
v-bind:isDismissible = "false"
/>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-warning"
alertHeadline="Warning Alert"
alertCopy="This is an example of a WARNING alert."
v-bind:isDismissible = "false"
/>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-info"
alertHeadline="Info Alert"
alertCopy="This is an example of a INFO alert."
v-bind:isDismissible = "false"
/>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-danger"
alertHeadline="Danger Alert"
alertCopy="This is an example of a DANGER alert."
v-bind:isDismissible = "false"
/>
</div>
</div>
<div class="row my-2">
<div class="col">
<alert
alertClass="alert-success"
alertHeadline="No Body Copy Alert"
alertCopy=""
v-bind:isDismissible = "false"
/>
</div>
</div>
</div>
</template>
<script>
import buttonPrimary from "@/uxComponents/buttonPrimary/buttonPrimary";
import buttonSecondary from "@/uxComponents/buttonSecondary/buttonSecondary";
import radioCard from "@/uxComponents/radioCard/radioCard";
import listButton from "@/uxComponents/listButton/listButton";
import vehicleBanner from "@/commonComponents/vehicleBanner/vehicleBanner";
import radioList from "@/uxComponents/radioList/radioList";
import alert from "@/uxComponents/alert/alert";
export default {
name: "App",
components: {
buttonPrimary,
buttonSecondary,
radioCard,
listButton,
vehicleBanner,
radioList,
alert
},
data() {
return {
years: [2023, 2022, 2021, 2020],
};
}
};
</script>

View file

@ -77,6 +77,22 @@ export default createStore({
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,
@ -116,5 +132,12 @@ export default createStore({
payload: {},
});
},
getEvoxImage(context, { relativeUrl }) {
return globalMethods.callMockHttpClient({
method: endpoints.GetPageData.method,
endpoint: relativeUrl,
payload: {},
});
},
},
});