Merge branch 'develop' into feature/Digital/SSR-51
This commit is contained in:
commit
75f8da12bc
33 changed files with 1033 additions and 111 deletions
44
package-lock.json
generated
44
package-lock.json
generated
|
|
@ -17717,6 +17717,29 @@
|
||||||
"webpack-merge": "^5.7.3",
|
"webpack-merge": "^5.7.3",
|
||||||
"webpack-virtual-modules": "^0.4.2",
|
"webpack-virtual-modules": "^0.4.2",
|
||||||
"whatwg-fetch": "^3.6.2"
|
"whatwg-fetch": "^3.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/vue-loader-v15": {
|
||||||
|
"version": "npm:vue-loader@15.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
|
||||||
|
"integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@vue/component-compiler-utils": "^3.1.0",
|
||||||
|
"hash-sum": "^1.0.2",
|
||||||
|
"loader-utils": "^1.1.0",
|
||||||
|
"vue-hot-reload-api": "^2.3.0",
|
||||||
|
"vue-style-loader": "^4.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"hash-sum": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@vue/cli-shared-utils": {
|
"@vue/cli-shared-utils": {
|
||||||
|
|
@ -17967,27 +17990,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@vue/vue-loader-v15": {
|
|
||||||
"version": "npm:vue-loader@15.10.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
|
|
||||||
"integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@vue/component-compiler-utils": "^3.1.0",
|
|
||||||
"hash-sum": "^1.0.2",
|
|
||||||
"loader-utils": "^1.1.0",
|
|
||||||
"vue-hot-reload-api": "^2.3.0",
|
|
||||||
"vue-style-loader": "^4.1.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"hash-sum": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@vue/vue3-jest": {
|
"@vue/vue3-jest": {
|
||||||
"version": "27.0.0",
|
"version": "27.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/vue3-jest/-/vue3-jest-27.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/vue3-jest/-/vue3-jest-27.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,16 @@
|
||||||
<head>
|
<head>
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = [{}];
|
window.dataLayer = [{}];
|
||||||
</script>
|
</script>
|
||||||
<script><%= process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY %></script>
|
<script><%= process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY %></script>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.625rem;
|
line-height: 1.5rem;
|
||||||
|
|
||||||
& > span {
|
& > span {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import buttonBack from "./button-back";
|
||||||
|
|
||||||
|
describe("back button", () => {
|
||||||
|
test("renders a button", () => {
|
||||||
|
// Arrange
|
||||||
|
const myFunction = () => {};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonBack, {
|
||||||
|
propsData: {
|
||||||
|
backButtonAction: myFunction,
|
||||||
|
backButtonAccessibleText: "something",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.find("button").exists()).toBe(true);
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
@click="handleClick"
|
||||||
|
class="back-button-wrapper"
|
||||||
|
:aria-label="backButtonAccessibleText"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="34px"
|
||||||
|
height="30px"
|
||||||
|
viewBox="-2.2 -6 30 30"
|
||||||
|
>
|
||||||
|
<g id="Layer_3">
|
||||||
|
<path
|
||||||
|
class="outer"
|
||||||
|
fill="#FFFFFF"
|
||||||
|
d="M19.934-1.434h-8.486c-1.683,0-2.999,0.528-4.021,1.614L1.685,6.146C0.78,7.079,0.338,8.027,0.338,9.041
|
||||||
|
c0,1.028,0.444,1.979,1.359,2.908l5.753,5.938c1.054,1.093,2.403,1.647,4.007,1.647l8.475,0.01c2.861,0,4.568-1.692,4.568-4.528
|
||||||
|
V3.094C24.5,0.259,22.793-1.434,19.934-1.434L19.934-1.434z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g id="Layer_2">
|
||||||
|
<path
|
||||||
|
class="inner"
|
||||||
|
fill="#727676"
|
||||||
|
d="M19.934,17.989c2.041,0,3.066-1.006,3.066-3.028V3.039c0-2.022-1.025-3.028-3.066-3.028h-8.486
|
||||||
|
c-1.143,0-2.129,0.292-2.929,1.143L2.766,7.13C2.131,7.784,1.838,8.37,1.838,8.985c0,0.605,0.283,1.201,0.928,1.855l5.762,5.947
|
||||||
|
c0.811,0.84,1.787,1.191,2.93,1.191L19.934,17.989z M10.773,13.253c-0.439,0-0.801-0.371-0.801-0.82
|
||||||
|
c0-0.215,0.078-0.42,0.235-0.566l2.861-2.861l-2.861-2.862c-0.156-0.156-0.234-0.352-0.234-0.566c0-0.458,0.362-0.801,0.801-0.801
|
||||||
|
c0.224,0,0.41,0.069,0.556,0.225l2.881,2.872l2.891-2.881c0.166-0.166,0.353-0.234,0.566-0.234c0.439,0,0.801,0.352,0.801,0.801
|
||||||
|
c0,0.225-0.078,0.4-0.234,0.576l-2.871,2.871l2.861,2.852c0.146,0.156,0.234,0.352,0.234,0.576c0,0.449-0.361,0.82-0.811,0.82
|
||||||
|
c-0.225,0-0.43-0.098-0.586-0.244l-2.852-2.871l-2.852,2.871C11.203,13.165,10.999,13.253,10.773,13.253z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "buttonBack",
|
||||||
|
props: {
|
||||||
|
backButtonAccessibleText: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClick() {
|
||||||
|
this.$emit("click-event");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.back-button-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
margin-left: 2px;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
svg .outer {
|
||||||
|
fill: $white;
|
||||||
|
stroke-width: 2.5px;
|
||||||
|
stroke: $blue;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: round;
|
||||||
|
transform: translate(-2.7px, -1.8px) scale(1.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -5,23 +5,39 @@
|
||||||
<span>
|
<span>
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</span>
|
</span>
|
||||||
|
<buttonBack
|
||||||
|
v-if="hasBackButton"
|
||||||
|
:backButtonAccessibleText="backButtonAccessibleText"
|
||||||
|
@click-event="clickEvent"
|
||||||
|
/>
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import buttonBack from "@/common-components/site-sub-header/button-back/button-back";
|
||||||
|
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
name: "siteSubHeader",
|
name: "siteSubHeader",
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
|
hasBackButton: Boolean,
|
||||||
|
backButtonAccessibleText: String,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
content()
|
content()
|
||||||
{
|
{
|
||||||
return this.getCmsContent(this.cmsWidgetName, "SubHeaderText")
|
return this.getCmsContent(this.cmsWidgetName, "SubHeaderText")
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
clickEvent() {
|
||||||
|
this.$emit("click-event");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: { buttonBack },
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-banner",
|
name: "vehicle-banner",
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -25,7 +25,7 @@ export default {
|
||||||
return this.genericVehicleImage;
|
return this.genericVehicleImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageUrl = this.mainStore.order.vehicle.imageUrl;
|
const imageUrl = useMainStore().order.vehicle.imageUrl;
|
||||||
if (!imageUrl || imageUrl === "NULL"){
|
if (!imageUrl || imageUrl === "NULL"){
|
||||||
return this.getUnmatchedVehicleIcon();
|
return this.getUnmatchedVehicleIcon();
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getUnmatchedVehicleIcon(){
|
getUnmatchedVehicleIcon(){
|
||||||
switch(this.mainStore.order.vehicle.category){
|
switch(useMainStore().order.vehicle.category){
|
||||||
case this.vehicleCategories.CAR:
|
case this.vehicleCategories.CAR:
|
||||||
return this.carUnmatchedVehicleIcon;
|
return this.carUnmatchedVehicleIcon;
|
||||||
case this.vehicleCategories.SUV:
|
case this.vehicleCategories.SUV:
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,14 @@ const endpoints = {
|
||||||
url: "/vehicle/api/v1/vehicle/years",
|
url: "/vehicle/api/v1/vehicle/years",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
|
GetVehicleMakes: {
|
||||||
|
url: "/vehicle/api/v1/vehicle/makes/",
|
||||||
|
method: "GET",
|
||||||
|
},
|
||||||
|
GetVehicleModels: {
|
||||||
|
url: "/vehicle/api/v1/vehicle/Models",
|
||||||
|
method: "GET",
|
||||||
|
},
|
||||||
GetPageData: {
|
GetPageData: {
|
||||||
url: (applicationAbbreviation, pageName) =>
|
url: (applicationAbbreviation, pageName) =>
|
||||||
`/content/api/v1/content/${applicationAbbreviation}/${pageName}`,
|
`/content/api/v1/content/${applicationAbbreviation}/${pageName}`,
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ export default {
|
||||||
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
|
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
|
||||||
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "SelfService" });
|
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "SelfService" });
|
||||||
const headers = {
|
const headers = {
|
||||||
[headerKeys.EXPERIMENT]: JSON.stringify(useMainStore.getters.experimentSettings),
|
[headerKeys.EXPERIMENT]: JSON.stringify(useMainStore.experimentSettings),
|
||||||
};
|
};
|
||||||
|
|
||||||
axios({
|
axios({
|
||||||
method: method,
|
method: method,
|
||||||
|
|
|
||||||
|
|
@ -89,14 +89,14 @@ function mapStringToState(str) {
|
||||||
const regexMatches = [...str.matchAll(regexExp)];
|
const regexMatches = [...str.matchAll(regexExp)];
|
||||||
const globalStateMatches = regexMatches.filter(match => {
|
const globalStateMatches = regexMatches.filter(match => {
|
||||||
return match[1] === dynamicStrings.GLOBAL_STATE;
|
return match[1] === dynamicStrings.GLOBAL_STATE;
|
||||||
})
|
});
|
||||||
|
|
||||||
// Our final string value that will be built from the matches.
|
// Our final string value that will be built from the matches.
|
||||||
let stringBuilder = "";
|
let stringBuilder = "";
|
||||||
|
|
||||||
for (const match of globalStateMatches) {
|
for (const match of globalStateMatches) {
|
||||||
// Reset store state for each match.
|
// Reset store state for each match.
|
||||||
let storeState = useMainStore().state;
|
let storeState = useMainStore();
|
||||||
|
|
||||||
for (const s of match[2].split(".")) {
|
for (const s of match[2].split(".")) {
|
||||||
if (storeState[s] != undefined) {
|
if (storeState[s] != undefined) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import { externalUrls } from "@/router/router-constants/externalUrl-values";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
|
|
||||||
import { useMainStore } from "@/store";
|
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
|
||||||
// Mock Lazy Load
|
// Mock Lazy Load
|
||||||
|
|
@ -343,52 +342,6 @@ describe("navigateToHeritageFunnel", () => {
|
||||||
saveSessionFunction.mockRestore();
|
saveSessionFunction.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should go to heritage funnel", async () => {
|
|
||||||
// Arrange
|
|
||||||
const mockReferralNumber = "2";
|
|
||||||
const mockCorrelationId = "55";
|
|
||||||
const mockReferralDate = "2022";
|
|
||||||
const mockAccountNumber = "167132";
|
|
||||||
const mockSavedSessionId = "xxx-xxx-xxx";
|
|
||||||
const mockCrmCustomerId = "xxx-xxx-xxx";
|
|
||||||
|
|
||||||
const mockOrderInfo = getMockOrderInfo(
|
|
||||||
mockReferralNumber,
|
|
||||||
mockCorrelationId,
|
|
||||||
mockReferralDate,
|
|
||||||
mockAccountNumber,
|
|
||||||
mockSavedSessionId,
|
|
||||||
mockCrmCustomerId
|
|
||||||
);
|
|
||||||
|
|
||||||
const mockData = {
|
|
||||||
actionList: [
|
|
||||||
{
|
|
||||||
actionName: storeActions.SAVE_SESSION,
|
|
||||||
data: mockOrderInfo,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
setupMocksForJsFiles(mockData);
|
|
||||||
|
|
||||||
useMainStore.getters.order.referralCorrelationId = mockCorrelationId;
|
|
||||||
|
|
||||||
router.navigateToExternalUrl = jest.fn();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await navigateToHeritageFunnel();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(router.navigateToExternalUrl).toHaveBeenCalled();
|
|
||||||
expect(router.navigateToExternalUrl).toHaveBeenCalledWith(
|
|
||||||
externalUrls.HERITAGE_FUNNEL,
|
|
||||||
expect.objectContaining({
|
|
||||||
corid: mockCorrelationId,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("should not save session, but should still navigate", async () => {
|
test("should not save session, but should still navigate", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockReferralNumber = "2";
|
const mockReferralNumber = "2";
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { storeActions } from "@/constants/store-actions";
|
||||||
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";
|
import { vehicleCategories } from "@/constants/vehicle-categories.js";
|
||||||
import { issPageValues } from "@/router/router-constants/issPage-values";
|
import { issPageValues } from "@/router/router-constants/issPage-values";
|
||||||
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
import { Form } from "vee-validate";
|
import { Form } from "vee-validate";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
import { useMainStore } from "@/store";
|
import { useMainStore } from "@/store";
|
||||||
|
|
@ -50,6 +51,7 @@ export function getMountOptions(mockData) {
|
||||||
mocks.navigationScenarios = navigationScenarios;
|
mocks.navigationScenarios = navigationScenarios;
|
||||||
mocks.vehicleCategories = vehicleCategories;
|
mocks.vehicleCategories = vehicleCategories;
|
||||||
mocks.fmgPageValues = fmgPageValues;
|
mocks.fmgPageValues = fmgPageValues;
|
||||||
|
mocks.issPageValues = issPageValues;
|
||||||
mocks.analyticsPageEvents = analyticsPageEvents;
|
mocks.analyticsPageEvents = analyticsPageEvents;
|
||||||
mocks.GaCategories = GaCategories;
|
mocks.GaCategories = GaCategories;
|
||||||
mocks.GaActions = GaActions;
|
mocks.GaActions = GaActions;
|
||||||
|
|
|
||||||
70
src/layouts/vehicle-make/make-question/make-question.spec.js
Normal file
70
src/layouts/vehicle-make/make-question/make-question.spec.js
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
|
||||||
|
describe("make-question.vue", () => {
|
||||||
|
|
||||||
|
test("Data from store api are used as radio question answers.", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, cmsContent } = setupMocks({
|
||||||
|
dataFromStoreApi: ["honda", "ford", "dodge"],
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
const initialData = makeQuestion.methods.loadInitialData.call(wrapper.vm);
|
||||||
|
makeQuestion.methods.initializeComponent.call(
|
||||||
|
wrapper.vm,
|
||||||
|
initialData
|
||||||
|
);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
const buttonQuestionComponent = await wrapper.findComponent({
|
||||||
|
name: "buttonQuestion",
|
||||||
|
});
|
||||||
|
expect(buttonQuestionComponent.attributes("answers")).toBe(
|
||||||
|
"honda,ford,dodge"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Selected make is emitted upon selection.", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({ modelValueProp: "honda" });
|
||||||
|
const makeToSelect = "ford";
|
||||||
|
|
||||||
|
//Act
|
||||||
|
wrapper.setValue({ selectedMake: makeToSelect });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
||||||
|
{ selectedMake: "ford" },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
modelValueProp = "1900",
|
||||||
|
cmsQuestionText = "CMS text goes here",
|
||||||
|
dataFromStoreApi = [],
|
||||||
|
}) {
|
||||||
|
//Mock store
|
||||||
|
const mountOptions = getMountOptions();
|
||||||
|
|
||||||
|
const store = useMainStore();
|
||||||
|
store.getVehicleMakes = jest.fn(() => dataFromStoreApi);
|
||||||
|
|
||||||
|
|
||||||
|
mountOptions.propsData = {
|
||||||
|
modelValue: modelValueProp,
|
||||||
|
};
|
||||||
|
const wrapper = shallowMount(makeQuestion, mountOptions);
|
||||||
|
|
||||||
|
//Mock CMS content
|
||||||
|
const cmsContent = {
|
||||||
|
QuestionText: cmsQuestionText,
|
||||||
|
};
|
||||||
|
return { wrapper, cmsContent };
|
||||||
|
}
|
||||||
56
src/layouts/vehicle-make/make-question/make-question.vue
Normal file
56
src/layouts/vehicle-make/make-question/make-question.vue
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<buttonQuestion
|
||||||
|
class="radioQuestion"
|
||||||
|
isOverflowScrollable
|
||||||
|
selectingInitiatesLoad
|
||||||
|
:questionText="questionText"
|
||||||
|
:answers="makes"
|
||||||
|
groupName="ChooseVehicleMake"
|
||||||
|
textPosition="text-start"
|
||||||
|
v-model="selectedValue"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "make-question",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
makes: Array,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: String,
|
||||||
|
cmsWidgetName: String,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
questionText(){
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
|
||||||
|
},
|
||||||
|
selectedValue: {
|
||||||
|
get: function() {
|
||||||
|
return this.modelValue
|
||||||
|
},
|
||||||
|
set: function(newValue) {
|
||||||
|
this.$emit("update:modelValue", newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadInitialData() {
|
||||||
|
return useMainStore().getVehicleMakes();
|
||||||
|
},
|
||||||
|
initializeComponent(initialData) {
|
||||||
|
this.makes = initialData;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -1 +1,140 @@
|
||||||
test.todo("some test to be written in the future");
|
// Supporting Files
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
|
||||||
|
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
||||||
|
|
||||||
|
// Mock fetchCmsContentForPage
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock our module for promises.
|
||||||
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
settleAllPromises: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("vehicle-make.vue", () => {
|
||||||
|
|
||||||
|
test("Make question component is initized with api data", async () => {
|
||||||
|
//Arrange
|
||||||
|
const makeQuestionInitialData = ["honda", "ford", "dodge"];
|
||||||
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
|
makeQuestionInitialData: makeQuestionInitialData,
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleMake.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-make" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
apiPromise.finally(() => {
|
||||||
|
expect(makeQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
||||||
|
makeQuestionInitialData
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("BackButtonAction triggers a router.navigate change", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
|
pageHeaderWidgetHeaderText: "Select a make to get started",
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleMake.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-make" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
wrapper.vm.backButtonAction();
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
apiPromise.finally(() => {
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Year set, arePagePrerequisitesValid should be true ", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
useMainStore().order.vehicle.year = 2001;
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleMake.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-make" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
vehicleMakeQuestionCmsContent = {},
|
||||||
|
makeQuestionInitialData = {},
|
||||||
|
pageHeaderWidgetHeaderText = {},
|
||||||
|
mountOptionsMockData = {},
|
||||||
|
}) {
|
||||||
|
//Mock api responses
|
||||||
|
const apiResponses = {
|
||||||
|
cmsContent: {
|
||||||
|
SiteSubHeaderWidget: pageHeaderWidgetHeaderText,
|
||||||
|
VehicleMakeQuestion: vehicleMakeQuestionCmsContent,
|
||||||
|
VehicleBannerWidget: {
|
||||||
|
GenericVehicleImage:
|
||||||
|
"https://digitalisscms.dev.safelite.io/images/default-source/default-album/blurred-image.jpg",
|
||||||
|
},
|
||||||
|
SiteHeaderWidget: {
|
||||||
|
LogoImage:
|
||||||
|
"https://digitalisscms.dev.safelite.io/images/default-source/default-album/logos/insuranceLogo.jpg",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
makeQuestionInitialData: makeQuestionInitialData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const apiPromise = Promise.resolve(apiResponses);
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiPromise);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
|
//Mock make question methods
|
||||||
|
makeQuestion.methods = {
|
||||||
|
loadInitialData: jest.fn(),
|
||||||
|
initializeComponent: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
|
const wrapper = shallowMount(vehicleMake, mountOptions);
|
||||||
|
|
||||||
|
const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" });
|
||||||
|
makeQuestionWrapper.vm.initializeComponent =
|
||||||
|
makeQuestion.methods.initializeComponent;
|
||||||
|
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||||
|
|
||||||
|
return { wrapper, apiPromise };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,102 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="page-container-grouped-styles">
|
||||||
<input type="text" v-model="year"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<span> Vehicle Make Placeholder </span>
|
<div class="select-car">
|
||||||
<span>{{returnVehicleYear}}</span>
|
<div class="select-car-form rounded text-center">
|
||||||
<button @click="updateVehicleYear(year)">Add</button>
|
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true"/>
|
||||||
|
<siteSubHeader
|
||||||
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
|
:hasBackButton="true"
|
||||||
|
@click-event="backButtonAction"
|
||||||
|
backButtonAccessibleText = "Change vehicle year"
|
||||||
|
/>
|
||||||
|
<div class="fade-on-route-transition">
|
||||||
|
<makeQuestion
|
||||||
|
class="fade-on-route-transition"
|
||||||
|
v-model="selectedMake"
|
||||||
|
ref="makeQuestion"
|
||||||
|
cmsWidgetName="VehicleMakeQuestion"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Components
|
||||||
|
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
||||||
|
import siteHeader from "@/common-components/site-header/site-header";
|
||||||
|
import siteSubHeader from "@/common-components/site-sub-header/site-sub-header";
|
||||||
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'vehicle-make',
|
name: 'vehicle-make',
|
||||||
methods:
|
data() {
|
||||||
{
|
return {
|
||||||
updateVehicleYear(item)
|
selectedMake: null,
|
||||||
{
|
};
|
||||||
this.mainStore.updateVehicleYear(item);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed:
|
|
||||||
{
|
async beforeRouteEnter(to, from, next) {
|
||||||
returnVehicleYear()
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
const makeQuestionInitialDataPromise = makeQuestion.methods.loadInitialData();
|
||||||
|
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
return this.mainStore.order.vehicle.year;
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultKey: "makeQuestionInitialData",
|
||||||
|
promise: makeQuestionInitialDataPromise,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
// Call the "next" function to complete the transition to this page.
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.$refs.makeQuestion.initializeComponent(
|
||||||
|
resultMap.makeQuestionInitialData
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
backButtonAction() {
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
arePagePrerequisitesValid() {
|
||||||
|
if (this.mainStore.order.vehicle.year){
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
makeQuestion,
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
vehicleBanner,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectedMake(make) {
|
||||||
|
this.mainStore.updateVehicleMake(make);
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.SELECTED_MAKE,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
describe("model-question.vue", () => {
|
||||||
|
test("Selected model is emitted upon selection.", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({ modelValueProp: "Accord" });
|
||||||
|
const modelToSelect = "Civic";
|
||||||
|
|
||||||
|
//Act
|
||||||
|
wrapper.setValue({ selectedModel: modelToSelect });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
||||||
|
{ selectedModel: "Civic" },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe("model-question.vue", () => {
|
||||||
|
test("Data from store api are used as radio question answers.", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, cmsContent } = setupMocks({
|
||||||
|
dataFromStoreApi: ["accord", "civic", "insight"],
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
const initialData = modelQuestion.methods.loadInitialData.call(wrapper.vm);
|
||||||
|
modelQuestion.methods.initializeComponent.call(
|
||||||
|
wrapper.vm,
|
||||||
|
initialData
|
||||||
|
);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
const buttonQuestionComponent = await wrapper.findComponent({
|
||||||
|
name: "buttonQuestion",
|
||||||
|
});
|
||||||
|
expect(buttonQuestionComponent.attributes("answers")).toBe(
|
||||||
|
"accord,civic,insight"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
modelValueProp = "1900",
|
||||||
|
cmsQuestionText = "CMS text goes here",
|
||||||
|
dataFromStoreApi = [],
|
||||||
|
}) {
|
||||||
|
//Mock store
|
||||||
|
const store = useMainStore();
|
||||||
|
store.getVehicleModels = jest.fn(() => dataFromStoreApi);
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions();
|
||||||
|
|
||||||
|
//Mock props
|
||||||
|
mountOptions.propsData = {
|
||||||
|
modelValue: modelValueProp,
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallowMount(modelQuestion, mountOptions);
|
||||||
|
|
||||||
|
//Mock CMS content
|
||||||
|
const cmsContent = {
|
||||||
|
QuestionText: cmsQuestionText,
|
||||||
|
};
|
||||||
|
return { wrapper, cmsContent };
|
||||||
|
}
|
||||||
56
src/layouts/vehicle-model/model-question/model-question.vue
Normal file
56
src/layouts/vehicle-model/model-question/model-question.vue
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<buttonQuestion
|
||||||
|
class="radioQuestion"
|
||||||
|
isOverflowScrollable
|
||||||
|
selectingInitiatesLoad
|
||||||
|
:questionText="questionText"
|
||||||
|
:answers="models"
|
||||||
|
groupName="ChooseVehicleModel"
|
||||||
|
textPosition="text-start"
|
||||||
|
v-model="selectedValue"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "model-question",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
models: Array,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: String,
|
||||||
|
cmsWidgetName: String,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
questionText(){
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
|
||||||
|
},
|
||||||
|
selectedValue: {
|
||||||
|
get: function() {
|
||||||
|
return this.modelValue
|
||||||
|
},
|
||||||
|
set: function(newValue) {
|
||||||
|
this.$emit("update:modelValue", newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadInitialData() {
|
||||||
|
return useMainStore().getVehicleModels();
|
||||||
|
},
|
||||||
|
initializeComponent(initialData) {
|
||||||
|
this.models = initialData;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
138
src/layouts/vehicle-model/vehicle-model.spec.js
Normal file
138
src/layouts/vehicle-model/vehicle-model.spec.js
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
// Components
|
||||||
|
import vehicleModel from "@/layouts/vehicle-model/vehicle-model.vue";
|
||||||
|
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
// Mock our module for promises.
|
||||||
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
settleAllPromises: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock fetchCmsContentForPage
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("vehicle-model.vue", () => {
|
||||||
|
test("Model question component is initized with api data", async () => {
|
||||||
|
//Arange
|
||||||
|
const modelQuestionInitialData = ["accord", "civic", "insight"];
|
||||||
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
|
modelQuestionInitialData: modelQuestionInitialData,
|
||||||
|
});
|
||||||
|
//Act
|
||||||
|
vehicleModel.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-model" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
//Assert
|
||||||
|
apiPromise.finally(() => {
|
||||||
|
expect(modelQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
||||||
|
modelQuestionInitialData
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("vehicle-model.vue", () => {
|
||||||
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
|
pageHeaderWidgetHeaderText: "Select a model to get started",
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
//Act
|
||||||
|
vehicleModel.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-model" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
wrapper.vm.backButtonAction();
|
||||||
|
await nextTick();
|
||||||
|
//Assert
|
||||||
|
apiPromise.finally(() => {
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe("vehicle-model.vue", () => {
|
||||||
|
test("Make set, arePagePrerequisitesValid should be true ", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
useMainStore().order.vehicle.make = "Honda";
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleModel.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-model" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
buttonQuestionContent = {},
|
||||||
|
modelQuestionInitialData = {},
|
||||||
|
pageHeaderWidgetHeaderText = {},
|
||||||
|
mountOptionsMockData = {},
|
||||||
|
}) {
|
||||||
|
//Mock api responses
|
||||||
|
const apiResponses = {
|
||||||
|
cmsContent: {
|
||||||
|
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
|
||||||
|
VehicleModelQuestion: buttonQuestionContent,
|
||||||
|
VehicleBannerWidget: {
|
||||||
|
GenericVehicleImage:
|
||||||
|
"https://digitalisscms.dev.safelite.io/images/default-source/default-album/blurred-image.jpg",
|
||||||
|
},
|
||||||
|
FunnelHeaderWidget: {
|
||||||
|
LogoImage:
|
||||||
|
"https://digitalisscms.dev.safelite.io/images/default-source/default-album/logos/insuranceLogo.jpg",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
modelQuestionInitialData: modelQuestionInitialData,
|
||||||
|
};
|
||||||
|
const apiPromise = Promise.resolve(apiResponses);
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiPromise);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
|
//Mock model question methods
|
||||||
|
modelQuestion.methods = {
|
||||||
|
loadInitialData: jest.fn(),
|
||||||
|
initializeComponent: jest.fn(),
|
||||||
|
};
|
||||||
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
|
const wrapper = shallowMount(vehicleModel, mountOptions);
|
||||||
|
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||||
|
|
||||||
|
const modelQuestionWrapper = wrapper.findComponent({ name: "modelQuestion" });
|
||||||
|
modelQuestionWrapper.vm.initializeComponent =
|
||||||
|
modelQuestion.methods.initializeComponent;
|
||||||
|
|
||||||
|
return { wrapper, apiPromise };
|
||||||
|
}
|
||||||
103
src/layouts/vehicle-model/vehicle-model.vue
Normal file
103
src/layouts/vehicle-model/vehicle-model.vue
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
<template>
|
||||||
|
<div class="page-container-grouped-styles">
|
||||||
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
|
<div class="select-car">
|
||||||
|
<div class="select-car-form rounded text-center">
|
||||||
|
<vehicleBanner cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage />
|
||||||
|
<siteSubHeader
|
||||||
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
|
:hasBackButton="true"
|
||||||
|
@click-event="backButtonAction"
|
||||||
|
backButtonAccessibleText = "Change vehicle make"
|
||||||
|
/>
|
||||||
|
<div class="fade-on-route-transition">
|
||||||
|
<modelQuestion v-model="selectedModel" ref="modelQuestion" cmsWidgetName="VehicleModelQuestion" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
||||||
|
import siteHeader from "@/common-components/site-header/site-header";
|
||||||
|
import siteSubHeader from "@/common-components/site-sub-header/site-sub-header";
|
||||||
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "vehicle-model",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedModel: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
const modelQuestionInitialDataPromise =
|
||||||
|
modelQuestion.methods.loadInitialData();
|
||||||
|
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultKey: "modelQuestionInitialData",
|
||||||
|
promise: modelQuestionInitialDataPromise,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
// Call the "next" function to complete the transition to this page.
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.$refs.modelQuestion.initializeComponent(
|
||||||
|
resultMap.modelQuestionInitialData
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
backButtonAction() {
|
||||||
|
// route to move backwards
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
arePagePrerequisitesValid()
|
||||||
|
{
|
||||||
|
if(this.mainStore.order.vehicle.make){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
selectedModel(model) {
|
||||||
|
this.mainStore.updateVehicleYear(model);
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.SELECTED_MODEL,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
modelQuestion,
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
vehicleBanner,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -5,6 +5,7 @@ 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 baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
|
|
@ -43,6 +44,27 @@ describe("vehicle-year.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("vehicle-year.vue", () => {
|
||||||
|
test("arePagePrerequisitesValid should be true ", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleYear.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-make" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
vehicleYearQuestionCmsContent = {},
|
vehicleYearQuestionCmsContent = {},
|
||||||
yearQuestionInitialData = {},
|
yearQuestionInitialData = {},
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<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 cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage="true"/>
|
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true"/>
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
<div class="fade-on-route-transition">
|
<div class="fade-on-route-transition">
|
||||||
<yearQuestion
|
<yearQuestion
|
||||||
|
|
@ -65,6 +65,22 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
selectedYear(year) {
|
||||||
|
const parsedYear = parseInt(year);
|
||||||
|
this.mainStore.updateVehicleYear(parsedYear);
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.SELECTED_YEAR,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arePagePrerequisitesValid() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
yearQuestion,
|
yearQuestion,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,23 @@ import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import { useMainStore } from "@/store";
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
|
describe("year-question.vue", () => {
|
||||||
|
test("Selected year is emitted upon selection.", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({ modelValueProp: "2020" });
|
||||||
|
const yearToSelect = "2021";
|
||||||
|
|
||||||
|
//Act
|
||||||
|
wrapper.setValue({ modelValue: yearToSelect });
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
||||||
|
{ modelValue: "2021" },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("year-question.vue", () => {
|
describe("year-question.vue", () => {
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
test("Data from store api are used as radio question answers.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default {
|
||||||
action: "",
|
action: "",
|
||||||
event: pageEvent,
|
event: pageEvent,
|
||||||
shouldUseSessionId: false,
|
shouldUseSessionId: false,
|
||||||
experimentsForUser: useMainStore.getters.applicationUserObj.experiments,
|
experimentsForUser: useMainStore.applicationUserObj.experiments,
|
||||||
};
|
};
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
|
baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
|
||||||
|
|
@ -53,7 +53,7 @@ export default {
|
||||||
label: label,
|
label: label,
|
||||||
value: value,
|
value: value,
|
||||||
shouldUseSessionId: false,
|
shouldUseSessionId: false,
|
||||||
experimentsForUser: useMainStore.getters.applicationUserObj.experiments,
|
experimentsForUser: useMainStore.applicationUserObj.experiments,
|
||||||
};
|
};
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
|
baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
|
||||||
|
|
@ -93,7 +93,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
pushExperimentsToDataLayer() {
|
pushExperimentsToDataLayer() {
|
||||||
const experiments = useMainStore.getters.applicationUserObj.experiments;
|
const experiments = useMainStore.applicationUserObj.experiments;
|
||||||
experiments?.forEach((exp) => {
|
experiments?.forEach((exp) => {
|
||||||
// Set Google Dimension Index based on experiment settings.
|
// Set Google Dimension Index based on experiment settings.
|
||||||
let googleDimensionIndex = 99;
|
let googleDimensionIndex = 99;
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ describe("analyticsMixin.js", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
|
expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer));
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
test("Experiments, should push to dataLayer with default Google Custom Dimension Index", () => {
|
test("Experiments, should push to dataLayer with default Google Custom Dimension Index", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
window.dataLayer = [];
|
window.dataLayer = [];
|
||||||
|
|
@ -154,7 +154,7 @@ describe("analyticsMixin.js", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useMainStore.getters = {
|
useMainStore.getters = {
|
||||||
applicationUser: {
|
applicationUserObj: {
|
||||||
experiments: [
|
experiments: [
|
||||||
{
|
{
|
||||||
settings: {},
|
settings: {},
|
||||||
|
|
@ -202,7 +202,7 @@ describe("analyticsMixin.js", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useMainStore.getters = {
|
useMainStore.getters = {
|
||||||
applicationUser: {
|
applicationUserObj: {
|
||||||
experiments: [
|
experiments: [
|
||||||
{
|
{
|
||||||
settings: { "Google Custom Dimension Index": "5" },
|
settings: { "Google Custom Dimension Index": "5" },
|
||||||
|
|
@ -227,7 +227,7 @@ describe("analyticsMixin.js", () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
test("Obj is not null after action prepended", () => {
|
test("Obj is not null after action prepended", () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const obj = { baseMethodName: "testMethodName", data: "testData" };
|
const obj = { baseMethodName: "testMethodName", data: "testData" };
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@ import { useMainStore } from "@/store";
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
hasSettingEqualTo(settingName, settingValue) {
|
hasSettingEqualTo(settingName, settingValue) {
|
||||||
return useMainStore.getters.experimentSettings[settingName] == settingValue;
|
return useMainStore.experimentSettings[settingName] == settingValue;
|
||||||
},
|
},
|
||||||
hasSetting(settingName) {
|
hasSetting(settingName) {
|
||||||
return Object.hasOwn( useMainStore.getters.experimentSettings, settingName);
|
return Object.hasOwn( useMainStore.experimentSettings, settingName);
|
||||||
},
|
},
|
||||||
getSettingValue(settingName) {
|
getSettingValue(settingName) {
|
||||||
return this.hasSetting(settingName)
|
return this.hasSetting(settingName)
|
||||||
? useMainStore.getters.experimentSettings[settingName]
|
? useMainStore.experimentSettings[settingName]
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@ export const issPageValues = {
|
||||||
WELCOME_PAGE: "welcome-page",
|
WELCOME_PAGE: "welcome-page",
|
||||||
VEHICLE_MAKE: "vehicle-make",
|
VEHICLE_MAKE: "vehicle-make",
|
||||||
VEHICLE_YEAR: "vehicle-year",
|
VEHICLE_YEAR: "vehicle-year",
|
||||||
|
VEHICLE_MODEL: "vehicle-model"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -5,7 +5,9 @@ const navigationScenarios = {
|
||||||
|
|
||||||
// YMMS
|
// YMMS
|
||||||
SELECTED_YEAR: "SELECTED_YEAR",
|
SELECTED_YEAR: "SELECTED_YEAR",
|
||||||
|
SELECTED_MAKE: "SELECTED_MAKE",
|
||||||
|
SELECTED_MODEL: "SELECTED_MODEL",
|
||||||
|
|
||||||
// TESTING
|
// TESTING
|
||||||
CLICKED_TEST: "CLICKED_TEST"
|
CLICKED_TEST: "CLICKED_TEST"
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,38 @@ const routingTable = function(store) {
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationIssPageValue: issPageValues.WELCOME_PAGE
|
destinationIssPageValue: issPageValues.WELCOME_PAGE
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.SELECTED_YEAR,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_MAKE
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
issPageValue: issPageValues.VEHICLE_MAKE,
|
||||||
|
maps: [
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_YEAR
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.SELECTED_MAKE,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_MODEL
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
issPageValue: issPageValues.VEHICLE_MODEL,
|
||||||
|
maps: [
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_MAKE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.SELECTED_MODEL,
|
||||||
|
destinationUrl: "https://www.google.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
issPageValue: issPageValues.WELCOME_PAGE,
|
issPageValue: issPageValues.WELCOME_PAGE,
|
||||||
maps: [
|
maps: [
|
||||||
|
|
@ -26,6 +56,7 @@ const routingTable = function(store) {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineStore, createPinia } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { endpoints } from "@/constants/endpoints.js";
|
import { endpoints } from "@/constants/endpoints.js";
|
||||||
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
|
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
|
||||||
import globalMethods from "@/global-methods";
|
import globalMethods from "@/global-methods";
|
||||||
|
|
@ -160,6 +160,22 @@ export const useMainStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getVehicleMakes() {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleMakes.method,
|
||||||
|
endpoint: endpoints.GetVehicleMakes.url + this.order.vehicle.year,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getVehicleModels() {
|
||||||
|
return globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetVehicleModels.method,
|
||||||
|
endpoint: `${endpoints.GetVehicleModels.url}/${this.order.vehicle.year}/${this.order.vehicle.make}`,
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Vehicle API Actions
|
// Vehicle API Actions
|
||||||
updateVehicleYear(year)
|
updateVehicleYear(year)
|
||||||
{
|
{
|
||||||
|
|
@ -168,6 +184,20 @@ export const useMainStore = defineStore({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateVehicleMake(make)
|
||||||
|
{
|
||||||
|
if (this.order.vehicle.make !== make) {
|
||||||
|
this.order.vehicle.make = make;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateVehicleModel(model)
|
||||||
|
{
|
||||||
|
if (this.order.vehicle.model !== model) {
|
||||||
|
this.order.vehicle.model = model;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// populate initial state
|
// populate initial state
|
||||||
populateInitialState()
|
populateInitialState()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
6
src/styles/mixins/customMixins.scss
Normal file
6
src/styles/mixins/customMixins.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
//Custom Mixins
|
||||||
|
|
||||||
|
//Blue gradient background mixin
|
||||||
|
@mixin blue-gradient {
|
||||||
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ module.exports = {
|
||||||
@import "@/styles/ux-variables.scss";
|
@import "@/styles/ux-variables.scss";
|
||||||
@import "./node_modules/bootstrap/scss/variables";
|
@import "./node_modules/bootstrap/scss/variables";
|
||||||
@import "./node_modules/bootstrap/scss/mixins";
|
@import "./node_modules/bootstrap/scss/mixins";
|
||||||
|
@import "@/styles/mixins/customMixins";
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ module.exports = {
|
||||||
@import "@/styles/ux-variables.scss";
|
@import "@/styles/ux-variables.scss";
|
||||||
@import "./node_modules/bootstrap/scss/variables";
|
@import "./node_modules/bootstrap/scss/variables";
|
||||||
@import "./node_modules/bootstrap/scss/mixins";
|
@import "./node_modules/bootstrap/scss/mixins";
|
||||||
|
@import "@/styles/mixins/customMixins";
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
devtool: 'source-map'
|
devtool: 'source-map'
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue