Merged from develop and updated unit tests
This commit is contained in:
commit
3616a7d75f
40 changed files with 1462 additions and 428 deletions
|
|
@ -8,6 +8,13 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- Modal -->
|
<!-- Modal -->
|
||||||
<div class="modal fade" id="footerModal" tabindex="-1" aria-labelledby="footerModalLabel" aria-hidden="true" v-on="{ 'show.bs.modal' : show, 'hide.bs.modal' : hide }" :style="`height: calc(100% - ${currentFooterAndHeaderHeight}px);`">
|
<div class="modal fade" id="footerModal" tabindex="-1" aria-labelledby="footerModalLabel" aria-hidden="true" v-on="{ 'show.bs.modal' : show, 'hide.bs.modal' : hide }" :style="`height: calc(100% - ${currentFooterAndHeaderHeight}px);`">
|
||||||
|
<div class="menu-modal-container">
|
||||||
|
<button class="menu-button" type="button" :class="[isActive ? 'active' : '']" data-bs-toggle="modal" data-bs-target="#footerModal" aria-label="Hamburger Menu (modal window)">
|
||||||
|
<div class="bar1"></div>
|
||||||
|
<div class="bar2"></div>
|
||||||
|
<div class="bar3"></div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="modal-dialog modal-fullscreen">
|
<div class="modal-dialog modal-fullscreen">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header visually-hidden">
|
<div class="modal-header visually-hidden">
|
||||||
|
|
@ -100,6 +107,8 @@ export default {
|
||||||
height: calc(100% - 72px);
|
height: calc(100% - 72px);
|
||||||
top: 72px;
|
top: 72px;
|
||||||
border-top: 1px solid $gray-300;
|
border-top: 1px solid $gray-300;
|
||||||
|
overflow-x: visible;
|
||||||
|
overflow-y: visible;
|
||||||
.modal-body {
|
.modal-body {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
|
|
@ -114,6 +123,45 @@ export default {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
|
.menu-modal-container {
|
||||||
|
position: absolute;
|
||||||
|
padding: 1.47rem 1rem 1.47rem 1.47rem;
|
||||||
|
right: 0;
|
||||||
|
top: -4.5rem;
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
&.menu-button {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: $white;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0;//Required to prevent 'squish' on iPhone
|
||||||
|
z-index: 1056;
|
||||||
|
.bar1,
|
||||||
|
.bar2,
|
||||||
|
.bar3 {
|
||||||
|
width: 14px;
|
||||||
|
height: 2px;
|
||||||
|
background-color: $blue;
|
||||||
|
margin: 1px 0;
|
||||||
|
transition: 0.25s;
|
||||||
|
}
|
||||||
|
&.active .bar1 {
|
||||||
|
transform: rotate(-45deg) translate(-3px, 3px);
|
||||||
|
}
|
||||||
|
&.active .bar2 {opacity: 0;}
|
||||||
|
&.active .bar3 {
|
||||||
|
transform: rotate(45deg) translate(-3px, -3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//.modal-backdrop styles are in common-styles.scss
|
//.modal-backdrop styles are in common-styles.scss
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import buttonQuestion from "@/common-components/button-question/button-question";
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
|
import { useValidateForm } from "vee-validate";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "questionChain",
|
name: "questionChain",
|
||||||
|
|
@ -32,38 +33,46 @@ export default {
|
||||||
validationRules: String,
|
validationRules: String,
|
||||||
modelValue: Array,
|
modelValue: Array,
|
||||||
partIndex: Number,
|
partIndex: Number,
|
||||||
|
key: String,
|
||||||
},
|
},
|
||||||
created() {
|
async created() {
|
||||||
|
// validate form upon create to prevent out of sync / persistent valid states
|
||||||
|
await useValidateForm(); // do a test validation check, without triggering full validation
|
||||||
|
|
||||||
this.questionData.partQuestions.map((q, i) => {
|
this.questionData.partQuestions.map((q, i) => {
|
||||||
let answerPair = [];
|
let answerPair = [];
|
||||||
const eachQuestion = {
|
const question = {
|
||||||
questionText: q.questionText,
|
questionText: q.questionText,
|
||||||
questionSequence: q.questionSequence,
|
questionSequence: q.questionSequence,
|
||||||
answers: q.answers.map((a) => {
|
answers: q.answers.map((a) => {
|
||||||
answerPair.push(a.nextQuestionSequence ? a.nextQuestionSequence : a.answerResult);
|
answerPair.push(a.nextQuestionSequence ? a.nextQuestionSequence : a.answerResult);
|
||||||
return {
|
return {
|
||||||
Text: a.answerText,
|
Text: a.answerText + " (" + a.answerResult + a.nextQuestionSequence + ")",
|
||||||
// Name will either be nextQuestionSequence or answerResult
|
// Name will either be nextQuestionSequence or answerResult
|
||||||
// Name will be used by list-button as the input value.
|
// Name will be used by list-button as the input value.
|
||||||
// It must be a single string or number, so concatenating together a string with
|
// It must be a single string or number, so concatenating together a string with
|
||||||
// 4 pieces of data separated by pipe characters:
|
// 4 pieces of data separated by pipe characters:
|
||||||
// question number|type of answer|answer value|answer text
|
// question number|type of answer|answer value|answer text
|
||||||
Name: a.nextQuestionSequence ?
|
Name: a.nextQuestionSequence ?
|
||||||
q.questionSequence + "|nextQuestion|" + a.nextQuestionSequence + "|" + a.answerText :
|
q.questionSequence + "|nextQuestion|" + a.nextQuestionSequence + "|" + a.answerText :
|
||||||
q.questionSequence + "|answer|" + a.answerResult + "|" + a.answerText,
|
q.questionSequence + "|answer|" + a.answerResult + "|" + a.answerText,
|
||||||
nextQuestionSequence: a.nextQuestionSequence,
|
nextQuestionSequence: a.nextQuestionSequence,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
answerSelected: "",
|
answerSelected: "",
|
||||||
};
|
};
|
||||||
eachQuestion.answerPair = answerPair;
|
question.answerPair = answerPair;
|
||||||
this.questions.push(eachQuestion);
|
if (!q.suppressQuestion) {
|
||||||
|
this.questions.push(question);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
// set this.currentQuestionNum to first valid question
|
||||||
|
this.currentQuestionNum = this.questions[1].questionSequence;
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
selectedValue: {
|
selectedValue: {
|
||||||
get: function() {
|
get: function() {
|
||||||
return "";
|
return this.modelValue[0];
|
||||||
},
|
},
|
||||||
set: function(returnedAnswer) {
|
set: function(returnedAnswer) {
|
||||||
const isQuestionChainComplete = this.handleReturnedAnswer(returnedAnswer);
|
const isQuestionChainComplete = this.handleReturnedAnswer(returnedAnswer);
|
||||||
|
|
@ -78,7 +87,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleReturnedAnswer(returnedAnswer) { // returns either a final answer or Boolean false
|
handleReturnedAnswer(returnedAnswer) { // this method will return either a final answer or Boolean false
|
||||||
if (!returnedAnswer) { return false }
|
if (!returnedAnswer) { return false }
|
||||||
|
|
||||||
// Example returnedAnswers:
|
// Example returnedAnswers:
|
||||||
|
|
@ -86,25 +95,25 @@ export default {
|
||||||
// "5|answer|DW02104|Yes"
|
// "5|answer|DW02104|Yes"
|
||||||
|
|
||||||
const returnedAnswerArray = returnedAnswer.split("|");
|
const returnedAnswerArray = returnedAnswer.split("|");
|
||||||
const questionNum = returnedAnswerArray[0];
|
const questionNum = parseInt(returnedAnswerArray[0]);
|
||||||
const questionType = returnedAnswerArray[1];
|
const questionType = returnedAnswerArray[1];
|
||||||
const questionAnswer = returnedAnswerArray[2];
|
const questionAnswer = returnedAnswerArray[2];
|
||||||
const questionAnswerText = returnedAnswerArray[3];
|
const questionAnswerText = returnedAnswerArray[3];
|
||||||
|
|
||||||
// remove all previous answers after the index of this one in questions
|
this.questions.forEach((q) => {
|
||||||
this.questions.map((q) => {
|
// mark this question as "answered"
|
||||||
if ((q.questionSequence > questionNum) || (q.answerPair?.includes(questionAnswer))) {
|
if (q.questionSequence === questionNum) {
|
||||||
q.answerSelected = "";
|
q.answerSelected = questionAnswerText;
|
||||||
|
q.answerNumber = questionNum;
|
||||||
|
}
|
||||||
|
// remove all previous answers after the index of this one in questions
|
||||||
|
if ((q.questionSequence > questionNum)) {
|
||||||
|
delete q.answerSelected;
|
||||||
}
|
}
|
||||||
return q;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// set this question as "answered"
|
|
||||||
this.questions[questionNum].answerSelected = questionAnswerText;
|
|
||||||
this.questions[questionNum].answerNumber = questionNum;
|
|
||||||
|
|
||||||
// update to next question index
|
// update to next question index
|
||||||
this.currentQuestionNum = questionType === "nextQuestion" ? parseInt(questionAnswer) : parseInt(questionNum); // update count to display next question
|
this.currentQuestionNum = questionType === "nextQuestion" ? parseInt(questionAnswer) : questionNum; // update count to display next question
|
||||||
|
|
||||||
// return false if there's a nextQuestion... or return an object with "final" answers
|
// return false if there's a nextQuestion... or return an object with "final" answers
|
||||||
if (questionType === "nextQuestion") {
|
if (questionType === "nextQuestion") {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ const applicationConfig = {
|
||||||
ANALYTICS_SESSION_TIMEOUT_MINUTES: 30,
|
ANALYTICS_SESSION_TIMEOUT_MINUTES: 30,
|
||||||
SAVED_SESSION_TIMEOUT_DAYS: 45,
|
SAVED_SESSION_TIMEOUT_DAYS: 45,
|
||||||
COOKIE_PATH: "/",
|
COOKIE_PATH: "/",
|
||||||
CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT // "Localhost", "Dev", "QA", and "Prod"
|
CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod"
|
||||||
|
APPLICATION_NAME: "FixMyGlass",
|
||||||
|
SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass"
|
||||||
};
|
};
|
||||||
|
|
||||||
export { applicationConfig };
|
export { applicationConfig };
|
||||||
|
|
@ -72,7 +72,7 @@ const endpoints = {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
LogExperimentExposureIfAssigned:{
|
LogExperimentExposureIfAssigned:{
|
||||||
url: "/analytics/api/v1/analytics/log-experiment-exposure",
|
url: "/experiments/api/v1/experiments/log-exposure",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
LogPageView:{
|
LogPageView:{
|
||||||
|
|
@ -90,6 +90,10 @@ const endpoints = {
|
||||||
GetExperimentsByUser: {
|
GetExperimentsByUser: {
|
||||||
url: "/analytics/api/v1/analytics/get-experiments",
|
url: "/analytics/api/v1/analytics/get-experiments",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
},
|
||||||
|
RunExperimentsForTrigger: {
|
||||||
|
url: "/experiments/api/v1/experiments/run",
|
||||||
|
method: "POST"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ const experimentUniverses = {
|
||||||
const experimentSettings = {
|
const experimentSettings = {
|
||||||
GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index'
|
GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const experimentTriggers = {
|
||||||
|
SITE_ENTRY: "SiteEntry",
|
||||||
|
PAGE_ENTRY: "PageEntry"
|
||||||
|
};
|
||||||
|
|
||||||
export { experimentUniverses, experimentSettings};
|
export { experimentUniverses, experimentSettings, experimentTriggers };
|
||||||
|
|
||||||
|
|
@ -30,6 +30,7 @@ const storeActions = {
|
||||||
LOG_CUSTOM_EVENT: "logCustomEvent",
|
LOG_CUSTOM_EVENT: "logCustomEvent",
|
||||||
INITIALIZE_SESSION: "initializeSession",
|
INITIALIZE_SESSION: "initializeSession",
|
||||||
GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser",
|
GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser",
|
||||||
|
RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger",
|
||||||
CLEAR_VIN: "clearVin",
|
CLEAR_VIN: "clearVin",
|
||||||
RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise",
|
RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise",
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ const storeMutations = {
|
||||||
UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace",
|
UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace",
|
||||||
UPDATE_PART_QUESTION_ANSWERS: "updatePartQuestionAnswers",
|
UPDATE_PART_QUESTION_ANSWERS: "updatePartQuestionAnswers",
|
||||||
UPDATE_GLASS_PARTS: "updateGlassParts",
|
UPDATE_GLASS_PARTS: "updateGlassParts",
|
||||||
|
UPDATE_OTHER_PARTS: "updateOtherParts",
|
||||||
|
|
||||||
UPDATE_REGISTRATION_LICENSE_PLATE : "updateRegistrationLicensePlate",
|
UPDATE_REGISTRATION_LICENSE_PLATE : "updateRegistrationLicensePlate",
|
||||||
UPDATE_REGISTRATION_ADDRESS: "updateRegistrationAddress",
|
UPDATE_REGISTRATION_ADDRESS: "updateRegistrationAddress",
|
||||||
|
|
@ -39,6 +40,7 @@ const storeMutations = {
|
||||||
UPDATE_REFERRAL_DATE: "updateReferralDate",
|
UPDATE_REFERRAL_DATE: "updateReferralDate",
|
||||||
UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId",
|
UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId",
|
||||||
UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber",
|
UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber",
|
||||||
|
UPDATE_EON: "updateEON",
|
||||||
UPDATE_SAVED_SESSION_ID: "updateSavedSessionId",
|
UPDATE_SAVED_SESSION_ID: "updateSavedSessionId",
|
||||||
UPDATE_CRM_CUSTOMER_ID: "updateCrmCustomerId",
|
UPDATE_CRM_CUSTOMER_ID: "updateCrmCustomerId",
|
||||||
|
|
||||||
|
|
@ -52,13 +54,17 @@ const storeMutations = {
|
||||||
RESET_REGISTRATION_STATE: "resetRegistrationState",
|
RESET_REGISTRATION_STATE: "resetRegistrationState",
|
||||||
RESET_GLASS_PARTS_STATE: "resetGlassPartsState",
|
RESET_GLASS_PARTS_STATE: "resetGlassPartsState",
|
||||||
RESET_STATE: "resetState",
|
RESET_STATE: "resetState",
|
||||||
|
RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise",
|
||||||
|
|
||||||
// OTHER MUTATIONS
|
// OTHER MUTATIONS
|
||||||
UPDATE_PAGE_DATA: "updatePageData",
|
UPDATE_PAGE_DATA: "updatePageData",
|
||||||
UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation",
|
UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation",
|
||||||
UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise",
|
UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise",
|
||||||
UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited",
|
UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited",
|
||||||
RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise",
|
|
||||||
|
// EXPERIMENT MUTATIONS
|
||||||
|
UPDATE_EXPERIMENTS: "updateExperiments",
|
||||||
|
UPDATE_TRIGGERED_SITE_ENTRY: "updateTriggeredSiteEntry",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { storeMutations };
|
export { storeMutations };
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita
|
||||||
if (toRoute.query[queryStrings.START_TYPE] === 'fmg') {
|
if (toRoute.query[queryStrings.START_TYPE] === 'fmg') {
|
||||||
// If they have an existing order, return 'heritage' for the page name.
|
// If they have an existing order, return 'heritage' for the page name.
|
||||||
if (existingHeritageOrder) {
|
if (existingHeritageOrder) {
|
||||||
return 'heritage';
|
return fmgPageValues.HERITAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await getLatestPageForRedirection();
|
return await getLatestPageForRedirection();
|
||||||
|
|
@ -61,11 +61,16 @@ async function getLatestPageForRedirection() {
|
||||||
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
||||||
// This also works if a user has a 'fmg' start_type query string but no current order.
|
// This also works if a user has a 'fmg' start_type query string but no current order.
|
||||||
// That shouldn't happen, but it's possible.
|
// That shouldn't happen, but it's possible.
|
||||||
const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default;
|
const vehicleMakeComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MAKE);
|
||||||
const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default;
|
const vehicleModelComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MODEL);
|
||||||
const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default;
|
const vehicleStyleComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_STYLE);
|
||||||
const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default;
|
const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);
|
||||||
|
const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
|
||||||
|
const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
|
||||||
|
const partQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.PART_QUESTIONS);
|
||||||
|
const vehiclePartsComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_PARTS);
|
||||||
|
const moldingQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.MOLDING_QUESTIONS);
|
||||||
|
const capabilityQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.CAPABILITY_QUESTIONS);
|
||||||
|
|
||||||
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VEHICLE_YEAR;
|
return fmgPageValues.VEHICLE_YEAR;
|
||||||
|
|
@ -75,15 +80,28 @@ async function getLatestPageForRedirection() {
|
||||||
return fmgPageValues.VEHICLE_MODEL;
|
return fmgPageValues.VEHICLE_MODEL;
|
||||||
} else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
} else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VEHICLE_STYLE;
|
return fmgPageValues.VEHICLE_STYLE;
|
||||||
} else if (store.getters.damage.isRepair == null || !store.getters.vehicle.carId) {
|
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VEHICLE_DAMAGE;
|
return fmgPageValues.VEHICLE_DAMAGE;
|
||||||
} else {
|
} else {
|
||||||
if (store.getters.vehicle.vin) {
|
if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||||
|
return fmgPageValues.CAPABILITY_QUESTIONS;
|
||||||
|
}
|
||||||
|
else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||||
|
return fmgPageValues.MOLDING_QUESTIONS;
|
||||||
|
}
|
||||||
|
else if (vehiclePartsComponent.methods.arePagePrerequisitesValid()) {
|
||||||
|
return fmgPageValues.VEHICLE_PARTS;
|
||||||
|
}
|
||||||
|
else if (partQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||||
|
return fmgPageValues.PART_QUESTIONS;
|
||||||
|
}
|
||||||
|
else if (vinLookupComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VIN_LOOKUP;
|
return fmgPageValues.VIN_LOOKUP;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return fmgPageValues.ESTIMATE;
|
return fmgPageValues.ESTIMATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -126,4 +144,8 @@ function isVinRelatedPage(toRoute) {
|
||||||
fmgPageValue === fmgPageValues.ADDRESS_LOOKUP ||
|
fmgPageValue === fmgPageValues.ADDRESS_LOOKUP ||
|
||||||
fmgPageValue === fmgPageValues.ADDRESS_VEHICLES ||
|
fmgPageValue === fmgPageValues.ADDRESS_VEHICLES ||
|
||||||
fmgPageValue === fmgPageValues.ESTIMATE;
|
fmgPageValue === fmgPageValues.ESTIMATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLazyLoadedComponent(pageName) {
|
||||||
|
return (await lazyLoadComponent(pageName)()).default;
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import { storeActions } from "@/constants/store-actions";
|
||||||
import { setupMocksForJsFiles, getMockOrderInfo } from "@/helpers/unit-test-helper.js";
|
import { setupMocksForJsFiles, getMockOrderInfo } from "@/helpers/unit-test-helper.js";
|
||||||
import { externalUrls } from "@/router/router-constants/externalUrl-values";
|
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 store from "@/store";
|
import store from "@/store";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
|
@ -15,278 +16,269 @@ jest.mock("@/router/dynamic-routing/component-loader.js", () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("getPageToRouteExistingOrderTo", () => {
|
describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
test("should return vehicle-year", async () => {
|
||||||
test("getPageToRouteExistingOrderTo, should return vehicle-year", async () => {
|
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {}
|
query: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
lazyLoadComponent
|
mockLazyLoadComponentReturnValues({
|
||||||
.mockReturnValueOnce(() => {
|
[fmgPageValues.VEHICLE_MAKE]: false
|
||||||
return {
|
})
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe('vehicle-year');
|
expect(result).toBe(fmgPageValues.VEHICLE_YEAR);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getPageToRouteExistingOrderTo, should return vehicle-model", async () => {
|
test("should return vehicle-make", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {}
|
query: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
lazyLoadComponent
|
mockLazyLoadComponentReturnValues({
|
||||||
.mockReturnValueOnce(() => {
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
return {
|
[fmgPageValues.VEHICLE_MODEL]: false
|
||||||
default: {
|
})
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe('vehicle-model');
|
expect(result).toBe(fmgPageValues.VEHICLE_MAKE);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getPageToRouteExistingOrderTo, should return vehicle-damage", async () => {
|
test("should return vehicle-model", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {}
|
query: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
lazyLoadComponent
|
mockLazyLoadComponentReturnValues({
|
||||||
.mockReturnValueOnce(() => {
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
return {
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
default: {
|
[fmgPageValues.VEHICLE_STYLE]: false,
|
||||||
methods: {
|
})
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
store.getters.damage.isRepair = undefined;
|
|
||||||
store.getters.vehicle.carId = 'C00000';
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe('vehicle-damage');
|
expect(result).toBe(fmgPageValues.VEHICLE_MODEL);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getPageToRouteExistingOrderTo, should return vin-lookup", async () => {
|
test("should return vehicle-style", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {}
|
query: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
lazyLoadComponent
|
mockLazyLoadComponentReturnValues({
|
||||||
.mockReturnValueOnce(() => {
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
return {
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
default: {
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
methods: {
|
[fmgPageValues.VEHICLE_DAMAGE]: false,
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
store.getters.damage.isRepair = true;
|
|
||||||
store.getters.vehicle.carId = 'C00000';
|
|
||||||
store.getters.vehicle.vin = "1FADP3F26DL212886"
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe('vin-lookup');
|
expect(result).toBe(fmgPageValues.VEHICLE_STYLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getPageToRouteExistingOrderTo, should return estimate", async () => {
|
test("should return vehicle-damage", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {}
|
query: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
lazyLoadComponent
|
mockLazyLoadComponentReturnValues({
|
||||||
.mockReturnValueOnce(() => {
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
return {
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
default: {
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
methods: {
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
[fmgPageValues.ESTIMATE]: false
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.mockReturnValueOnce(() => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
store.getters.damage.isRepair = true;
|
|
||||||
store.getters.vehicle.carId = 'C00000';
|
|
||||||
store.getters.vehicle.vin = null;
|
|
||||||
// Act
|
// Act
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe('estimate');
|
expect(result).toBe(fmgPageValues.VEHICLE_DAMAGE);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => {
|
test("user has YMMS and no vehicle questions > should return vin-lookup", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: false,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.VIN_LOOKUP);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("user has YMMS but no questions or carId > should return estimate", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: false,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.ESTIMATE);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("user has capability questions and molding questions > should return capability questions", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: false,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.CAPABILITY_QUESTIONS);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("user has molding questions and part questions > should return molding questions", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: false,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.MOLDING_QUESTIONS);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("user has vehicle parts questions > should return vehicle-parts", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: true,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.VEHICLE_PARTS);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("user has part questions > should return part-questions", async () => {
|
||||||
|
// Arrange
|
||||||
|
const toRoute = {
|
||||||
|
query: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock out the lazy load calls for all components.
|
||||||
|
mockLazyLoadComponentReturnValues({
|
||||||
|
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||||
|
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||||
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.MOLDING_QUESTIONS]: false,
|
||||||
|
[fmgPageValues.VEHICLE_PARTS]: false,
|
||||||
|
[fmgPageValues.PART_QUESTIONS]: true,
|
||||||
|
[fmgPageValues.VIN_LOOKUP]: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(fmgPageValues.PART_QUESTIONS);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("existing order > should return heritage", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -298,7 +290,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, true);
|
const result = await getPageToRouteExistingOrderTo(toRoute, true);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(result).toBe("heritage");
|
expect(result).toBe(fmgPageValues.HERITAGE);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -401,4 +393,22 @@ describe("navigateToHeritageFunnel", () => {
|
||||||
expect(router.navigateToExternalUrl).toHaveBeenCalled();
|
expect(router.navigateToExternalUrl).toHaveBeenCalled();
|
||||||
saveOrderFunction.mockRestore();
|
saveOrderFunction.mockRestore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `arePagePrerequisitesValidObject` is an object where the keys are fmgPageValue names and the values are booleans that indicate
|
||||||
|
* whether arePagePrerequisitesValid is true or false
|
||||||
|
*/
|
||||||
|
function mockLazyLoadComponentReturnValues(arePagePrerequisitesValidObject = {}) {
|
||||||
|
lazyLoadComponent.mockImplementation((pageName) => {
|
||||||
|
return async () => {
|
||||||
|
return Promise.resolve({
|
||||||
|
default: {
|
||||||
|
methods: {
|
||||||
|
arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(arePagePrerequisitesValidObject[pageName])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,12 @@ export function isSavedSessionStillActive() {
|
||||||
const savedSessionTimeStamp = new Date(getFunnelCookie().SavedSessionTimeoutDate);
|
const savedSessionTimeStamp = new Date(getFunnelCookie().SavedSessionTimeoutDate);
|
||||||
const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp);
|
const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp);
|
||||||
|
|
||||||
if (isSavedSessionTimedOut) {
|
return !isSavedSessionTimedOut;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function to get the date for the saved session timeout.
|
Function to calculate the date for the saved session timeout.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getDateForSavedSessionTimeout() {
|
export function getDateForSavedSessionTimeout() {
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ describe("address-lookup.vue", () => {
|
||||||
await wrapper.vm.backButtonAction();
|
await wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -285,7 +285,7 @@ describe("address-lookup.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, undefined, {}, {}, carsFound);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, undefined, {}, {}, carsFound);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("if the car entered matches one of the vehicles found but the zip is NOT serviceable, do not navigate forward", async () => {
|
test("if the car entered matches one of the vehicles found but the zip is NOT serviceable, do not navigate forward", async () => {
|
||||||
|
|
@ -365,7 +365,7 @@ describe("address-lookup.vue", () => {
|
||||||
await wrapper.vm.navigateForward(carsFound);
|
await wrapper.vm.navigateForward(carsFound);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, undefined, {}, { "displayVehicleChangeAlert": true });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, undefined, {}, { "displayVehicleChangeAlert": true });
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -626,7 +626,9 @@ function setupMocks({ isZipValid = true, isZipServiceable = true, lookupVinbyAdd
|
||||||
],
|
],
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
getters: {
|
getters: {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ describe("addressVehicles.vue", () => {
|
||||||
test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
|
test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.$router.navigate = jest.fn();
|
wrapper.vm.$router.navigateWithoutSaving = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.setData({
|
await wrapper.setData({
|
||||||
|
|
@ -62,7 +62,7 @@ describe("addressVehicles.vue", () => {
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toBeCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalled();
|
||||||
|
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
@ -111,7 +111,7 @@ describe("addressVehicles.vue", () => {
|
||||||
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
|
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
|
||||||
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
|
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
|
||||||
wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
|
wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
|
||||||
wrapper.vm.$router.navigate = jest.fn();
|
wrapper.vm.$router.navigateWithSaving = jest.fn();
|
||||||
wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {});
|
wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -131,7 +131,7 @@ describe("addressVehicles.vue", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
|
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
|
||||||
wrapper.vm.$router.navigate = jest.fn();
|
wrapper.vm.$router.navigateWithSaving = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.setData({
|
await wrapper.setData({
|
||||||
|
|
@ -142,7 +142,7 @@ describe("addressVehicles.vue", () => {
|
||||||
await wrapper.vm.navigateForward();
|
await wrapper.vm.navigateForward();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toBeCalledTimes(1);
|
||||||
|
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return true; // TODO - DO TRUE TEST OF PAGEDATA
|
return false; // TODO - DO TRUE TEST OF PAGEDATA
|
||||||
// return Object.keys(store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)).length > 0;
|
// return Object.keys(store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)).length > 0;
|
||||||
},
|
},
|
||||||
showThisPartQuestionChain(part, i) {
|
showThisPartQuestionChain(part, i) {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ describe("estimate.vue", () => {
|
||||||
expect(arePagePrerequisitesValid).toBe(false);
|
expect(arePagePrerequisitesValid).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("After selecting provide my home address on ForwardButtonAction triggers a router.navigate", async () => {
|
test("After selecting provide my home address on ForwardButtonAction triggers a router.navigateWithSaving", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -88,11 +88,11 @@ describe("estimate.vue", () => {
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("After selecting provide my manual vin on ForwardButtonAction triggers a router.navigate", async () => {
|
test("After selecting provide my manual vin on ForwardButtonAction triggers a router.navigateWithSaving", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -104,11 +104,11 @@ describe("estimate.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("BackButtonAction triggers a router.navigate change", async () => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -124,10 +124,10 @@ describe("estimate.vue", () => {
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Provide my license plate on ForwardButtonAction triggers a router.navigate", async () => {
|
test("Provide my license plate on ForwardButtonAction triggers a router.navigateWithSaving", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -139,7 +139,7 @@ describe("estimate.vue", () => {
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -152,6 +152,8 @@ function setupMocks({
|
||||||
mountOptionsMockData = {
|
mountOptionsMockData = {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}) {
|
}) {
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
if(store.getters.damage.isRepair!=null){
|
if(store.getters.damage.isRepair != null){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ describe("license-plate-lookup.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("navigation", () => {
|
describe("navigation", () => {
|
||||||
test("BackButtonAction triggers a router.navigate change", async () => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -103,7 +103,7 @@ describe("license-plate-lookup.vue", () => {
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("on forwardButtonAction click", () => {
|
describe("on forwardButtonAction click", () => {
|
||||||
|
|
@ -212,7 +212,7 @@ describe("license-plate-lookup.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("navigateForward", () => {
|
describe("navigateForward", () => {
|
||||||
test("navigate should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when navigateForward is called", async () => {
|
test("navigateWithSaving should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when navigateForward is called", async () => {
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -232,7 +232,7 @@ describe("license-plate-lookup.vue", () => {
|
||||||
await wrapper.vm.navigateForward();
|
await wrapper.vm.navigateForward();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("navigateForwardWithSingleCarMatch should be called if isCarIdDifferent is false or isSelectedGlassAvailableForVehicle is true when navigateForward is called", async () => {
|
test("navigateForwardWithSingleCarMatch should be called if isCarIdDifferent is false or isSelectedGlassAvailableForVehicle is true when navigateForward is called", async () => {
|
||||||
|
|
@ -549,6 +549,8 @@ function setupMocks({
|
||||||
...mountOptionsMockData,
|
...mountOptionsMockData,
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn()
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
getters: {
|
getters: {
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return true; // TODO - DO TRUE TEST OF PAGEDATA
|
return false; // TODO - DO TRUE TEST OF PAGEDATA
|
||||||
// return Object.keys(store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)).length > 0;
|
// return Object.keys(store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)).length > 0;
|
||||||
},
|
},
|
||||||
showThisPartQuestionChain(part, i) {
|
showThisPartQuestionChain(part, i) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@
|
||||||
<div v-for="(part, i) in partsQuestionsData" :key="i">
|
<div v-for="(part, i) in partsQuestionsData" :key="i">
|
||||||
<questionChain
|
<questionChain
|
||||||
ref="questionChain"
|
ref="questionChain"
|
||||||
v-model="selectedModel"
|
:key="part.key"
|
||||||
|
v-model="selectedAnswer"
|
||||||
:questionData="part"
|
:questionData="part"
|
||||||
:partIndex="i"
|
:partIndex="i"
|
||||||
v-if="showThisPartQuestionChain(part, i)"
|
v-if="showThisPartQuestionChain(part, i)"
|
||||||
|
|
@ -91,17 +92,14 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedModel: [],
|
partsQuestionsFromApi: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => {
|
||||||
partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => {
|
return Array.isArray(p.partQuestions) && p.partQuestions.length > 0;
|
||||||
if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) {
|
|
||||||
return {
|
|
||||||
glassName: p.glassName,
|
|
||||||
glassLocation: p.glassLocation,
|
|
||||||
partQuestions: p.partQuestions,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
|
selectedAnswer: [],
|
||||||
currentPartNum: 0,
|
currentPartNum: 0,
|
||||||
|
newAnswersArray: [],
|
||||||
|
partsQuestionsData: [],
|
||||||
|
foundDuplicateQuestions: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -113,10 +111,16 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mixins: [vehicleQuestionsMixin],
|
mixins: [vehicleQuestionsMixin],
|
||||||
|
mounted() {
|
||||||
|
this.partsQuestionsData = this.partsQuestionsFromApi.map((part, i) => {
|
||||||
|
part.key = part.glassLocation + part.glassName;
|
||||||
|
return part;
|
||||||
|
});
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showThisPartQuestionChain(part, i) {
|
showThisPartQuestionChain(part, i) {
|
||||||
if (part.partQuestions?.length < 1) { return false; } // return false if only one partQuestion
|
if (part.partQuestions?.length < 1 || part.suppressPart) { return false; } // return false if no partQuestions or if suppressed
|
||||||
if (this.currentPartNum === i || part.answerData?.answerResult.length > 0) { return true; }
|
if (this.currentPartNum === i || part.answerData?.answerResult?.length > 0) { return true; }
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
|
|
@ -136,6 +140,11 @@ export default {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// clear out answerData for future page loads; must occur prior to store save
|
||||||
|
this.partsQuestionsData.forEach((part) => {
|
||||||
|
part.answerData = {};
|
||||||
|
});
|
||||||
|
|
||||||
// save to vuex store as order.damage.partQuestionAnswers (array)
|
// save to vuex store as order.damage.partQuestionAnswers (array)
|
||||||
await this.dispatchStoreAction(this.storeActions.SAVE_PART_QUESTION_ANSWERS, partQuestionAnswersArray, false);
|
await this.dispatchStoreAction(this.storeActions.SAVE_PART_QUESTION_ANSWERS, partQuestionAnswersArray, false);
|
||||||
|
|
||||||
|
|
@ -146,7 +155,6 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts;
|
const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts;
|
||||||
|
|
||||||
const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(glassNameAndPartsForStore);
|
const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(glassNameAndPartsForStore);
|
||||||
const hasChildPartQuestions = this.hasChildPartQuestions(glassNameAndPartsForStore);
|
const hasChildPartQuestions = this.hasChildPartQuestions(glassNameAndPartsForStore);
|
||||||
const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore);
|
const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore);
|
||||||
|
|
@ -175,16 +183,220 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length > 0;
|
const partQuestionsFromPageData = store.getters.pageData(fmgPageValues.PART_QUESTIONS);
|
||||||
|
return partQuestionsFromPageData && Object.keys(partQuestionsFromPageData).length > 0;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
selectedModel(model) {
|
selectedAnswer(answer) {
|
||||||
this.partsQuestionsData[model.partIndex].answerData = {
|
// when selectedAnswer updates, user has completed this part's question chain and has a final answer
|
||||||
answerResult: model.answerResult,
|
// (does not get run for each invididual question's answer, only when
|
||||||
answeredQuestions: model.answeredQuestions,
|
// all relevent questions for the current part have been answered)
|
||||||
|
const glassPart = this.partsQuestionsData[answer.partIndex];
|
||||||
|
const completeAnsweredQuestions = [...answer.answeredQuestions];
|
||||||
|
const answeredQuestionIndexes = [];
|
||||||
|
|
||||||
|
// examine all the answers returned that were part of the user's journey through question-chain
|
||||||
|
|
||||||
|
// loop through every answered question on currently answered glass part
|
||||||
|
answer.answeredQuestions.forEach((aq) => {
|
||||||
|
|
||||||
|
// gather all the question numbers of the answered questions
|
||||||
|
answeredQuestionIndexes.push(aq.questionNum);
|
||||||
|
|
||||||
|
const answeredQuestionText = aq.questionText.toUpperCase();
|
||||||
|
const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase();
|
||||||
|
|
||||||
|
// HANDLE DUPLICATE QUESTIONS
|
||||||
|
// loop through all glass parts data (but only examining parts after currently being answered part)
|
||||||
|
this.partsQuestionsData.forEach((glassPart, i) => {
|
||||||
|
|
||||||
|
// restrict duplicate logic to only parts that follow the currently being answered part
|
||||||
|
if (i > answer.partIndex) {
|
||||||
|
|
||||||
|
// loop through this glass part's part questions, looking for a questionText match
|
||||||
|
glassPart.partQuestions.forEach((pq, pqIndex) => {
|
||||||
|
// does pq.questionText match answeredQuestionText? (do we have a duplicate question?)
|
||||||
|
|
||||||
|
if (pq.questionText.toUpperCase() === answeredQuestionText) {
|
||||||
|
// which one of this partQuestions' answers matches our answer?
|
||||||
|
|
||||||
|
let matchedAnswer;
|
||||||
|
pq.answers.forEach((ans, ansIndex) => {
|
||||||
|
delete pq.answers[ansIndex].selected;
|
||||||
|
if (ans.answerText.toUpperCase() === answeredQuestionAnswer) {
|
||||||
|
matchedAnswer = ans;
|
||||||
|
pq.answers[ansIndex].selected = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchedAnswer) {
|
||||||
|
const thisAnsweredPartQuestion = glassPart.partQuestions[pqIndex];
|
||||||
|
|
||||||
|
// remove answerData from this glass part
|
||||||
|
delete glassPart.answerData;
|
||||||
|
delete glassPart.suppressPart;
|
||||||
|
|
||||||
|
// Update the key to re-render this part's question-chain component
|
||||||
|
this.partsQuestionsData[i].key = this.partsQuestionsData[i].glassLocation + this.partsQuestionsData[i].glassName + Date.now().toString();
|
||||||
|
|
||||||
|
// handle suppressing downstream in this question chain
|
||||||
|
const rejectedAnswer = thisAnsweredPartQuestion.answers.filter((ans) => {
|
||||||
|
return !ans.selected;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rejectedAnswer[0].nextQuestionSequence) {
|
||||||
|
glassPart.partQuestions[rejectedAnswer[0].nextQuestionSequence - 1].suppressQuestion = true;
|
||||||
|
}
|
||||||
|
if (matchedAnswer.nextQuestionSequence) {
|
||||||
|
// ensure that accepted answer is NOT suppressed
|
||||||
|
delete glassPart.partQuestions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle suppressing upstream in this question chain
|
||||||
|
glassPart.partQuestions.forEach((q) => {
|
||||||
|
q.answers.forEach((thisAns) => {
|
||||||
|
// restore any of the answers that formerly led to the duplicated question
|
||||||
|
if (thisAns.originalNextQuestionSequence === pq.questionSequence) {
|
||||||
|
// restore original nextQuestionSequence
|
||||||
|
thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence;
|
||||||
|
delete thisAns.originalNextQuestionSequence;
|
||||||
|
// restore original answerResult
|
||||||
|
if (thisAns.originalAnswerResult) {
|
||||||
|
thisAns.answerResult = thisAns.originalAnswerResult;
|
||||||
|
delete thisAns.originalAnswerResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// search for any of the answers that lead to the duplicated question
|
||||||
|
if (thisAns.nextQuestionSequence === pq.questionSequence) {
|
||||||
|
// update either the nextQuestionSequence or the answerResult
|
||||||
|
if (matchedAnswer.nextQuestionSequence) {
|
||||||
|
thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence;
|
||||||
|
thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence;
|
||||||
|
} else {
|
||||||
|
thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence;
|
||||||
|
thisAns.nextQuestionSequence = null;
|
||||||
|
thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult;
|
||||||
|
thisAns.answerResult = matchedAnswer.answerResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// suppress current question
|
||||||
|
thisAnsweredPartQuestion.suppressQuestion = true;
|
||||||
|
|
||||||
|
const thisGlassPart = "glassPart" + i;
|
||||||
|
if (this.foundDuplicateQuestions[thisGlassPart]) {
|
||||||
|
if (!this.foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredPartQuestion.questionSequence)) {
|
||||||
|
this.foundDuplicateQuestions[thisGlassPart].push(thisAnsweredPartQuestion.questionSequence);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.foundDuplicateQuestions[thisGlassPart] = [thisAnsweredPartQuestion.questionSequence];
|
||||||
|
}
|
||||||
|
|
||||||
|
// are there any questions left that are not suppressed?
|
||||||
|
const remainingQuestions = glassPart.partQuestions.filter((q) => {
|
||||||
|
return !q.suppressQuestion;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (remainingQuestions.length < 1) {
|
||||||
|
// this is the final answer for this glass part
|
||||||
|
|
||||||
|
// mark this part as completely answered by adding answerData
|
||||||
|
const answeredQuestionObj = {
|
||||||
|
questionText: pq.questionText,
|
||||||
|
selectedAnswerText: matchedAnswer.answerText,
|
||||||
|
questionNum: pq.questionSequence,
|
||||||
|
};
|
||||||
|
// set the answerData as 'already answered'
|
||||||
|
glassPart.answerData = {
|
||||||
|
answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult,
|
||||||
|
answeredQuestions: [answeredQuestionObj],
|
||||||
|
};
|
||||||
|
|
||||||
|
// suppress this glassPart because it has an answer
|
||||||
|
glassPart.suppressPart = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // END of if (matchedAnswer)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// look through all (this part's) part questions for any duplicates that were suppressed;
|
||||||
|
// add them to the list of answered questions if found
|
||||||
|
|
||||||
|
// EX answeredQuestionIndexes: [1,5,11,13]
|
||||||
|
|
||||||
|
// EX this.foundDuplicateQuestions = {
|
||||||
|
// "glassPart1": [1],
|
||||||
|
// "glassPart2": [7, 10]
|
||||||
|
// };
|
||||||
|
|
||||||
|
const thisPartsDupes = this.foundDuplicateQuestions["glassPart" + answer.partIndex];
|
||||||
|
|
||||||
|
thisPartsDupes?.forEach((dupe) => {
|
||||||
|
// dupe is a single integer
|
||||||
|
const dupeQuestion = glassPart.partQuestions[dupe - 1];
|
||||||
|
const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true);
|
||||||
|
|
||||||
|
glassPart.partQuestions.forEach((q) => {
|
||||||
|
let includeThisDupeInAnsweredQuestions = false;
|
||||||
|
|
||||||
|
// did one of the answers of this question point to the duplicated question?
|
||||||
|
q.answers.forEach((a) => {
|
||||||
|
if ((dupe === a.originalNextQuestionSequence) &&
|
||||||
|
(answeredQuestionIndexes.includes(q.questionSequence)) &&
|
||||||
|
(a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) {
|
||||||
|
includeThisDupeInAnsweredQuestions = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// is this q.questionSequnce listed as the duplicated question's nextQuestionSequence?
|
||||||
|
if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) {
|
||||||
|
includeThisDupeInAnsweredQuestions = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeThisDupeInAnsweredQuestions) {
|
||||||
|
completeAnsweredQuestions.push({
|
||||||
|
questionNum: dupeQuestion.questionSequence,
|
||||||
|
questionText: dupeQuestion.questionText,
|
||||||
|
selectedAnswerText: dupeQuestionAnswer.answerText,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// make sure there are no duplicated dupes...
|
||||||
|
const foundInCompleteAnsweredQuestions = new Set();
|
||||||
|
let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => {
|
||||||
|
const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText);
|
||||||
|
foundInCompleteAnsweredQuestions.add(el.questionText);
|
||||||
|
return !duplicate;
|
||||||
|
});
|
||||||
|
filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a,b) => a.questionNum - b.questionNum);
|
||||||
|
|
||||||
|
// set final answer data for the current answered glass part
|
||||||
|
glassPart.answerData = {
|
||||||
|
answerResult: answer.answerResult,
|
||||||
|
answeredQuestions: filteredCompleteAnsweredQuestions,
|
||||||
|
}
|
||||||
|
|
||||||
|
// this part has been fully answered, so advance to next part's question chain
|
||||||
|
for (let i = answer.partIndex + 1; i < this.partsQuestionsData.length; i++) {
|
||||||
|
// if this part has not yet been fully answered, then make it the current part
|
||||||
|
if (!this.partsQuestionsData[i].answerData?.answerResult) {
|
||||||
|
this.currentPartNum = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.currentPartNum = model.partIndex + 1;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ jest.mock("@/store", () => ({
|
||||||
|
|
||||||
describe("vehicle-damage.vue", () => {
|
describe("vehicle-damage.vue", () => {
|
||||||
describe("navigation", () => {
|
describe("navigation", () => {
|
||||||
test("BackButtonAction triggers a router.navigate change", async () => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -73,7 +73,7 @@ describe("vehicle-damage.vue", () => {
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ describe("vehicle-damage.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
pageHeaderWidgetHeaderText: "",
|
pageHeaderWidgetHeaderText: "",
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: { navigate: jest.fn(), },
|
router: { navigate: jest.fn(), navigateWithSaving: jest.fn(), },
|
||||||
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
|
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
|
||||||
store: {
|
store: {
|
||||||
getters: {
|
getters: {
|
||||||
|
|
@ -158,7 +158,7 @@ describe("vehicle-damage.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
|
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
|
||||||
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(storeActions.GET_DAMAGE_OPTIONS, {"carId": "C00000000"});
|
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(storeActions.GET_DAMAGE_OPTIONS, {"carId": "C00000000"});
|
||||||
});
|
});
|
||||||
|
|
@ -217,7 +217,7 @@ describe("vehicle-damage.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
pageHeaderWidgetHeaderText: "",
|
pageHeaderWidgetHeaderText: "",
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: { navigate: jest.fn(), },
|
router: { navigate: jest.fn(), navigateWithSaving: jest.fn(), },
|
||||||
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
|
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
|
||||||
store: {
|
store: {
|
||||||
getters: {
|
getters: {
|
||||||
|
|
@ -248,7 +248,7 @@ describe("vehicle-damage.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
|
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
|
||||||
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(storeActions.GET_DAMAGE_OPTIONS, {"carId": "C00000000"});
|
expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith(storeActions.GET_DAMAGE_OPTIONS, {"carId": "C00000000"});
|
||||||
});
|
});
|
||||||
|
|
@ -690,6 +690,8 @@ function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCo
|
||||||
var mountOptionsMockDataDefault = {
|
var mountOptionsMockDataDefault = {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
if(store.getters.vehicle.carId){
|
if (store.getters.vehicle.carId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,14 @@ describe("vehicle-make.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("vehicle-make.vue", () => {
|
describe("vehicle-make.vue", () => {
|
||||||
test("BackButtonAction triggers a router.navigate change", async (done) => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
pageHeaderWidgetHeaderText: "Select a make to get started",
|
pageHeaderWidgetHeaderText: "Select a make to get started",
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -81,7 +82,7 @@ describe("vehicle-make.vue", () => {
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
apiPromise.finally(() => {
|
apiPromise.finally(() => {
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
if (store.getters.vehicle.year){
|
if (store.getters.vehicle.year){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,14 @@ describe("vehicle-model.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("vehicle-model.vue", () => {
|
describe("vehicle-model.vue", () => {
|
||||||
test("BackButtonAction triggers a router.navigate change", async (done) => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
pageHeaderWidgetHeaderText: "Select a model to get started",
|
pageHeaderWidgetHeaderText: "Select a model to get started",
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -77,7 +78,7 @@ describe("vehicle-model.vue", () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
//Assert
|
//Assert
|
||||||
apiPromise.finally(() => {
|
apiPromise.finally(() => {
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { nextTick } from "vue";
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||||
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||||
|
|
@ -76,7 +77,9 @@ describe("vehicle-parts.vue", () => {
|
||||||
{
|
{
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -114,7 +117,9 @@ describe("vehicle-parts.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -145,13 +150,15 @@ describe("vehicle-parts.vue", () => {
|
||||||
test("Initial data, should populate this.glassParts", async () => {
|
test("Initial data, should populate this.glassParts", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters.pageData.mockReturnValueOnce(basePartResponse);
|
store.getters.pageData.mockReturnValue(basePartResponse);
|
||||||
store.getters.lineItems = { glassParts: [{ partNumber: 'DB12209YPYNOEM' }] }
|
store.getters.lineItems = { glassParts: [{ partNumber: 'DB12209YPYNOEM' }] }
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -178,17 +185,15 @@ describe("vehicle-parts.vue", () => {
|
||||||
expect(wrapper.vm.glassParts).toEqual({ "Rear-Stationary": { "Rear": ['DB12209YPYNOEM'] } });
|
expect(wrapper.vm.glassParts).toEqual({ "Rear-Stationary": { "Rear": ['DB12209YPYNOEM'] } });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("BackButtonAction triggers a router.navigate change", async () => {
|
test("User had part questions > BackButtonAction triggers a router.navigateWithoutSaving change with correct scenario", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters.pageData.mockReturnValueOnce(basePartResponse);
|
|
||||||
store.getters.lineItems = { glassParts: null }
|
|
||||||
|
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -196,7 +201,25 @@ describe("vehicle-parts.vue", () => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
getters: store.getters
|
getters: {
|
||||||
|
pageData: () => {
|
||||||
|
return {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
glassName: "Stationary",
|
||||||
|
glassLocation: "Rear",
|
||||||
|
parts: null,
|
||||||
|
partQuestions: [{
|
||||||
|
testProperty: "some value"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: null
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -212,11 +235,52 @@ describe("vehicle-parts.vue", () => {
|
||||||
wrapper.vm.backButtonAction();
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS, wrapper.vm.$route);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("ForwardButtonAction triggers a router.navigate change if there are child part questions", async () => {
|
test("User did not have part questions > BackButtonAction triggers a router.navigateWithoutSaving change with correct scenario", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
fmgPage: 'vehicle-parts',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
store: {
|
||||||
|
getters: {
|
||||||
|
pageData: () => basePartResponse,
|
||||||
|
lineItems: {
|
||||||
|
glassParts: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS, wrapper.vm.$route);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test("ForwardButtonAction triggers a router.navigateWithSaving change if there are child part questions", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters.pageData.mockReturnValueOnce({
|
store.getters.pageData.mockReturnValueOnce({
|
||||||
|
|
@ -261,7 +325,9 @@ describe("vehicle-parts.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -288,10 +354,10 @@ describe("vehicle-parts.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("ForwardButtonAction triggers a router.navigate change if there are capability questions", async () => {
|
test("ForwardButtonAction triggers a router.navigateWithSaving change if there are capability questions", async () => {
|
||||||
|
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters.pageData.mockReturnValueOnce({
|
store.getters.pageData.mockReturnValueOnce({
|
||||||
|
|
@ -317,7 +383,9 @@ describe("vehicle-parts.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -344,7 +412,7 @@ describe("vehicle-parts.vue", () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("ForwardButtonAction saves selected parts to store if no molding or capability questions", async () => {
|
test("ForwardButtonAction saves selected parts to store if no molding or capability questions", async () => {
|
||||||
|
|
@ -356,7 +424,9 @@ describe("vehicle-parts.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
query: {
|
query: {
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ import store from "@/store";
|
||||||
import { storeMutations } from "@/constants/store-mutations.js";
|
import { storeMutations } from "@/constants/store-mutations.js";
|
||||||
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
|
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
|
||||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||||
|
import { assertParenthesizedExpression } from "@babel/types";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-parts",
|
name: "vehicle-parts",
|
||||||
|
|
@ -126,7 +127,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
glassName: g.glassName,
|
glassName: g.glassName,
|
||||||
glassLocation: g.glassLocation,
|
glassLocation: g.glassLocation,
|
||||||
colorAnswers: g.parts.reduce((arr, p) => {
|
colorAnswers: g.parts?.reduce((arr, p) => {
|
||||||
arr.push({
|
arr.push({
|
||||||
ColorAnswerText: p.color,
|
ColorAnswerText: p.color,
|
||||||
FeatureAnswers: [
|
FeatureAnswers: [
|
||||||
|
|
@ -155,14 +156,14 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
// Check if isRepair is populated and if the pageData we need is here (Parts data)
|
// Check if isRepair is populated and if the pageData we need is here (Parts data)
|
||||||
return store.getters.damage.isRepair != null &&
|
return store.getters.damage.isRepair != null && store.getters.pageData(fmgPageValues.VEHICLE_PARTS) &&
|
||||||
Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0;
|
Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0;
|
||||||
},
|
},
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions);
|
const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions);
|
||||||
const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS;
|
const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS;
|
||||||
|
|
||||||
this.$router.WithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
backNavigationScenario,
|
backNavigationScenario,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
@ -175,7 +176,6 @@ export default {
|
||||||
this.PartsFromApi.partsOrQuestions
|
this.PartsFromApi.partsOrQuestions
|
||||||
)) {
|
)) {
|
||||||
for (let [partKey, partValue] of Object.entries(value.parts)) {
|
for (let [partKey, partValue] of Object.entries(value.parts)) {
|
||||||
|
|
||||||
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
|
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
|
||||||
|
|
||||||
const isMatched = this.selectedGlassPartNumbers.some(
|
const isMatched = this.selectedGlassPartNumbers.some(
|
||||||
|
|
@ -184,9 +184,9 @@ export default {
|
||||||
|
|
||||||
if (isMatched) {
|
if (isMatched) {
|
||||||
matchedParts.push({
|
matchedParts.push({
|
||||||
"glassLocation": value.glassLocation,
|
glassLocation: value.glassLocation,
|
||||||
"glassName": value.glassName,
|
glassName: value.glassName,
|
||||||
"parts": [currentPart]
|
parts: [currentPart]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,15 @@ jest.mock("@/store", () => ({
|
||||||
vehicle: {
|
vehicle: {
|
||||||
model: "TL",
|
model: "TL",
|
||||||
},
|
},
|
||||||
|
applicationUser:{
|
||||||
|
pageData: {
|
||||||
|
"part-questions": null,
|
||||||
|
"vehicle-make": {},
|
||||||
|
"vehicle-model": {},
|
||||||
|
"vehicle-style": {},
|
||||||
|
"vehicle-damage": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
@ -57,13 +66,15 @@ describe("vehicle-style.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("vehicle-style.vue", () => {
|
describe("vehicle-style.vue", () => {
|
||||||
test("BackButtonAction triggers a router.navigate change", async (done) => {
|
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
pageHeaderWidgetHeaderText: "Select a style to get started",
|
pageHeaderWidgetHeaderText: "Select a style to get started",
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn(),
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -80,7 +91,7 @@ describe("vehicle-style.vue", () => {
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
apiPromise.finally(() => {
|
apiPromise.finally(() => {
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,21 @@
|
||||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
||||||
<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 />
|
<vehicleBanner
|
||||||
|
cmsWidgetName="VehicleBannerWidget"
|
||||||
|
displayGenericVehicleImage
|
||||||
|
/>
|
||||||
<funnelSubHeader
|
<funnelSubHeader
|
||||||
cmsWidgetName="FunnelSubHeaderWidget"
|
cmsWidgetName="FunnelSubHeaderWidget"
|
||||||
:hasBackButton="true"
|
:hasBackButton="true"
|
||||||
@click-event="backButtonAction"
|
@click-event="backButtonAction"
|
||||||
/>
|
/>
|
||||||
<div class="fade-on-route-transition">
|
<div class="fade-on-route-transition">
|
||||||
<styleQuestion v-model="selectedStyle" ref="styleQuestion" cmsWidgetName="VehicleStyleQuestion" />
|
<styleQuestion
|
||||||
|
v-model="selectedStyle"
|
||||||
|
ref="styleQuestion"
|
||||||
|
cmsWidgetName="VehicleStyleQuestion"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -29,14 +36,19 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
|
import router from "@/router";
|
||||||
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "vehicle-style",
|
name: "vehicle-style",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedStyle: null,
|
selectedStyle: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {},
|
computed: {},
|
||||||
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
|
@ -58,20 +70,37 @@ export default {
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
const visitedVehicleDamage = JSON.stringify(store.getters.applicationUser.pageData).indexOf(fmgPageValues.VEHICLE_DAMAGE) < 0 ? false : true;
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
// If we have exactly one style then navigate directly to vehicle-damage
|
||||||
vm.$refs.styleQuestion.initializeComponent(
|
if(resultMap.styleQuestionInitialData.length === 1 && !visitedVehicleDamage) {
|
||||||
resultMap.styleQuestionInitialData
|
store.commit(storeMutations.UPDATE_STYLE, resultMap.styleQuestionInitialData[0]);
|
||||||
);
|
|
||||||
});
|
await store.dispatch(storeActions.SET_VEHICLE,
|
||||||
|
{
|
||||||
|
year: store.getters.vehicle.year,
|
||||||
|
make: store.getters.vehicle.make,
|
||||||
|
model: store.getters.vehicle.model,
|
||||||
|
style: store.getters.vehicle.style,
|
||||||
|
});
|
||||||
|
|
||||||
|
//emulate selecting the vehicle style
|
||||||
|
router.overrideNavigation(navigationScenarios.SELECTED_STYLE, to, next);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
next( (vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.$refs.styleQuestion.initializeComponent(resultMap.styleQuestionInitialData)
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
// route to move backwards
|
// route to move backwards
|
||||||
this.$router.WithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
this.navigationScenarios.CLICKED_BACK,
|
this.navigationScenarios.CLICKED_BACK,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ import store from "@/store";
|
||||||
jest.mock("@/store", () => ({
|
jest.mock("@/store", () => ({
|
||||||
commit: jest.fn(),
|
commit: jest.fn(),
|
||||||
dispatch: jest.fn(),
|
dispatch: jest.fn(),
|
||||||
|
getters: {
|
||||||
|
applicationUser: {
|
||||||
|
experiments: []
|
||||||
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import { experimentUniverses } from "@/constants/experiments";
|
import { experimentUniverses } from "@/constants/experiments";
|
||||||
import { getDeviceIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper";
|
import { getDeviceIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
|
|
||||||
|
|
@ -48,13 +49,15 @@ export default {
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||||
const yearQuestionInitialDataPromise = yearQuestion.methods.loadInitialData();
|
const yearQuestionInitialDataPromise = yearQuestion.methods.loadInitialData();
|
||||||
|
|
||||||
|
const experimentForLogging = store.getters.applicationUser.experiments.find(e => e.universeName === experimentUniverses.CONCEPT_FUNNEL);
|
||||||
|
|
||||||
// Log experiment exposure
|
// Log experiment exposure
|
||||||
const logExperimentExposurePromise = baseMixin.methods.dispatchStoreAction(storeActions.LOG_EXPERIMENT_EXPOSURE,
|
baseMixin.methods.dispatchStoreAction(storeActions.LOG_EXPERIMENT_EXPOSURE,
|
||||||
{
|
{
|
||||||
userId: getDeviceIdValue(),
|
userId: getDeviceIdValue(),
|
||||||
sessionKey: getSessionKeyValue(),
|
sessionKey: getSessionKeyValue(),
|
||||||
pageName: to.query.fmgPage,
|
pageName: to.query.fmgPage,
|
||||||
universeName: experimentUniverses.CONCEPT_FUNNEL
|
experiment: experimentForLogging
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
|
|
@ -67,10 +70,6 @@ export default {
|
||||||
resultKey: "yearQuestionInitialData",
|
resultKey: "yearQuestionInitialData",
|
||||||
promise: yearQuestionInitialDataPromise,
|
promise: yearQuestionInitialDataPromise,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resultKey: "logExperimentExposure",
|
|
||||||
promise: logExperimentExposurePromise,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
let resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ describe("vin-lookup.vue", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
customMountOptions: {
|
customMountOptions: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigateWithSaving: jest.fn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -169,8 +169,8 @@ describe("vin-lookup.vue", () => {
|
||||||
await wrapper.vm.navigateForward();
|
await wrapper.vm.navigateForward();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toBeCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, wrapper.vm.$route, expect.anything(), expect.anything());
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, wrapper.vm.$route, expect.anything(), expect.anything());
|
||||||
})
|
})
|
||||||
|
|
||||||
test("carId matches => navigateForwardWithSingleCarMatch", async () => {
|
test("carId matches => navigateForwardWithSingleCarMatch", async () => {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { queryStrings } from "@/constants/query-strings";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
import { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes } from "@/constants/analytics";
|
import { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes } from "@/constants/analytics";
|
||||||
import { cookieNames } from "@/constants/cookie-names";
|
import { cookieNames } from "@/constants/cookie-names";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ export default {
|
||||||
action: '',
|
action: '',
|
||||||
event: pageEvent,
|
event: pageEvent,
|
||||||
shouldUseSessionId: false,
|
shouldUseSessionId: false,
|
||||||
|
experimentsForUser: store.getters.applicationUser.experiments,
|
||||||
};
|
};
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
|
baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
|
||||||
|
|
@ -37,6 +39,7 @@ export default {
|
||||||
label: label,
|
label: label,
|
||||||
value: value,
|
value: value,
|
||||||
shouldUseSessionId: false,
|
shouldUseSessionId: false,
|
||||||
|
experimentsForUser: store.getters.applicationUser.experiments
|
||||||
};
|
};
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
|
baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
|
||||||
|
|
@ -57,7 +60,7 @@ export default {
|
||||||
pushToDataLayerIfDefined(eventToBePushed);
|
pushToDataLayerIfDefined(eventToBePushed);
|
||||||
|
|
||||||
if (pushToLogApp) {
|
if (pushToLogApp) {
|
||||||
this.logCustomEvent(category, action, labelToLog, undefined);
|
this.logCustomEvent(category, action, labelToLog, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -75,7 +78,8 @@ export default {
|
||||||
this.logPageView(analyticsPageEvents.ENTRY);
|
this.logPageView(analyticsPageEvents.ENTRY);
|
||||||
},
|
},
|
||||||
|
|
||||||
pushExperimentsToDataLayer(experiments) {
|
pushExperimentsToDataLayer() {
|
||||||
|
const experiments = store.getters.applicationUser.experiments;
|
||||||
experiments?.forEach(exp => {
|
experiments?.forEach(exp => {
|
||||||
|
|
||||||
// Set Google Dimension Index based on experiment settings.
|
// Set Google Dimension Index based on experiment settings.
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
import { setupMocksForJsFiles, setupCookies } from "@/helpers/unit-test-helper.js";
|
import { setupMocksForJsFiles, setupCookies } from "@/helpers/unit-test-helper.js";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
import { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes } from "@/constants/analytics";
|
import { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes } from "@/constants/analytics";
|
||||||
|
import store from "@/store";
|
||||||
|
|
||||||
describe("analyticsMixin.js", () => {
|
describe("analyticsMixin.js", () => {
|
||||||
test("logPageView: calls dispatch with type and payload", () => {
|
test("logPageView: calls dispatch with type and payload", () => {
|
||||||
|
|
@ -119,6 +120,21 @@ describe("analyticsMixin.js", () => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Mock store
|
||||||
|
jest.mock("@/store", () => { return {}; }, { virtual: true });
|
||||||
|
|
||||||
|
store.getters = {
|
||||||
|
applicationUser: {
|
||||||
|
experiments: [
|
||||||
|
{
|
||||||
|
settings: {},
|
||||||
|
variationName: 'test',
|
||||||
|
universeName: 'testUniverse'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
||||||
|
|
@ -147,6 +163,20 @@ describe("analyticsMixin.js", () => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Mock store
|
||||||
|
jest.mock("@/store", () => { return {}; }, { virtual: true });
|
||||||
|
|
||||||
|
store.getters = {
|
||||||
|
applicationUser: {
|
||||||
|
experiments: [
|
||||||
|
{
|
||||||
|
settings: { "Google Custom Dimension Index": "5" },
|
||||||
|
variationName: 'test',
|
||||||
|
universeName: 'testUniverse'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData);
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ export default {
|
||||||
return partsOrQuestions?.some(pq => pq.parts?.length > 1);
|
return partsOrQuestions?.some(pq => pq.parts?.length > 1);
|
||||||
},
|
},
|
||||||
hasChildPartQuestions(partsOrQuestions) {
|
hasChildPartQuestions(partsOrQuestions) {
|
||||||
return partsOrQuestions.some(pq => {
|
return partsOrQuestions?.some(pq => {
|
||||||
return pq.parts?.some(part => part.childPartQuestions?.length > 0);
|
return pq.parts?.some(part => part.childPartQuestions?.length > 0);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hasCapabilityQuestions(partsOrQuestions) {
|
hasCapabilityQuestions(partsOrQuestions) {
|
||||||
return partsOrQuestions.some(pq => {
|
return partsOrQuestions?.some(pq => {
|
||||||
return pq.parts?.some(part => part.requiresCapabilityQuestions === true);
|
return pq.parts?.some(part => part.requiresCapabilityQuestions === true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("multiple glass locations have part questions => go to parts-questions", async () => {
|
test("multiple glass locations have part questions => go to parts-questions", async () => {
|
||||||
|
|
@ -163,8 +163,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("multiple glass locations selected, one has part question => go to parts-questions", async () => {
|
test("multiple glass locations selected, one has part question => go to parts-questions", async () => {
|
||||||
|
|
@ -263,8 +263,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("a selected glass location has part questions and multiple parts => go to parts-questions", async () => {
|
test("a selected glass location has part questions and multiple parts => go to parts-questions", async () => {
|
||||||
|
|
@ -411,8 +411,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -453,8 +453,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("multiple glass locations selected, one of them has multiple parts => go to vehicle parts", async () => {
|
test("multiple glass locations selected, one of them has multiple parts => go to vehicle parts", async () => {
|
||||||
|
|
@ -559,8 +559,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("multiple glass locations selected, multiple have multiple parts => go to vehicle-parts", async () => {
|
test("multiple glass locations selected, multiple have multiple parts => go to vehicle-parts", async () => {
|
||||||
|
|
@ -731,8 +731,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -784,8 +784,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -819,8 +819,8 @@ describe("vin-pages-mixin", () => {
|
||||||
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
await wrapper.vm.navigateForwardWithSingleCarMatch();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -984,7 +984,7 @@ function setupMocks({ partsOrQuestions = [] }) {
|
||||||
|
|
||||||
const mocks = getMountOptions({
|
const mocks = getMountOptions({
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn(), navigateWithSaving: jest.fn(), navigateWithoutSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
store: {
|
store: {
|
||||||
commit: jest.fn()
|
commit: jest.fn()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import baseMixin from "@/mixins/base-mixin";
|
||||||
import eventBus from "@/helpers/event-bus/event-bus";
|
import eventBus from "@/helpers/event-bus/event-bus";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import analyticsMixin from "@/mixins/analytics-mixin";
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
|
import { experimentTriggers } from "../constants/experiments";
|
||||||
|
import { applicationConfig } from "../constants/application-config";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
|
|
@ -60,6 +62,8 @@ const routes = [
|
||||||
to.query.fmgPage = pageToRedirectTo;
|
to.query.fmgPage = pageToRedirectTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await runExperiments(to.query.fmgPage);
|
||||||
|
|
||||||
// Process funnel cookie.
|
// Process funnel cookie.
|
||||||
updateOrCreateFunnelCookie();
|
updateOrCreateFunnelCookie();
|
||||||
|
|
||||||
|
|
@ -124,8 +128,6 @@ const router = createRouter({
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
// Update lastPageVisited in the store
|
// Update lastPageVisited in the store
|
||||||
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
||||||
// Push page view to GA
|
|
||||||
analyticsMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]);
|
|
||||||
|
|
||||||
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
||||||
if (eval(to.params.isSavingNavigation)) {
|
if (eval(to.params.isSavingNavigation)) {
|
||||||
|
|
@ -134,10 +136,11 @@ router.afterEach((to, from) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
baseMixin.methods.dispatchStoreAction(storeActions.GET_EXPERIMENTS_BY_USER, { userId: getDeviceIdValue() })
|
// Push page view to GA
|
||||||
.then( (response) => {
|
analyticsMixin.methods.pushPageViewToGA();
|
||||||
analyticsMixin.methods.pushExperimentsToDataLayer(response.data);
|
|
||||||
});
|
// Push experiments to Data Layer
|
||||||
|
analyticsMixin.methods.pushExperimentsToDataLayer();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -153,6 +156,12 @@ router.navigateToExternalUrl = (url, optionalQuery = {}) => {
|
||||||
navigateToUrl(url, optionalQuery);
|
navigateToUrl(url, optionalQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example.
|
||||||
|
router.overrideNavigation = (scenario, currentRoute, next, optionalQuery = {}, optionalParams = {}, optionalPageData) => {
|
||||||
|
router.navigate(scenario, currentRoute, optionalQuery, optionalParams, optionalPageData);
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
// PRIVATE FUNCTIONS
|
// PRIVATE FUNCTIONS
|
||||||
|
|
||||||
// Navigate to the next route, depending on the scenario.
|
// Navigate to the next route, depending on the scenario.
|
||||||
|
|
@ -169,10 +178,9 @@ async function navigate(scenario, currentRoute, isSavingNavigation, optionalQuer
|
||||||
if (destinationFmgPageValue !== undefined) {
|
if (destinationFmgPageValue !== undefined) {
|
||||||
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one.
|
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one.
|
||||||
|
|
||||||
// Update page data to the store for next page if provided. Otherwise, keep existing page data
|
// Update page data to the store for next page if provided. Otherwise, keep existing page data or set to empty object
|
||||||
if (optionalPageData !== undefined) {
|
const existingPageDataForPage = store.getters.pageData(destinationFmgPageValue);
|
||||||
baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData);
|
baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData ? optionalPageData : existingPageDataForPage ?? {});
|
||||||
}
|
|
||||||
|
|
||||||
optionalParams.isSavingNavigation = isSavingNavigation;
|
optionalParams.isSavingNavigation = isSavingNavigation;
|
||||||
|
|
||||||
|
|
@ -266,4 +274,21 @@ function arePagePrerequisitesValid(component) {
|
||||||
return component.default.methods.arePagePrerequisitesValid();
|
return component.default.methods.arePagePrerequisitesValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run SiteEntry and PageEntry triggers for experiments
|
||||||
|
async function runExperiments(nextPage) {
|
||||||
|
if (!store.getters.applicationUser.triggeredSiteEntry) {
|
||||||
|
await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, {
|
||||||
|
userId: getDeviceIdValue(),
|
||||||
|
triggerEvent: experimentTriggers.SITE_ENTRY,
|
||||||
|
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, {
|
||||||
|
userId: getDeviceIdValue(),
|
||||||
|
triggerEvent: experimentTriggers.PAGE_ENTRY,
|
||||||
|
triggerValue: nextPage
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ const fmgPageValues = {
|
||||||
REVEAL: "reveal",
|
REVEAL: "reveal",
|
||||||
ESTIMATE: "estimate",
|
ESTIMATE: "estimate",
|
||||||
ADDRESS_VEHICLES: "address-vehicles",
|
ADDRESS_VEHICLES: "address-vehicles",
|
||||||
QUOTE: "quote"
|
QUOTE: "quote",
|
||||||
|
HERITAGE: "heritage"
|
||||||
};
|
};
|
||||||
|
|
||||||
export { fmgPageValues };
|
export { fmgPageValues };
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ import { storeMutations } from "@/constants/store-mutations";
|
||||||
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
|
import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper";
|
||||||
import createPersistedState from "vuex-persistedstate";
|
import createPersistedState from "vuex-persistedstate";
|
||||||
import globalMethods from "@/global-methods";
|
import globalMethods from "@/global-methods";
|
||||||
import { storeActions } from "../constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
|
import { experimentTriggers } from "@/constants/experiments";
|
||||||
|
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
|
||||||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
|
|
||||||
// Export State
|
// Export State
|
||||||
|
|
@ -60,6 +63,7 @@ const getDefaultState = () => {
|
||||||
referralDate: null,
|
referralDate: null,
|
||||||
referralCorrelationId: null,
|
referralCorrelationId: null,
|
||||||
accountNumber: 0,
|
accountNumber: 0,
|
||||||
|
eon: null
|
||||||
},
|
},
|
||||||
applicationUser: {
|
applicationUser: {
|
||||||
eventBus: [],
|
eventBus: [],
|
||||||
|
|
@ -69,7 +73,8 @@ const getDefaultState = () => {
|
||||||
savedSessionId: null,
|
savedSessionId: null,
|
||||||
crmCustomerId: null,
|
crmCustomerId: null,
|
||||||
lastPageVisited: null,
|
lastPageVisited: null,
|
||||||
experiments: []
|
experiments: [],
|
||||||
|
triggeredSiteEntry: false
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -119,11 +124,14 @@ export const mutations = {
|
||||||
state.order.damage.glassToReplace = glassToReplace;
|
state.order.damage.glassToReplace = glassToReplace;
|
||||||
},
|
},
|
||||||
updatePartQuestionAnswers(state, answersArray) {
|
updatePartQuestionAnswers(state, answersArray) {
|
||||||
state.order.damage.partQuestionAnswers = answersArray;
|
state.order.damage.partQuestionAnswers = answersArray;
|
||||||
},
|
},
|
||||||
updateGlassParts(state, partsData) {
|
updateGlassParts(state, partsData) {
|
||||||
state.order.lineItems.glassParts = partsData;
|
state.order.lineItems.glassParts = partsData;
|
||||||
},
|
},
|
||||||
|
updateOtherParts(state, partsData) {
|
||||||
|
state.order.lineItems.otherParts = partsData;
|
||||||
|
},
|
||||||
updatePageData(state, pageData) {
|
updatePageData(state, pageData) {
|
||||||
state.applicationUser.pageData[pageData.page] = pageData.data;
|
state.applicationUser.pageData[pageData.page] = pageData.data;
|
||||||
},
|
},
|
||||||
|
|
@ -139,6 +147,9 @@ export const mutations = {
|
||||||
updateParentAcctNumber(state, parentAcctNumber) {
|
updateParentAcctNumber(state, parentAcctNumber) {
|
||||||
state.order.accountNumber = parentAcctNumber;
|
state.order.accountNumber = parentAcctNumber;
|
||||||
},
|
},
|
||||||
|
updateEON(state, eon) {
|
||||||
|
state.order.eon = eon;
|
||||||
|
},
|
||||||
updateIsInsurance(state, isInsurance) {
|
updateIsInsurance(state, isInsurance) {
|
||||||
state.order.payment.isInsurance = isInsurance;
|
state.order.payment.isInsurance = isInsurance;
|
||||||
},
|
},
|
||||||
|
|
@ -267,6 +278,9 @@ export const mutations = {
|
||||||
state.order.lineItems.glassParts = null;
|
state.order.lineItems.glassParts = null;
|
||||||
state.order.damage.partQuestionAnswers = null;
|
state.order.damage.partQuestionAnswers = null;
|
||||||
state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null;
|
state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null;
|
||||||
},
|
},
|
||||||
resetState(state) {
|
resetState(state) {
|
||||||
Object.assign(state, getDefaultState());
|
Object.assign(state, getDefaultState());
|
||||||
|
|
@ -279,6 +293,14 @@ export const mutations = {
|
||||||
state.order.referralNumber = orderInformation.referralNumber;
|
state.order.referralNumber = orderInformation.referralNumber;
|
||||||
state.order.referralDate = orderInformation.referralDate;
|
state.order.referralDate = orderInformation.referralDate;
|
||||||
state.order.referralCorrelationId = orderInformation.referralCorrelationId;
|
state.order.referralCorrelationId = orderInformation.referralCorrelationId;
|
||||||
|
state.order.eon = orderInformation.eon;
|
||||||
|
|
||||||
|
if (state.order.vehicle.vin !== orderInformation.vehicle?.vin) {
|
||||||
|
state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null;
|
||||||
|
state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null;
|
||||||
|
}
|
||||||
|
|
||||||
state.order.vehicle = Object.assign(state.order.vehicle, {
|
state.order.vehicle = Object.assign(state.order.vehicle, {
|
||||||
year: orderInformation.vehicle?.year,
|
year: orderInformation.vehicle?.year,
|
||||||
|
|
@ -317,7 +339,14 @@ export const mutations = {
|
||||||
state.order.payment.insuranceCoverage.isVerified = orderInformation?.insuranceInfo.coverageVerified;
|
state.order.payment.insuranceCoverage.isVerified = orderInformation?.insuranceInfo.coverageVerified;
|
||||||
|
|
||||||
state.order.customer.emailAddress = orderInformation.customer.emailAddress;
|
state.order.customer.emailAddress = orderInformation.customer.emailAddress;
|
||||||
|
state.applicationUser.experiments = orderInformation.experiments;
|
||||||
},
|
},
|
||||||
|
updateExperiments(state, experiments) {
|
||||||
|
state.applicationUser.experiments = experiments;
|
||||||
|
},
|
||||||
|
updateTriggeredSiteEntry(state, wasSiteEntryTriggered) {
|
||||||
|
state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export Getters
|
// Export Getters
|
||||||
|
|
@ -338,9 +367,37 @@ export const getters = {
|
||||||
applicationUser: (state) => state.applicationUser,
|
applicationUser: (state) => state.applicationUser,
|
||||||
order: (state) => state.order,
|
order: (state) => state.order,
|
||||||
payment: (state) => state.order.payment,
|
payment: (state) => state.order.payment,
|
||||||
|
experimentOrder: (state) => {
|
||||||
|
return {
|
||||||
|
vehicleYear: state.order.vehicle.year,
|
||||||
|
vehicleMake: state.order.vehicle.make,
|
||||||
|
vehicleModel: state.order.vehicle.model,
|
||||||
|
vehicleStyle: state.order.vehicle.style,
|
||||||
|
isRepair: state.order.damage.isRepair,
|
||||||
|
numberOfChips: state.order.damage.numberOfChips,
|
||||||
|
carId: state.order.vehicle.carId,
|
||||||
|
serviceCity: state.order.serviceLocation.city,
|
||||||
|
serviceState: state.order.serviceLocation.state,
|
||||||
|
serviceZipCode: state.order.serviceLocation.zipCode,
|
||||||
|
parentAccountNumber: state.order.accountNumber,
|
||||||
|
isCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
|
||||||
|
orderPartNumbers: [...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "partNumber"), ...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, "partNumber")],
|
||||||
|
orderPartTypes: [...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "recalibrationType"), ...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, "recalibrationType")],
|
||||||
|
hasRecalibrationPart: getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "requiresRecalibration")?.length > 0,
|
||||||
|
selectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
|
||||||
|
selectedWindshieldGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.WINDSHIELD),
|
||||||
|
selectedBackGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.REAR),
|
||||||
|
selectedDriverSideGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.DRIVER),
|
||||||
|
selectedPassengerSideGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.PASSENGER)
|
||||||
|
}
|
||||||
|
},
|
||||||
experimentSettings: (state) => state.applicationUser.experiments.map(x => x.settings).reduce((r, c) => Object.assign(r, c), {})
|
experimentSettings: (state) => state.applicationUser.experiments.map(x => x.settings).reduce((r, c) => Object.assign(r, c), {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllValuesOfPropertyInArrayOfObjects(array, propertyName) {
|
||||||
|
return (array ?? []).map(x => x[propertyName]).filter(x => x);
|
||||||
|
}
|
||||||
|
|
||||||
// Export Actions
|
// Export Actions
|
||||||
export const actions = {
|
export const actions = {
|
||||||
|
|
||||||
|
|
@ -490,39 +547,51 @@ export const actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Analytics Actions
|
// Analytics Actions
|
||||||
logExperimentExposure(context, { userId, sessionKey, pageName, universeName }) {
|
logExperimentExposure(context, { userId, sessionKey, pageName, experiment }) {
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
method: endpoints.LogExperimentExposureIfAssigned.method,
|
method: endpoints.LogExperimentExposureIfAssigned.method,
|
||||||
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
|
endpoint: endpoints.LogExperimentExposureIfAssigned.url,
|
||||||
payload: {
|
payload: {
|
||||||
userId: userId,
|
experimentForLogging: {
|
||||||
sessionKey: sessionKey,
|
userId: userId,
|
||||||
pageName: pageName,
|
experimentUniverseId: experiment.universeId,
|
||||||
universeName: universeName
|
experimentUniverseName: experiment.universeName,
|
||||||
|
experimentTestId: experiment.testId,
|
||||||
|
experimentTestName: experiment.testName,
|
||||||
|
experimentVariationId: experiment.variationId,
|
||||||
|
experimentVariationName: experiment.variationName,
|
||||||
|
enabled: experiment.isActive,
|
||||||
|
isExposed: experiment.isExposed,
|
||||||
|
userPartitionNumber: experiment.userPartitionNumber,
|
||||||
|
assignmentId: experiment.assignmentId,
|
||||||
|
sessionKey: sessionKey,
|
||||||
|
pageName: pageName,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Misc Actions
|
// Misc Actions
|
||||||
updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, accountNumber, savedSessionId, crmCustomerId }) {
|
updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, eon, accountNumber, savedSessionId, crmCustomerId }) {
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
||||||
|
context.commit(storeMutations.UPDATE_EON, eon);
|
||||||
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, accountNumber);
|
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, accountNumber);
|
||||||
context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId);
|
context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId);
|
||||||
context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId);
|
context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId);
|
||||||
},
|
},
|
||||||
|
logPageView(context, { userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) {
|
||||||
logPageView(context, { userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId }) {
|
|
||||||
var payload = {
|
var payload = {
|
||||||
userId: userId,
|
userId: userId,
|
||||||
sessionKey: sessionKey,
|
sessionKey: sessionKey,
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
pageName: pageName,
|
pageName: pageName,
|
||||||
applicationName: 'SafeliteDotCom',
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
action: action,
|
action: action,
|
||||||
event: event,
|
event: event,
|
||||||
shouldUseSessionId: shouldUseSessionId
|
shouldUseSessionId: shouldUseSessionId,
|
||||||
|
experimentsForUser: experimentsForUser
|
||||||
};
|
};
|
||||||
|
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
|
|
@ -532,18 +601,19 @@ export const actions = {
|
||||||
logApiCall: false
|
logApiCall: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
logCustomEvent(context, { userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId }) {
|
logCustomEvent(context, { userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) {
|
||||||
var payload = {
|
var payload = {
|
||||||
userId: userId,
|
userId: userId,
|
||||||
sessionKey: sessionKey,
|
sessionKey: sessionKey,
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
pageName: pageName,
|
pageName: pageName,
|
||||||
applicationName: 'SafeliteDotCom',
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
category: category,
|
category: category,
|
||||||
action: action,
|
action: action,
|
||||||
label: label,
|
label: label,
|
||||||
value: value,
|
value: value,
|
||||||
shouldUseSessionId: shouldUseSessionId
|
shouldUseSessionId: shouldUseSessionId,
|
||||||
|
experimentsForUser: experimentsForUser
|
||||||
};
|
};
|
||||||
|
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
|
|
@ -555,7 +625,7 @@ export const actions = {
|
||||||
},
|
},
|
||||||
initializeSession(context, { userId, sessionId, userAgent, referrer }) {
|
initializeSession(context, { userId, sessionId, userAgent, referrer }) {
|
||||||
var payload = {
|
var payload = {
|
||||||
applicationName: 'SafeliteDotCom',
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
deviceId: userId,
|
deviceId: userId,
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
|
|
@ -574,10 +644,11 @@ export const actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Misc Actions
|
// Misc Actions
|
||||||
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId }) {
|
setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) {
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber);
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate);
|
||||||
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId);
|
||||||
|
context.commit(storeMutations.UPDATE_EON, eon);
|
||||||
},
|
},
|
||||||
|
|
||||||
GetExperimentsByUser(context, { userId }) {
|
GetExperimentsByUser(context, { userId }) {
|
||||||
|
|
@ -588,6 +659,28 @@ export const actions = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) {
|
||||||
|
if (triggerEvent == experimentTriggers.SITE_ENTRY) {
|
||||||
|
context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload = {
|
||||||
|
applicationName: applicationConfig.APPLICATION_NAME,
|
||||||
|
userId: userId,
|
||||||
|
triggerEvent: triggerEvent,
|
||||||
|
triggerValue: triggerValue,
|
||||||
|
experimentOrder: context.getters.experimentOrder
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await globalMethods.callHttpClient({
|
||||||
|
method: endpoints.RunExperimentsForTrigger.method,
|
||||||
|
endpoint: endpoints.RunExperimentsForTrigger.url,
|
||||||
|
payload: payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments);
|
||||||
|
},
|
||||||
|
|
||||||
getEvoxImage(context, { relativeUrl }) {
|
getEvoxImage(context, { relativeUrl }) {
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
method: endpoints.GetPageData.method,
|
method: endpoints.GetPageData.method,
|
||||||
|
|
@ -650,6 +743,7 @@ export const actions = {
|
||||||
const damage = context.getters.damage;
|
const damage = context.getters.damage;
|
||||||
const order = context.state.order;
|
const order = context.state.order;
|
||||||
const applicationUser = context.getters.applicationUser;
|
const applicationUser = context.getters.applicationUser;
|
||||||
|
const lineItems = context.state.order.lineItems;
|
||||||
|
|
||||||
return globalMethods.callHttpClient({
|
return globalMethods.callHttpClient({
|
||||||
method: endpoints.SaveOrder.method,
|
method: endpoints.SaveOrder.method,
|
||||||
|
|
@ -680,6 +774,9 @@ export const actions = {
|
||||||
customer: {
|
customer: {
|
||||||
emailAddress: order.customer.emailAddress,
|
emailAddress: order.customer.emailAddress,
|
||||||
},
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: lineItems.glassParts
|
||||||
|
},
|
||||||
serviceLocation: {
|
serviceLocation: {
|
||||||
streetAddress: order.serviceLocation.address,
|
streetAddress: order.serviceLocation.address,
|
||||||
city: order.serviceLocation.city,
|
city: order.serviceLocation.city,
|
||||||
|
|
@ -693,7 +790,7 @@ export const actions = {
|
||||||
lastPage: applicationUser.lastPageVisited,
|
lastPage: applicationUser.lastPageVisited,
|
||||||
crmCustomerId: applicationUser.crmCustomerId,
|
crmCustomerId: applicationUser.crmCustomerId,
|
||||||
savedSessionId: applicationUser.savedSessionId,
|
savedSessionId: applicationUser.savedSessionId,
|
||||||
|
experiments: applicationUser.experiments,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -708,8 +805,8 @@ export const actions = {
|
||||||
accountNumber: accountNumber?.toString()
|
accountNumber: accountNumber?.toString()
|
||||||
},
|
},
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
// clear the state if the existing referral number does not equal what is returned from loadOrder
|
// clear the state if the existing EON does not equal what is returned from loadOrder
|
||||||
if (context.state.order.referralNumber != response.data.referralNumber) {
|
if (context.state.order.eon && context.state.order.eon != response.data.eon) {
|
||||||
context.commit(storeMutations.RESET_STATE);
|
context.commit(storeMutations.RESET_STATE);
|
||||||
}
|
}
|
||||||
context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data);
|
context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data);
|
||||||
|
|
@ -736,6 +833,7 @@ export const actions = {
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
context.commit(storeMutations.UPDATE_YEAR, year);
|
context.commit(storeMutations.UPDATE_YEAR, year);
|
||||||
|
|
@ -756,6 +854,7 @@ export const actions = {
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
context.commit(storeMutations.UPDATE_MAKE, make);
|
context.commit(storeMutations.UPDATE_MAKE, make);
|
||||||
|
|
@ -775,6 +874,7 @@ export const actions = {
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
context.commit(storeMutations.UPDATE_MODEL, model);
|
context.commit(storeMutations.UPDATE_MODEL, model);
|
||||||
|
|
@ -792,6 +892,7 @@ export const actions = {
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
context.commit(storeMutations.UPDATE_STYLE, style);
|
context.commit(storeMutations.UPDATE_STYLE, style);
|
||||||
|
|
@ -822,6 +923,7 @@ export const actions = {
|
||||||
//Reset dependent state when changing
|
//Reset dependent state when changing
|
||||||
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
|
if (vehicleInfo.vin !== context.state.order.vehicle.vin) {
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
if (!isSelectedGlassAvailableForVehicle) {
|
if (!isSelectedGlassAvailableForVehicle) {
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
|
|
@ -840,6 +942,7 @@ export const actions = {
|
||||||
|
|
||||||
if (!isSelectedGlassAvailableForVehicle) {
|
if (!isSelectedGlassAvailableForVehicle) {
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
|
|
@ -855,6 +958,7 @@ export const actions = {
|
||||||
|
|
||||||
if (!isSelectedGlassAvailableForVehicle) {
|
if (!isSelectedGlassAvailableForVehicle) {
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
|
|
@ -880,6 +984,7 @@ export const actions = {
|
||||||
|
|
||||||
if (!isSelectedGlassAvailableForVehicle) {
|
if (!isSelectedGlassAvailableForVehicle) {
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
|
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save new values
|
//Save new values
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import globalMethods from "@/global-methods";
|
||||||
import { mutations, state, actions, getters } from "@/store";
|
import { mutations, state, actions, getters } from "@/store";
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
import { storeMutations } from "@/constants/store-mutations";
|
||||||
import { storeActions } from "@/constants/store-actions";
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import { experimentTriggers } from "@/constants/experiments";
|
||||||
|
|
||||||
// Mock global method
|
// Mock global method
|
||||||
globalMethods.callHttpClient = jest.fn();
|
globalMethods.callHttpClient = jest.fn();
|
||||||
|
|
||||||
|
|
@ -249,6 +251,36 @@ describe("Mutations", () => {
|
||||||
expect(storeState.order.payment.insuranceCoverage.isVerified).toEqual(true);
|
expect(storeState.order.payment.insuranceCoverage.isVerified).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("updateExperiments, should set experiments", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const mockExperimentsList = [
|
||||||
|
{
|
||||||
|
universeName: "XYZ",
|
||||||
|
settings: {
|
||||||
|
ExperimentSetting: "ExperimentValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateExperiments(storeState, mockExperimentsList);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.applicationUser.experiments).toEqual(mockExperimentsList);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updateTriggeredSiteEntry, should set triggeredSiteEntry", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mutations.updateTriggeredSiteEntry(storeState, true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(storeState.applicationUser.triggeredSiteEntry).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Actions", () => {
|
describe("Actions", () => {
|
||||||
|
|
@ -575,12 +607,13 @@ describe("Actions", () => {
|
||||||
lastPageVisited: "test-page",
|
lastPageVisited: "test-page",
|
||||||
crmCustomerId: "xxx-xxx-xxx",
|
crmCustomerId: "xxx-xxx-xxx",
|
||||||
savedSessionId: "xxx-xxx-xxx"
|
savedSessionId: "xxx-xxx-xxx"
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
context.state = {
|
context.state = {
|
||||||
order: {
|
order: {
|
||||||
serviceLocation: {},
|
serviceLocation: {},
|
||||||
customer: {}
|
customer: {},
|
||||||
|
lineItems: {}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -793,13 +826,27 @@ describe("Actions", () => {
|
||||||
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const payload = { isCarIdDifferent: true, isSelectedGlassAvailableForVehicle: false, vehicleInfo: { carId: 'C010101', vin: "XXXXX" }, registrationInfo: { zipCode: "80020" }, serviceLocationInfo: { state: "CO" }, customerEmail: "test@safleite.com" };
|
const payload = {
|
||||||
|
isCarIdDifferent: true,
|
||||||
|
isSelectedGlassAvailableForVehicle: false,
|
||||||
|
vehicleInfo: {
|
||||||
|
carId: 'C010101', vin: "XXXXX"
|
||||||
|
},
|
||||||
|
registrationInfo: {
|
||||||
|
zipCode: "80020"
|
||||||
|
},
|
||||||
|
serviceLocationInfo: {
|
||||||
|
state: "CO"
|
||||||
|
},
|
||||||
|
customerEmail: "test@safleite.com"
|
||||||
|
};
|
||||||
|
|
||||||
actions.saveVinLookup(context, payload);
|
actions.saveVinLookup(context, payload);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(1, storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
expect(dispatch).toHaveBeenNthCalledWith(1, storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(2, storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
expect(dispatch).toHaveBeenNthCalledWith(2, storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||||
|
expect(dispatch).toHaveBeenNthCalledWith(3, storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE, payload.vehicleInfo);
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE, payload.vehicleInfo);
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo);
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo);
|
||||||
|
|
@ -1041,6 +1088,72 @@ describe("Actions", () => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("runExperimentsForTrigger", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mutations.resetState(state);
|
||||||
|
globalMethods.callHttpClient = jest.fn().mockReturnValue({
|
||||||
|
data: {
|
||||||
|
experiments: [
|
||||||
|
{
|
||||||
|
mockProperty: "mockValue"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
test("triggerEvent is SiteEntry => set triggeredSiteEntry to true in store", async () => {
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
context.commit = jest.fn().mockImplementation((storeMutation, value) => mutations[storeMutation](context, value));
|
||||||
|
context.getters = {
|
||||||
|
...getters,
|
||||||
|
applicationUser: getters.applicationUser(context)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await actions.runExperimentsForTrigger(context, {
|
||||||
|
triggerEvent: experimentTriggers.SITE_ENTRY,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(context.commit).toHaveBeenNthCalledWith(1, storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true);
|
||||||
|
expect(context.getters.applicationUser.triggeredSiteEntry).toBe(true);
|
||||||
|
expect(globalMethods.callHttpClient).toHaveBeenCalled();
|
||||||
|
expect(context.commit).toHaveBeenNthCalledWith(2, storeMutations.UPDATE_EXPERIMENTS, [
|
||||||
|
{
|
||||||
|
mockProperty: "mockValue"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("triggerEvent is not SiteEntry => triggeredSiteEntry is false in store", async () => {
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
context.commit = jest.fn().mockImplementation((storeMutation, value) => mutations[storeMutation](context, value));
|
||||||
|
context.getters = {
|
||||||
|
...getters,
|
||||||
|
applicationUser: getters.applicationUser(context)
|
||||||
|
};
|
||||||
|
expect(context.commit).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await actions.runExperimentsForTrigger(context, {
|
||||||
|
triggerEvent: "NotSiteEntry",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(context.commit).not.toHaveBeenCalledWith(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, expect.any);
|
||||||
|
expect(context.getters.applicationUser.triggeredSiteEntry).toBe(false);
|
||||||
|
|
||||||
|
expect(globalMethods.callHttpClient).toHaveBeenCalledTimes(1);
|
||||||
|
expect(context.commit).toHaveBeenNthCalledWith(1, storeMutations.UPDATE_EXPERIMENTS, [
|
||||||
|
{
|
||||||
|
mockProperty: "mockValue"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1138,4 +1251,321 @@ describe("Getters", () => {
|
||||||
expect(getters.payment(storeState).insuranceCoverage.isVerified).toEqual(true);
|
expect(getters.payment(storeState).insuranceCoverage.isVerified).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("experimentOrder", () => {
|
||||||
|
test("glassToReplace, glassParts, and otherParts are null > return correct experimentOrder values", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const mockStateValues = {
|
||||||
|
vehicleYear: 1000,
|
||||||
|
vehicleMake: "CarMake",
|
||||||
|
vehicleModel: "CarModel",
|
||||||
|
vehicleStyle: "SuperCoolStyle",
|
||||||
|
isRepair: true,
|
||||||
|
numberOfChips: 9999999,
|
||||||
|
carId: "Gibberish",
|
||||||
|
serviceCity: "Columbus",
|
||||||
|
serviceState: "OH-IO",
|
||||||
|
serviceZipCode: 43215,
|
||||||
|
parentAccountNumber: "999999",
|
||||||
|
isCoverageVerified: true,
|
||||||
|
glassParts: null,
|
||||||
|
otherParts: null,
|
||||||
|
glassToReplace: null
|
||||||
|
}
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mutations.updateYear(storeState, mockStateValues.vehicleYear);
|
||||||
|
mutations.updateMake(storeState, mockStateValues.vehicleMake);
|
||||||
|
mutations.updateModel(storeState, mockStateValues.vehicleModel);
|
||||||
|
mutations.updateStyle(storeState, mockStateValues.vehicleStyle);
|
||||||
|
mutations.updateIsRepair(storeState, mockStateValues.isRepair);
|
||||||
|
mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips);
|
||||||
|
mutations.updateCarId(storeState, mockStateValues.carId);
|
||||||
|
mutations.updateServiceLocation(storeState, {
|
||||||
|
city: mockStateValues.serviceCity,
|
||||||
|
state: mockStateValues.serviceState,
|
||||||
|
zipCode: mockStateValues.serviceZipCode
|
||||||
|
});
|
||||||
|
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
|
||||||
|
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
|
||||||
|
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
|
||||||
|
mutations.updateOtherParts(storeState, mockStateValues.otherParts);
|
||||||
|
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(getters.experimentOrder(storeState)).toEqual({
|
||||||
|
vehicleYear: mockStateValues.vehicleYear,
|
||||||
|
vehicleMake: mockStateValues.vehicleMake,
|
||||||
|
vehicleModel: mockStateValues.vehicleModel,
|
||||||
|
vehicleStyle: mockStateValues.vehicleStyle,
|
||||||
|
isRepair: mockStateValues.isRepair,
|
||||||
|
numberOfChips: mockStateValues.numberOfChips,
|
||||||
|
carId: mockStateValues.carId,
|
||||||
|
serviceCity: mockStateValues.serviceCity,
|
||||||
|
serviceState: mockStateValues.serviceState,
|
||||||
|
serviceZipCode: mockStateValues.serviceZipCode,
|
||||||
|
parentAccountNumber: mockStateValues.parentAccountNumber,
|
||||||
|
isCoverageVerified: mockStateValues.isCoverageVerified,
|
||||||
|
orderPartNumbers: [],
|
||||||
|
orderPartTypes: [],
|
||||||
|
hasRecalibrationPart: false,
|
||||||
|
selectedMultiGlass: false,
|
||||||
|
selectedWindshieldGlass: false,
|
||||||
|
selectedBackGlass: false,
|
||||||
|
selectedDriverSideGlass: false,
|
||||||
|
selectedPassengerSideGlass: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("glassToReplace, glassParts, and otherParts are empty > return correct experimentOrder values", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const mockStateValues = {
|
||||||
|
vehicleYear: 1000,
|
||||||
|
vehicleMake: "CarMake",
|
||||||
|
vehicleModel: "CarModel",
|
||||||
|
vehicleStyle: "SuperCoolStyle",
|
||||||
|
isRepair: true,
|
||||||
|
numberOfChips: 9999999,
|
||||||
|
carId: "Gibberish",
|
||||||
|
serviceCity: "Columbus",
|
||||||
|
serviceState: "OH-IO",
|
||||||
|
serviceZipCode: 43215,
|
||||||
|
parentAccountNumber: "999999",
|
||||||
|
isCoverageVerified: true,
|
||||||
|
glassParts: [],
|
||||||
|
otherParts: [],
|
||||||
|
glassToReplace: []
|
||||||
|
}
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mutations.updateYear(storeState, mockStateValues.vehicleYear);
|
||||||
|
mutations.updateMake(storeState, mockStateValues.vehicleMake);
|
||||||
|
mutations.updateModel(storeState, mockStateValues.vehicleModel);
|
||||||
|
mutations.updateStyle(storeState, mockStateValues.vehicleStyle);
|
||||||
|
mutations.updateIsRepair(storeState, mockStateValues.isRepair);
|
||||||
|
mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips);
|
||||||
|
mutations.updateCarId(storeState, mockStateValues.carId);
|
||||||
|
mutations.updateServiceLocation(storeState, {
|
||||||
|
city: mockStateValues.serviceCity,
|
||||||
|
state: mockStateValues.serviceState,
|
||||||
|
zipCode: mockStateValues.serviceZipCode
|
||||||
|
});
|
||||||
|
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
|
||||||
|
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
|
||||||
|
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
|
||||||
|
mutations.updateOtherParts(storeState, mockStateValues.otherParts);
|
||||||
|
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(getters.experimentOrder(storeState)).toEqual({
|
||||||
|
vehicleYear: mockStateValues.vehicleYear,
|
||||||
|
vehicleMake: mockStateValues.vehicleMake,
|
||||||
|
vehicleModel: mockStateValues.vehicleModel,
|
||||||
|
vehicleStyle: mockStateValues.vehicleStyle,
|
||||||
|
isRepair: mockStateValues.isRepair,
|
||||||
|
numberOfChips: mockStateValues.numberOfChips,
|
||||||
|
carId: mockStateValues.carId,
|
||||||
|
serviceCity: mockStateValues.serviceCity,
|
||||||
|
serviceState: mockStateValues.serviceState,
|
||||||
|
serviceZipCode: mockStateValues.serviceZipCode,
|
||||||
|
parentAccountNumber: mockStateValues.parentAccountNumber,
|
||||||
|
isCoverageVerified: mockStateValues.isCoverageVerified,
|
||||||
|
orderPartNumbers: [],
|
||||||
|
orderPartTypes: [],
|
||||||
|
hasRecalibrationPart: false,
|
||||||
|
selectedMultiGlass: false,
|
||||||
|
selectedWindshieldGlass: false,
|
||||||
|
selectedBackGlass: false,
|
||||||
|
selectedDriverSideGlass: false,
|
||||||
|
selectedPassengerSideGlass: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Single windshield requiring recalibration is selected > return correct experimentOrder values", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const mockStateValues = {
|
||||||
|
vehicleYear: 1000,
|
||||||
|
vehicleMake: "CarMake",
|
||||||
|
vehicleModel: "CarModel",
|
||||||
|
vehicleStyle: "SuperCoolStyle",
|
||||||
|
isRepair: false,
|
||||||
|
numberOfChips: 0,
|
||||||
|
carId: "Gibberish",
|
||||||
|
serviceCity: "Columbus",
|
||||||
|
serviceState: "OH-IO",
|
||||||
|
serviceZipCode: 43215,
|
||||||
|
parentAccountNumber: "999999",
|
||||||
|
isCoverageVerified: false,
|
||||||
|
glassParts: [
|
||||||
|
{
|
||||||
|
partNumber: "WINDSHIELDPARTNUMBER",
|
||||||
|
description: "This is a windshield",
|
||||||
|
recalibrationType: "ADAS, maybe",
|
||||||
|
requiresRecalibration: true,
|
||||||
|
requiresCapabilityQuestions: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
otherParts: [
|
||||||
|
|
||||||
|
],
|
||||||
|
glassToReplace: [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mutations.updateYear(storeState, mockStateValues.vehicleYear);
|
||||||
|
mutations.updateMake(storeState, mockStateValues.vehicleMake);
|
||||||
|
mutations.updateModel(storeState, mockStateValues.vehicleModel);
|
||||||
|
mutations.updateStyle(storeState, mockStateValues.vehicleStyle);
|
||||||
|
mutations.updateIsRepair(storeState, mockStateValues.isRepair);
|
||||||
|
mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips);
|
||||||
|
mutations.updateCarId(storeState, mockStateValues.carId);
|
||||||
|
mutations.updateServiceLocation(storeState, {
|
||||||
|
city: mockStateValues.serviceCity,
|
||||||
|
state: mockStateValues.serviceState,
|
||||||
|
zipCode: mockStateValues.serviceZipCode
|
||||||
|
});
|
||||||
|
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
|
||||||
|
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
|
||||||
|
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
|
||||||
|
mutations.updateOtherParts(storeState, mockStateValues.otherParts);
|
||||||
|
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(getters.experimentOrder(storeState)).toEqual({
|
||||||
|
vehicleYear: mockStateValues.vehicleYear,
|
||||||
|
vehicleMake: mockStateValues.vehicleMake,
|
||||||
|
vehicleModel: mockStateValues.vehicleModel,
|
||||||
|
vehicleStyle: mockStateValues.vehicleStyle,
|
||||||
|
isRepair: mockStateValues.isRepair,
|
||||||
|
numberOfChips: mockStateValues.numberOfChips,
|
||||||
|
carId: mockStateValues.carId,
|
||||||
|
serviceCity: mockStateValues.serviceCity,
|
||||||
|
serviceState: mockStateValues.serviceState,
|
||||||
|
serviceZipCode: mockStateValues.serviceZipCode,
|
||||||
|
parentAccountNumber: mockStateValues.parentAccountNumber,
|
||||||
|
isCoverageVerified: mockStateValues.isCoverageVerified,
|
||||||
|
orderPartNumbers: ["WINDSHIELDPARTNUMBER"],
|
||||||
|
orderPartTypes: ["ADAS, maybe"],
|
||||||
|
hasRecalibrationPart: true,
|
||||||
|
selectedMultiGlass: false,
|
||||||
|
selectedWindshieldGlass: true,
|
||||||
|
selectedBackGlass: false,
|
||||||
|
selectedDriverSideGlass: false,
|
||||||
|
selectedPassengerSideGlass: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Select multiglass > return correct experimentOrder values", () => {
|
||||||
|
// Arrange
|
||||||
|
const storeState = state;
|
||||||
|
const mockStateValues = {
|
||||||
|
vehicleYear: 1000,
|
||||||
|
vehicleMake: "CarMake",
|
||||||
|
vehicleModel: "CarModel",
|
||||||
|
vehicleStyle: "SuperCoolStyle",
|
||||||
|
isRepair: false,
|
||||||
|
numberOfChips: 0,
|
||||||
|
carId: "Gibberish",
|
||||||
|
serviceCity: "Columbus",
|
||||||
|
serviceState: "OH-IO",
|
||||||
|
serviceZipCode: 43215,
|
||||||
|
parentAccountNumber: "999999",
|
||||||
|
isCoverageVerified: false,
|
||||||
|
glassParts: [
|
||||||
|
{
|
||||||
|
partNumber: "BACKGLASS_PN",
|
||||||
|
description: "This is a back glass",
|
||||||
|
recalibrationType: null,
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
partNumber: "DRIVERGLASS_PN",
|
||||||
|
description: "This is a driver side glass",
|
||||||
|
recalibrationType: null,
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
partNumber: "PASSENGERGLASS_PN",
|
||||||
|
description: "This is a passenger side glass",
|
||||||
|
recalibrationType: null,
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
otherParts: [
|
||||||
|
|
||||||
|
],
|
||||||
|
glassToReplace: [
|
||||||
|
{
|
||||||
|
glassLocation: "Rear",
|
||||||
|
glassName: "Stationary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
glassLocation: "Driver",
|
||||||
|
glassName: "Front"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
glassLocation: "Passenger",
|
||||||
|
glassName: "Front"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
glassLocation: "Passenger",
|
||||||
|
glassName: "Quarter"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mutations.updateYear(storeState, mockStateValues.vehicleYear);
|
||||||
|
mutations.updateMake(storeState, mockStateValues.vehicleMake);
|
||||||
|
mutations.updateModel(storeState, mockStateValues.vehicleModel);
|
||||||
|
mutations.updateStyle(storeState, mockStateValues.vehicleStyle);
|
||||||
|
mutations.updateIsRepair(storeState, mockStateValues.isRepair);
|
||||||
|
mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips);
|
||||||
|
mutations.updateCarId(storeState, mockStateValues.carId);
|
||||||
|
mutations.updateServiceLocation(storeState, {
|
||||||
|
city: mockStateValues.serviceCity,
|
||||||
|
state: mockStateValues.serviceState,
|
||||||
|
zipCode: mockStateValues.serviceZipCode
|
||||||
|
});
|
||||||
|
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
|
||||||
|
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
|
||||||
|
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
|
||||||
|
mutations.updateOtherParts(storeState, mockStateValues.otherParts);
|
||||||
|
mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(getters.experimentOrder(storeState)).toEqual({
|
||||||
|
vehicleYear: mockStateValues.vehicleYear,
|
||||||
|
vehicleMake: mockStateValues.vehicleMake,
|
||||||
|
vehicleModel: mockStateValues.vehicleModel,
|
||||||
|
vehicleStyle: mockStateValues.vehicleStyle,
|
||||||
|
isRepair: mockStateValues.isRepair,
|
||||||
|
numberOfChips: mockStateValues.numberOfChips,
|
||||||
|
carId: mockStateValues.carId,
|
||||||
|
serviceCity: mockStateValues.serviceCity,
|
||||||
|
serviceState: mockStateValues.serviceState,
|
||||||
|
serviceZipCode: mockStateValues.serviceZipCode,
|
||||||
|
parentAccountNumber: mockStateValues.parentAccountNumber,
|
||||||
|
isCoverageVerified: mockStateValues.isCoverageVerified,
|
||||||
|
orderPartNumbers: ["BACKGLASS_PN", "DRIVERGLASS_PN", "PASSENGERGLASS_PN"],
|
||||||
|
orderPartTypes: [],
|
||||||
|
hasRecalibrationPart: false,
|
||||||
|
selectedMultiGlass: true,
|
||||||
|
selectedWindshieldGlass: false,
|
||||||
|
selectedBackGlass: true,
|
||||||
|
selectedDriverSideGlass: true,
|
||||||
|
selectedPassengerSideGlass: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
//Blue gradient background mixin
|
//Blue gradient background mixin
|
||||||
@mixin blue-gradient {
|
@mixin blue-gradient {
|
||||||
background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%);
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,14 +54,14 @@ export default {
|
||||||
.btn {
|
.btn {
|
||||||
&.btn-primary {
|
&.btn-primary {
|
||||||
position: relative;
|
position: relative;
|
||||||
background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%);
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: $border-radius-lg;
|
border-radius: $border-radius-lg;
|
||||||
color: $white;
|
color: $white;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%);
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue