Baseline linting of several additional layout pages.
This commit is contained in:
parent
8c39458d91
commit
8620d3888b
35 changed files with 1283 additions and 1302 deletions
|
|
@ -19,7 +19,7 @@ module.exports = {
|
||||||
'object-curly-newline': ['error', { consistent: true }],
|
'object-curly-newline': ['error', { consistent: true }],
|
||||||
'function-paren-newline': ['error', 'never'],
|
'function-paren-newline': ['error', 'never'],
|
||||||
'operator-linebreak': ['error', 'before'],
|
'operator-linebreak': ['error', 'before'],
|
||||||
'implicit-arrow-linebreak': ['error', 'beside'],
|
'implicit-arrow-linebreak': ['off'],
|
||||||
'comma-dangle': ['error', 'never'],
|
'comma-dangle': ['error', 'never'],
|
||||||
indent: ['error', 4],
|
indent: ['error', 4],
|
||||||
'max-len': ['error', { code: 140 }],
|
'max-len': ['error', { code: 140 }],
|
||||||
|
|
|
||||||
|
|
@ -19,64 +19,122 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn()
|
fetchCmsContentForPage: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
const baseStoreGettersPageData = () => {
|
mountOptionsMockData = {
|
||||||
return {
|
router: {
|
||||||
partsOrQuestions: [
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn()
|
||||||
|
},
|
||||||
|
actionList: [
|
||||||
{
|
{
|
||||||
parts: null,
|
actionName: 'savePartQuestionAnswers',
|
||||||
partQuestions: [
|
data: {}
|
||||||
{
|
},
|
||||||
questionSequence: 1,
|
{
|
||||||
questionText:
|
actionName: 'getParts',
|
||||||
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
data: {}
|
||||||
answers: [
|
|
||||||
{
|
|
||||||
answerResult: '',
|
|
||||||
answerText: 'Yes',
|
|
||||||
nextQuestionSequence: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
answerResult: '',
|
|
||||||
answerText: 'No',
|
|
||||||
nextQuestionSequence: 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
glassLocation: 'Windshield',
|
|
||||||
glassName: 'Single',
|
|
||||||
answerKey: 'Windshield-Single',
|
|
||||||
answerData: null
|
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
};
|
route: {
|
||||||
};
|
query: {
|
||||||
const baseStoreGettersDamage = () => {
|
issPage: 'part-questions'
|
||||||
return {
|
}
|
||||||
partsQuestionAnswers: [
|
},
|
||||||
{
|
data() {
|
||||||
glassLocation: 'Windshield',
|
return {
|
||||||
glassName: 'Single',
|
computedSwitcher: [
|
||||||
result: 'FW04848',
|
|
||||||
answeredQuestions: [
|
|
||||||
{
|
{
|
||||||
questionText:
|
glassLocation: 'Windshield',
|
||||||
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
glassName: 'Single',
|
||||||
selectedAnswerText: 'Yes',
|
answerData: {
|
||||||
questionNum: 1
|
answerResult: 'FW04848',
|
||||||
},
|
answeredQuestions: []
|
||||||
{
|
}
|
||||||
questionText:
|
|
||||||
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
|
||||||
selectedAnswerText: 'Yes',
|
|
||||||
questionNum: 2
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
questionsData: {
|
||||||
|
get() {
|
||||||
|
return this.computedSwitcher;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.computedSwitcher = val;
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
};
|
}
|
||||||
};
|
}) {
|
||||||
|
useMainStore().getParts = jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
glassPieceParts: []
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...mountOptionsMockData,
|
||||||
|
mixins: [baseMixin, vehicleQuestionsMixin]
|
||||||
|
});
|
||||||
|
mountOptions.attachTo = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(partQuestions, mountOptions);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseStoreGettersPageData = () => ({
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: null,
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
questionSequence: 1,
|
||||||
|
questionText:
|
||||||
|
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
||||||
|
answers: [
|
||||||
|
{
|
||||||
|
answerResult: '',
|
||||||
|
answerText: 'Yes',
|
||||||
|
nextQuestionSequence: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
answerResult: '',
|
||||||
|
answerText: 'No',
|
||||||
|
nextQuestionSequence: 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
glassLocation: 'Windshield',
|
||||||
|
glassName: 'Single',
|
||||||
|
answerKey: 'Windshield-Single',
|
||||||
|
answerData: null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const baseStoreGettersDamage = () => ({
|
||||||
|
partsQuestionAnswers: [
|
||||||
|
{
|
||||||
|
glassLocation: 'Windshield',
|
||||||
|
glassName: 'Single',
|
||||||
|
result: 'FW04848',
|
||||||
|
answeredQuestions: [
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
||||||
|
selectedAnswerText: 'Yes',
|
||||||
|
questionNum: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
||||||
|
selectedAnswerText: 'Yes',
|
||||||
|
questionNum: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
useMainStore().pageData = baseStoreGettersPageData;
|
useMainStore().pageData = baseStoreGettersPageData;
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
@ -99,9 +157,7 @@ describe('partQuestions.vue...', () => {
|
||||||
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => undefined);
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = wrapper.vm.arePagePrerequisitesValid();
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
@ -114,11 +170,9 @@ describe('partQuestions.vue...', () => {
|
||||||
|
|
||||||
test('Should be at least one item in partsOrQuestions', () => {
|
test('Should be at least one item in partsOrQuestions', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => ({
|
||||||
return {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -212,13 +266,11 @@ describe('partQuestions.vue...', () => {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper.vm.getParts = jest.fn(() => {
|
wrapper.vm.getParts = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
glassPieceParts: []
|
||||||
glassPieceParts: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -246,13 +298,11 @@ describe('partQuestions.vue...', () => {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
useMainStore().getParts = jest.fn(() => {
|
useMainStore().getParts = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
glassPieceParts: []
|
||||||
glassPieceParts: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -278,13 +328,11 @@ describe('partQuestions.vue...', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getParts = jest.fn(() => {
|
useMainStore().getParts = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
glassPieceParts: []
|
||||||
glassPieceParts: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -311,13 +359,11 @@ describe('partQuestions.vue...', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getParts = jest.fn(() => {
|
useMainStore().getParts = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
glassPieceParts: []
|
||||||
glassPieceParts: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
wrapper.vm.navigateForward = jest.fn();
|
wrapper.vm.navigateForward = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -330,68 +376,3 @@ describe('partQuestions.vue...', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
mountOptionsMockData = {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithSaving: jest.fn(),
|
|
||||||
navigateWithoutSaving: jest.fn()
|
|
||||||
},
|
|
||||||
actionList: [
|
|
||||||
{
|
|
||||||
actionName: 'savePartQuestionAnswers',
|
|
||||||
data: {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actionName: 'getParts',
|
|
||||||
data: {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
route: {
|
|
||||||
query: {
|
|
||||||
issPage: 'part-questions'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
computedSwitcher: [
|
|
||||||
{
|
|
||||||
glassLocation: 'Windshield',
|
|
||||||
glassName: 'Single',
|
|
||||||
answerData: {
|
|
||||||
answerResult: 'FW04848',
|
|
||||||
answeredQuestions: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
questionsData: {
|
|
||||||
get() {
|
|
||||||
return this.computedSwitcher;
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.computedSwitcher = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
useMainStore().getParts = jest.fn(() => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
glassPieceParts: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
...mountOptionsMockData,
|
|
||||||
mixins: [baseMixin, vehicleQuestionsMixin]
|
|
||||||
});
|
|
||||||
mountOptions['attachTo'] = document.body;
|
|
||||||
|
|
||||||
const wrapper = shallowMount(partQuestions, mountOptions);
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<questions-page-layout
|
<questions-page-layout
|
||||||
ref="questionsPageLayout"
|
ref="questionsPageLayout"
|
||||||
|
v-model="selectedAnswers"
|
||||||
:isMetaValid="meta.valid"
|
:isMetaValid="meta.valid"
|
||||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||||
:questionsData="questionsData"
|
:questionsData="questionsData"
|
||||||
:validationRules="rules.optionRequired"
|
:validationRules="rules.optionRequired"
|
||||||
v-model="selectedAnswers"
|
:index="currentGlassIndex"
|
||||||
@forwardButtonAction="forwardButtonAction"
|
@forwardButtonAction="forwardButtonAction"
|
||||||
@back-click="navigateBack"
|
@back-click="navigateBack" />
|
||||||
:index="currentGlassIndex" />
|
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -30,6 +34,10 @@ import globalRules from '@/constants/global-rules';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'part-questions',
|
name: 'part-questions',
|
||||||
|
components: {
|
||||||
|
Form,
|
||||||
|
questionsPageLayout
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -80,22 +88,20 @@ export default {
|
||||||
.map((glass, index) => {
|
.map((glass, index) => {
|
||||||
// NOTE: questions for property "questions" can differ between layouts
|
// NOTE: questions for property "questions" can differ between layouts
|
||||||
glass.questions = glass.partQuestions;
|
glass.questions = glass.partQuestions;
|
||||||
glass.answerKey = glass.glassLocation + '-' + glass.glassName;
|
glass.answerKey = `${glass.glassLocation}-${glass.glassName}`;
|
||||||
// reset selectedAnswers for this glass
|
// reset selectedAnswers for this glass
|
||||||
this.selectedAnswers[glass.answerKey] = [];
|
this.selectedAnswers[glass.answerKey] = [];
|
||||||
|
|
||||||
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
|
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
|
||||||
|
|
||||||
// Set up watch for each set of glass questions
|
// Set up watch for each set of glass questions
|
||||||
this.$watch(
|
this.$watch(`selectedAnswers.${glass.answerKey}`,
|
||||||
'selectedAnswers.' + glass.answerKey,
|
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue && Object.keys(newValue).length > 0) {
|
if (newValue && Object.keys(newValue).length > 0) {
|
||||||
this.handleAnswerUpdates(newValue, glass.answerKey);
|
this.handleAnswerUpdates(newValue, glass.answerKey);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true });
|
||||||
);
|
|
||||||
|
|
||||||
return updatedGlass;
|
return updatedGlass;
|
||||||
});
|
});
|
||||||
|
|
@ -104,20 +110,18 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const partQuestionsFromPageData = useMainStore().pageData(issPageValues.PART_QUESTIONS);
|
const partQuestionsFromPageData = useMainStore().pageData(issPageValues.PART_QUESTIONS);
|
||||||
return (
|
return (
|
||||||
partQuestionsFromPageData &&
|
partQuestionsFromPageData
|
||||||
Object.keys(partQuestionsFromPageData.partsOrQuestions).length > 0
|
&& Object.keys(partQuestionsFromPageData.partsOrQuestions).length > 0
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
const questionAnswersArray = this.questionsData.map((glass) => {
|
const questionAnswersArray = this.questionsData.map((glass) => ({
|
||||||
return {
|
glassLocation: glass.glassLocation,
|
||||||
glassLocation: glass.glassLocation,
|
glassName: glass.glassName,
|
||||||
glassName: glass.glassName,
|
result: (glass.answerData && glass.answerData.answerResult) || '',
|
||||||
result: (glass.answerData && glass.answerData.answerResult) || '',
|
answeredQuestions: glass.answerData?.answeredQuestions,
|
||||||
answeredQuestions: glass.answerData?.answeredQuestions,
|
isSuppressedPart: glass.isSuppressedPart
|
||||||
isSuppressedPart: glass.isSuppressedPart
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// clear out answerData for future page loads; must occur prior to store save
|
// clear out answerData for future page loads; must occur prior to store save
|
||||||
this.questionsData.forEach((glass) => {
|
this.questionsData.forEach((glass) => {
|
||||||
|
|
@ -137,10 +141,6 @@ export default {
|
||||||
// TODO KO delete for quote mvp
|
// TODO KO delete for quote mvp
|
||||||
this.navigateForward(glassPartsForStore, null);
|
this.navigateForward(glassPartsForStore, null);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Form,
|
|
||||||
questionsPageLayout
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2 payment">
|
<div class="container-fluid pb-2 payment">
|
||||||
<p>Placeholder for payment page</p>
|
<p>Placeholder for payment page</p>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
cmsWidgetName="SiteFooterWidget"
|
|
||||||
ref="siteFooter"
|
ref="siteFooter"
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -31,14 +34,12 @@ import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'payment-page',
|
name: 'payment-page',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
|
||||||
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
return { mainStore };
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
@ -51,11 +52,18 @@ export default {
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
return { mainStore };
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
|
|
@ -69,17 +77,11 @@ export default {
|
||||||
|
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
components: {
|
};
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
Form,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.payment p{
|
.payment p{
|
||||||
margin-bottom:0.75rem;
|
margin-bottom:0.75rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import policyHolderDetails from '@/layouts/policy-holder-details/policy-holder-details.vue';
|
import policyHolderDetails from '@/layouts/policy-holder-details/policy-holder-details';
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
||||||
|
|
@ -19,6 +18,55 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn()
|
fetchCmsContentForPage: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks() {
|
||||||
|
const wrapper = shallowMount(policyHolderDetails,
|
||||||
|
getMountOptions({
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
mainStore: {
|
||||||
|
order: {
|
||||||
|
customer: {
|
||||||
|
emailAddress: 'test@test.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
const policies = [{
|
||||||
|
vehicles: [
|
||||||
|
{
|
||||||
|
vin: 'TEST_VIN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
vin: 'TEST_VIN2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: {
|
||||||
|
policies
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const apiResponses = {
|
||||||
|
policyLookupResponse: {
|
||||||
|
policies
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
|
||||||
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('policy-holder-details.vue', () => {
|
describe('policy-holder-details.vue', () => {
|
||||||
test('Should render policy-holder-details sub-components (policy holder first name, last name, street address etc.)', async () => {
|
test('Should render policy-holder-details sub-components (policy holder first name, last name, street address etc.)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -116,65 +164,10 @@ describe('navigation', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
|
||||||
navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
mockvehicles
|
mockvehicles);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks() {
|
|
||||||
const wrapper = shallowMount(
|
|
||||||
policyHolderDetails,
|
|
||||||
getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
mainStore: {
|
|
||||||
order: {
|
|
||||||
customer: {
|
|
||||||
emailAddress: 'test@test.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const policies = [{
|
|
||||||
vehicles: [
|
|
||||||
{
|
|
||||||
vin: 'TEST_VIN'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
vin: 'TEST_VIN2'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
|
||||||
policies:policies
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const apiResponses = {
|
|
||||||
policyLookupResponse:{
|
|
||||||
policies:policies
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
|
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,49 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2 px-5">
|
<div class="container-fluid pb-2 px-5">
|
||||||
<div class="row mt-4 mb-3">
|
<div class="row mt-4 mb-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" id="sub-header"/>
|
<siteSubHeader
|
||||||
<addressQuestions ref="addressQuestions" v-model="customerQuestions.addressQuestions" includeStreetAddress2="true" id="address-questions-wrapper"/>
|
id="sub-header"
|
||||||
|
cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
|
<addressQuestions
|
||||||
|
id="address-questions-wrapper"
|
||||||
|
ref="addressQuestions"
|
||||||
|
v-model="customerQuestions.addressQuestions"
|
||||||
|
includeStreetAddress2="true" />
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
inputId="firstNameField"
|
ref="policyHolderFirstName"
|
||||||
cmsWidgetName="PolicyholderFirstNameQuestion"
|
v-model="customerQuestions.firstName"
|
||||||
v-model="customerQuestions.firstName"
|
inputId="firstNameField"
|
||||||
isRequired
|
cmsWidgetName="PolicyholderFirstNameQuestion"
|
||||||
ref="policyHolderFirstName"
|
isRequired
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
:validationRules="rules.firstName" />
|
:validationRules="rules.firstName" />
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
class="mt-4"
|
ref="policyHolderLastName"
|
||||||
inputId="lastNameField"
|
v-model="customerQuestions.lastName"
|
||||||
cmsWidgetName="PolicyholderLastNameQuestion"
|
class="mt-4"
|
||||||
v-model="customerQuestions.lastName"
|
inputId="lastNameField"
|
||||||
isRequired
|
cmsWidgetName="PolicyholderLastNameQuestion"
|
||||||
ref="policyHolderLastName"
|
isRequired
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
:validationRules="rules.lastName" />
|
:validationRules="rules.lastName" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
class="mt-5"
|
ref="siteFooter"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
class="mt-5"
|
||||||
ref="siteFooter"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -58,21 +67,16 @@ import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'policy-holder-details',
|
name: 'policy-holder-details',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
textboxQuestion,
|
||||||
|
addressQuestions,
|
||||||
|
siteFooter,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
customerQuestions: this.getPolicyHolderDetailsFromStore(),
|
|
||||||
vehiclesFound: [],
|
|
||||||
rules: {
|
|
||||||
firstName: globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
|
|
||||||
lastName: globalRules.POLICYHOLDER_LAST_NAME_REQUIRED
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
return { mainStore };
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
@ -86,12 +90,34 @@ export default {
|
||||||
];
|
];
|
||||||
|
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
return { mainStore };
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
customerQuestions: this.getPolicyHolderDetailsFromStore(),
|
||||||
|
vehiclesFound: [],
|
||||||
|
rules: {
|
||||||
|
firstName: globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
|
||||||
|
lastName: globalRules.POLICYHOLDER_LAST_NAME_REQUIRED
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isCoverageEnabled() {
|
||||||
|
return this.mainStore.issConfig.isCoverageEnabled;
|
||||||
|
},
|
||||||
|
vehiclesCount() {
|
||||||
|
return this.vehiclesFound.length;
|
||||||
|
}
|
||||||
|
},
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
|
|
@ -105,18 +131,14 @@ export default {
|
||||||
|
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
if (this.vehiclesCount > 0) {
|
if (this.vehiclesCount > 0) {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
|
||||||
this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
|
|
||||||
this.$route,
|
this.$route,
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
this.vehiclesFound
|
this.vehiclesFound);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
|
||||||
this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
|
this.$route);
|
||||||
this.$route
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -132,29 +154,13 @@ export default {
|
||||||
},
|
},
|
||||||
firstName: this.mainStore.order.customer.firstName,
|
firstName: this.mainStore.order.customer.firstName,
|
||||||
lastName: this.mainStore.order.customer.lastName
|
lastName: this.mainStore.order.customer.lastName
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
isCoverageEnabled() {
|
|
||||||
return this.mainStore.issConfig.isCoverageEnabled;
|
|
||||||
},
|
|
||||||
vehiclesCount() {
|
|
||||||
return this.vehiclesFound.length;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
siteHeader,
|
|
||||||
siteSubHeader,
|
|
||||||
textboxQuestion,
|
|
||||||
addressQuestions,
|
|
||||||
siteFooter,
|
|
||||||
Form
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
#sub-header p {
|
#sub-header p {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
import policyVehiclesQuestion from '@/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question.vue';
|
import policyVehiclesQuestion from '@/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn(() => ['vehicle not listed'])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('policy-vehicles-question.vue', () => {
|
describe('policy-vehicles-question.vue', () => {
|
||||||
test('Selected vehicle is emitted upon selection', async () => {
|
test('Selected vehicle is emitted upon selection', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const vehicleToSelect = 'Test1';
|
const vehicleToSelect = 'Test1';
|
||||||
const wrapper = shallowMount(policyVehiclesQuestion, {
|
const wrapper = shallowMount(policyVehiclesQuestion, {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
|
|
@ -22,11 +28,3 @@ describe('policy-vehicles-question.vue', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn(() => {
|
|
||||||
return ['vehicle not listed'];
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
:validationRules="validationRules" />
|
:validationRules="validationRules" />
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
import buttonQuestion from '@/digital-components/button-question/button-question';
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
name: 'policy-vehicles-question',
|
name: 'policy-vehicles-question',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import policyVehicles from '@/layouts/policy-vehicles/policy-vehicles.vue';
|
import policyVehicles from '@/layouts/policy-vehicles/policy-vehicles';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper';
|
import { getMountOptions } from '@/helpers/unit-test-helper';
|
||||||
|
|
@ -9,8 +9,8 @@ import baseMixin from '@/mixins/base-mixin';
|
||||||
import { getRandomString, getRandomInt } from '@/helpers/data-generation';
|
import { getRandomString, getRandomInt } from '@/helpers/data-generation';
|
||||||
import { endorsementOptions } from '@/constants/endorsement-options';
|
import { endorsementOptions } from '@/constants/endorsement-options';
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
import { issPageValues } from "@/router/router-constants/issPage-values";
|
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||||
import { vehicleSelectionOptions } from "@/constants/vehicle-selection-options";
|
import { vehicleSelectionOptions } from '@/constants/vehicle-selection-options';
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
// Mock fetchCmsContentForPage
|
||||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
|
|
@ -27,6 +27,54 @@ jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
settleAllPromises: jest.fn()
|
settleAllPromises: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dynamicStrings() {
|
||||||
|
return { ROUTER_LINK: 'routerLink:' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function setupMocks() {
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
mixins: [mockMixin],
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$route: {
|
||||||
|
params: {
|
||||||
|
id: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [createTestingPinia()]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const apiResponses = {
|
||||||
|
cmsContent: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
|
const wrapper = shallowMount(policyVehicles, mountOptions);
|
||||||
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||||
|
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('policy-vehicles.vue', () => {
|
describe('policy-vehicles.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
|
||||||
|
|
@ -48,7 +96,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
await wrapper.setData({
|
await wrapper.setData({
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{ vin: vin },
|
{ vin }
|
||||||
],
|
],
|
||||||
bailout: false
|
bailout: false
|
||||||
});
|
});
|
||||||
|
|
@ -56,19 +104,19 @@ describe('policy-vehicles.vue', () => {
|
||||||
const year = getRandomInt(1998, 2023);
|
const year = getRandomInt(1998, 2023);
|
||||||
const lookupVehicleResponse = {
|
const lookupVehicleResponse = {
|
||||||
data: {
|
data: {
|
||||||
year: year,
|
year
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
store.lookupVehicleByVin.mockReturnValue(Promise.resolve(lookupVehicleResponse));
|
store.lookupVehicleByVin.mockReturnValue(Promise.resolve(lookupVehicleResponse));
|
||||||
|
|
||||||
const expectedInput = {
|
const expectedInput = {
|
||||||
year: year,
|
year,
|
||||||
vin: vin,
|
vin,
|
||||||
noCoverage: true,
|
noCoverage: true,
|
||||||
deductible: 0,
|
deductible: 0,
|
||||||
repairWaived: false
|
repairWaived: false
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -76,12 +124,10 @@ describe('policy-vehicles.vue', () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.bailout).toBeFalsy();
|
expect(wrapper.vm.bailout).toBeFalsy();
|
||||||
expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput);
|
expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput);
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
|
||||||
navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{}
|
{});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', async () => {
|
test('Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', async () => {
|
||||||
|
|
@ -102,12 +148,10 @@ describe('policy-vehicles.vue', () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.bailout).toBeTruthy();
|
expect(wrapper.vm.bailout).toBeTruthy();
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
||||||
navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{}
|
{});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.', async () => {
|
test('vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.', async () => {
|
||||||
|
|
@ -122,12 +166,10 @@ describe('policy-vehicles.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
|
||||||
navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{}
|
{});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -209,7 +251,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
vin: otherVin
|
vin: otherVin
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -225,11 +267,11 @@ describe('policy-vehicles.vue', () => {
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{
|
{
|
||||||
vin: vin,
|
vin,
|
||||||
coverages: []
|
coverages: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -247,7 +289,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{
|
{
|
||||||
vin: vin,
|
vin,
|
||||||
coverages: [
|
coverages: [
|
||||||
{
|
{
|
||||||
deductible: firstDeductible
|
deductible: firstDeductible
|
||||||
|
|
@ -258,7 +300,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.deductibleForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -280,7 +322,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
vin: otherVin
|
vin: otherVin
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -296,11 +338,11 @@ describe('policy-vehicles.vue', () => {
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{
|
{
|
||||||
vin: vin,
|
vin,
|
||||||
endorsements: []
|
endorsements: []
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -316,11 +358,11 @@ describe('policy-vehicles.vue', () => {
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{
|
{
|
||||||
vin: vin,
|
vin,
|
||||||
endorsements: [ endorsementOptions.EDUCATOR, endorsementOptions.PARKING_GUARD ]
|
endorsements: [endorsementOptions.EDUCATOR, endorsementOptions.PARKING_GUARD]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -336,7 +378,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
selectedVehicleVin: vin,
|
selectedVehicleVin: vin,
|
||||||
policyVehicles: [
|
policyVehicles: [
|
||||||
{
|
{
|
||||||
vin: vin,
|
vin,
|
||||||
endorsements: [
|
endorsements: [
|
||||||
endorsementOptions.EDUCATOR,
|
endorsementOptions.EDUCATOR,
|
||||||
endorsementOptions.REPAIR_WAIVED,
|
endorsementOptions.REPAIR_WAIVED,
|
||||||
|
|
@ -344,7 +386,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
const result = policyVehicles.computed.repairWaivedForSelectedVehicle.call(testValues);
|
||||||
|
|
@ -359,7 +401,7 @@ describe('policy-vehicles.vue', () => {
|
||||||
const vin = getRandomString(17, 17);
|
const vin = getRandomString(17, 17);
|
||||||
useMainStore().applicationUser = {
|
useMainStore().applicationUser = {
|
||||||
pageData: {
|
pageData: {
|
||||||
[issPageValues.POLICY_VEHICLES]: [{ vin: vin }],
|
[issPageValues.POLICY_VEHICLES]: [{ vin }]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -372,51 +414,3 @@ describe('policy-vehicles.vue', () => {
|
||||||
expect(wrapper.vm.selectedVehicleVin).toBe(vin);
|
expect(wrapper.vm.selectedVehicleVin).toBe(vin);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn()
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
dynamicStrings() {
|
|
||||||
return { ROUTER_LINK: 'routerLink:' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function setupMocks() {
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
mixins: [mockMixin],
|
|
||||||
global: {
|
|
||||||
mocks: {
|
|
||||||
$route: {
|
|
||||||
params: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
$router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [createTestingPinia()]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
const wrapper = shallowMount(policyVehicles, mountOptions);
|
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
|
||||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,113 +1,6 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import providerPrefRadio from './provider-pref-radio';
|
|
||||||
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
||||||
|
import providerPrefRadio from './provider-pref-radio';
|
||||||
describe('provider-pref-radio.vue', () => {
|
|
||||||
it('Should include buttonLabel in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
console.log(outputHtml);
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabel']));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should include buttonLabelAuxillaryCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabelAuxillaryCopy']));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should include buttonLabelSubCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabelSubCopy']));
|
|
||||||
});
|
|
||||||
it('Should include buttonFooterCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonFooterCopy']));
|
|
||||||
});
|
|
||||||
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when provided with a dashed (x5) buttonBodyCopy', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(results.length).toBe(5);
|
|
||||||
});
|
|
||||||
it('Should get strings from getArrayOfListItemsFromRawCmsCopy without dashes when provided with a dashed buttonBodyCopy', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const fileredResults = results.filter((result) => {
|
|
||||||
return result.includes(' -');
|
|
||||||
});
|
|
||||||
expect(fileredResults.length).toBe(0);
|
|
||||||
});
|
|
||||||
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ', async () => {
|
|
||||||
// Arrange
|
|
||||||
const moddedProps = mockProps;
|
|
||||||
moddedProps['buttonBodyCopy'] = '- buttonBodyCopy test copy - 2 - 3 - 4 - 5 -';
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: moddedProps
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(results.length).toBe(5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
buttonLabel: 'buttonLabel test copy',
|
buttonLabel: 'buttonLabel test copy',
|
||||||
|
|
@ -125,3 +18,109 @@ function setupMocks({ mountOptionsMockData = {} }) {
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('provider-pref-radio.vue', () => {
|
||||||
|
it('Should include buttonLabel in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
console.log(outputHtml);
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabel));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should include buttonLabelAuxillaryCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabelAuxillaryCopy));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should include buttonLabelSubCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabelSubCopy));
|
||||||
|
});
|
||||||
|
it('Should include buttonFooterCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonFooterCopy));
|
||||||
|
});
|
||||||
|
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when provided with a dashed (x5) buttonBodyCopy', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(results.length).toBe(5);
|
||||||
|
});
|
||||||
|
it('Should get strings from getArrayOfListItemsFromRawCmsCopy without dashes when provided with a dashed buttonBodyCopy', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const fileredResults = results.filter((result) => result.includes(' -'));
|
||||||
|
expect(fileredResults.length).toBe(0);
|
||||||
|
});
|
||||||
|
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
|
||||||
|
async () => {
|
||||||
|
// Arrange
|
||||||
|
const moddedProps = mockProps;
|
||||||
|
moddedProps.buttonBodyCopy = '- buttonBodyCopy test copy - 2 - 3 - 4 - 5 -';
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: moddedProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(results.length).toBe(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<baseInputButton v-bind="$props" v-model="selectedValue">
|
<baseInputButton
|
||||||
<div class="option-label"
|
v-bind="$props"
|
||||||
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
|
v-model="selectedValue">
|
||||||
for="testradio">
|
<div
|
||||||
|
class="option-label"
|
||||||
|
:class="[buttonLabelSubCopy ? 'has-subheader' : '']"
|
||||||
|
for="testradio">
|
||||||
<div class="option-specs">
|
<div class="option-specs">
|
||||||
<p class="m-0">
|
<p class="m-0">
|
||||||
<span v-html="this.buttonLabel"></span>
|
<span v-html="buttonLabel"></span>
|
||||||
<span class="option-info" v-html="this.buttonAuxiliaryCopy"></span>
|
<span
|
||||||
|
class="option-info"
|
||||||
|
v-html="buttonAuxiliaryCopy"></span>
|
||||||
</p>
|
</p>
|
||||||
<p class="sub-label m-0"
|
<p
|
||||||
v-if="this.buttonLabelSubCopy"
|
v-if="buttonLabelSubCopy"
|
||||||
v-html="this.buttonLabelSubCopy"></p>
|
class="sub-label m-0"
|
||||||
|
v-html="buttonLabelSubCopy"></p>
|
||||||
<div>
|
<div>
|
||||||
<ul >
|
<ul>
|
||||||
<li v-for="listItem in this.arrayOfListItemsFromBodyText" :key="listItem" class="mb-0">
|
<li
|
||||||
|
v-for="listItem in arrayOfListItemsFromBodyText"
|
||||||
|
:key="listItem"
|
||||||
|
class="mb-0">
|
||||||
<!-- no textLink -->
|
<!-- no textLink -->
|
||||||
<span v-html="listItem"></span>
|
<span v-html="listItem"></span>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -25,17 +34,15 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import baseInputButton from '@/digital-components/base-input-button/base-input-button';
|
import baseInputButton from '@/digital-components/base-input-button/base-input-button';
|
||||||
import textLink from '@/ux-components/text-link/text-link';
|
|
||||||
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'providerPrefRadio',
|
name: 'provider-pref-radio',
|
||||||
mixins: [inputButtonWrapperMixin],
|
|
||||||
components: {
|
components: {
|
||||||
baseInputButton,
|
baseInputButton
|
||||||
textLink
|
|
||||||
},
|
},
|
||||||
|
mixins: [inputButtonWrapperMixin],
|
||||||
computed: {
|
computed: {
|
||||||
arrayOfListItemsFromBodyText() {
|
arrayOfListItemsFromBodyText() {
|
||||||
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
|
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
|
||||||
|
|
@ -48,6 +55,7 @@ export default {
|
||||||
.split('- ') // At some point we'll want a better delimiter
|
.split('- ') // At some point we'll want a better delimiter
|
||||||
.filter((lineItem) => lineItem);
|
.filter((lineItem) => lineItem);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -217,8 +225,8 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import ProviderPreference from '@/layouts/provider-preference/provider-preference.vue'
|
import ProviderPreference from '@/layouts/provider-preference/provider-preference';
|
||||||
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage, setupModalLinks } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
||||||
|
|
@ -18,6 +18,29 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
setupModalLinks: jest.fn()
|
setupModalLinks: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks(mockApiResponses) {
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
route: 'provider-preference'
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = shallowMount(ProviderPreference,
|
||||||
|
mountOptions);
|
||||||
|
|
||||||
|
useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: {}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const apiResponses = mockApiResponses;
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => { });
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('provider-preference.vue', () => {
|
describe('provider-preference.vue', () => {
|
||||||
test('Should navigate to safelite flow when safelite selected', () => {
|
test('Should navigate to safelite flow when safelite selected', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -57,30 +80,3 @@ describe('provider-preference.vue', () => {
|
||||||
expect(wrapper.vm.$router.navigate).toBeCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, 'provider-preference');
|
expect(wrapper.vm.$router.navigate).toBeCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, 'provider-preference');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks(mockApiResponses) {
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
route: 'provider-preference'
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
|
||||||
ProviderPreference,
|
|
||||||
mountOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const apiResponses = mockApiResponses;
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
fetchCmsContentForPage.mockImplementation (() => {});
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,60 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeader" id="sub-header" class="mb-5 mt-4" />
|
<siteSubHeader
|
||||||
|
id="sub-header"
|
||||||
<buttonQuestion ref="buttonQuestion"
|
cmsWidgetName="SiteSubHeader"
|
||||||
|
class="mb-5 mt-4" />
|
||||||
|
<buttonQuestion
|
||||||
|
ref="buttonQuestion"
|
||||||
|
v-model="selectedProvider"
|
||||||
questionText="Select an option:"
|
questionText="Select an option:"
|
||||||
:answers="prefAnswers"
|
:answers="prefAnswers"
|
||||||
groupName="prefQuestions"
|
groupName="prefQuestions"
|
||||||
buttonTypeString="providerPrefRadio"
|
buttonTypeString="providerPrefRadio"
|
||||||
v-model="selectedProvider"
|
|
||||||
:validationRules="rules.optionRequired"
|
:validationRules="rules.optionRequired"
|
||||||
isRequired
|
isRequired
|
||||||
class="mx-5" />
|
class="mx-5" />
|
||||||
<div class="px-5">
|
<div class="px-5">
|
||||||
<siteFooter
|
<siteFooter
|
||||||
|
ref="siteFooter"
|
||||||
class="mt-5"
|
class="mt-5"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="isForwardActionDisabled"
|
:isForwardActionDisabled="isForwardActionDisabled"
|
||||||
@backClicked="backButtonAction"
|
@backClicked="backButtonAction"
|
||||||
@forwardClicked="forwardButtonAction"
|
@forwardClicked="forwardButtonAction" />
|
||||||
ref="siteFooter" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<recalModal ref="recalModal" cmsWidgetName="RecalModal" />
|
<recalModal
|
||||||
<steeringModal cmsWidgetName="StateSteeringModal" ref="StateSteeringModal" />
|
ref="recalModal"
|
||||||
|
cmsWidgetName="RecalModal" />
|
||||||
|
<steeringModal
|
||||||
|
ref="StateSteeringModal"
|
||||||
|
cmsWidgetName="StateSteeringModal" />
|
||||||
<shopPreferenceModal
|
<shopPreferenceModal
|
||||||
cmsWidgetName="ShopPreferenceDrawer"
|
|
||||||
ref="ShopPreferenceDrawer"
|
ref="ShopPreferenceDrawer"
|
||||||
@openSteering="openStateSteeringModal"
|
cmsWidgetName="ShopPreferenceDrawer"
|
||||||
:showSteeringLink="showSteeringLink"/>
|
:showSteeringLink="showSteeringLink"
|
||||||
<tpaRecalModal cmsWidgetName="TPARecalModal"
|
@openSteering="openStateSteeringModal" />
|
||||||
|
<tpaRecalModal
|
||||||
ref="TPARecalModal"
|
ref="TPARecalModal"
|
||||||
|
cmsWidgetName="TPARecalModal"
|
||||||
:ackError="ackError"
|
:ackError="ackError"
|
||||||
@buttonClick="navigateWithTPAAck"
|
@buttonClick="navigateWithTPAAck" />
|
||||||
/>
|
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
// Import Supporting Files
|
// Import Supporting Files
|
||||||
import { fetchCmsContentForPage, setupModalLinks, processIfStatements } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage, setupModalLinks } from '@/helpers/cms-content-helper';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { errorMessages } from '@/constants/error-messages';
|
import { errorMessages } from '@/constants/error-messages';
|
||||||
import buttonQuestion from '@/digital-components/button-question/button-question';
|
import buttonQuestion from '@/digital-components/button-question/button-question';
|
||||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal';
|
|
||||||
import { issPageValues } from '@/router/router-constants/issPage-values';
|
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
|
|
@ -55,42 +63,30 @@ import { Form } from 'vee-validate';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
import providerPrefRadio from './provider-pref-radio/provider-pref-radio';
|
|
||||||
import recalModal from '@/layouts/coverage-statement/recal-modal/recal-modal';
|
import recalModal from '@/layouts/coverage-statement/recal-modal/recal-modal';
|
||||||
import steeringModal from '@/layouts/provider-preference/steering-modal/steering-modal';
|
import steeringModal from '@/layouts/provider-preference/steering-modal/steering-modal';
|
||||||
import shopPreferenceModal from '@/layouts/provider-preference/shop-preference-modal/shop-preference-modal';
|
import shopPreferenceModal from '@/layouts/provider-preference/shop-preference-modal/shop-preference-modal';
|
||||||
import tpaRecalModal from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-modal.vue'
|
import tpaRecalModal from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-modal';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
|
|
||||||
const options = { SAFELITE: 'SafeliteOption', TPA: 'TPAOption' };
|
const options = { SAFELITE: 'SafeliteOption', TPA: 'TPAOption' };
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'provider-preference',
|
name: 'provider-preference',
|
||||||
mixins: [baseFormMixin],
|
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
siteFooter,
|
siteFooter,
|
||||||
siteHeader,
|
siteHeader,
|
||||||
siteSubHeader,
|
siteSubHeader,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
Form,
|
Form,
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
contentGroupModal,
|
|
||||||
providerPrefRadio,
|
|
||||||
recalModal,
|
recalModal,
|
||||||
steeringModal,
|
steeringModal,
|
||||||
shopPreferenceModal,
|
shopPreferenceModal,
|
||||||
tpaRecalModal
|
tpaRecalModal
|
||||||
},
|
},
|
||||||
data() {
|
mixins: [baseFormMixin],
|
||||||
return {
|
|
||||||
selectedProvider: null,
|
|
||||||
showSteeringLink: false,
|
|
||||||
tpaAcknowledgement: false,
|
|
||||||
rules: {
|
|
||||||
optionRequired: globalRules.OPTION_REQUIRED
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
|
|
@ -105,11 +101,21 @@ export default {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
|
||||||
vm.showSteeringLink = !!vm.$refs.StateSteeringModal.ModalBodyText;
|
vm.showSteeringLink = !!vm.$refs.StateSteeringModal.ModalBodyText;
|
||||||
if(vm.showSteeringLink) {
|
if (vm.showSteeringLink) {
|
||||||
vm.$refs.StateSteeringModal.openModal();
|
vm.$refs.StateSteeringModal.openModal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedProvider: null,
|
||||||
|
showSteeringLink: false,
|
||||||
|
tpaAcknowledgement: false,
|
||||||
|
rules: {
|
||||||
|
optionRequired: globalRules.OPTION_REQUIRED
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isForwardActionDisabled() {
|
isForwardActionDisabled() {
|
||||||
return this.selectedProvider === null;
|
return this.selectedProvider === null;
|
||||||
|
|
@ -140,13 +146,19 @@ export default {
|
||||||
return errorMessages.ACKNOWLEDGEMENT_REQUIRED;
|
return errorMessages.ACKNOWLEDGEMENT_REQUIRED;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
setupModalLinks(this);
|
||||||
|
const pageData = this.mainStore.pageData(issPageValues.PROVIDER_PREFERENCE);
|
||||||
|
this.selectedProvider = pageData?.selectedProvider ? pageData.selectedProvider : null;
|
||||||
|
this.tpaAcknowledgement = pageData?.tpaAcknowledgement ? pageData.tpaAcknowledgement : false;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getHeaderTextFromCms(cmsWidgetName) {
|
getHeaderTextFromCms(cmsWidgetName) {
|
||||||
const headerText = this.getCmsContent(cmsWidgetName, 'HeaderText');
|
const headerText = this.getCmsContent(cmsWidgetName, 'HeaderText');
|
||||||
return headerText?.replace('{custom:SafeliteLogo}', "<span class='safeliteLogo'></span>");
|
return headerText?.replace('{custom:SafeliteLogo}', "<span class='safeliteLogo'></span>");
|
||||||
},
|
},
|
||||||
getSubheaderTextFromCms(cmsWidgetName) {
|
getSubheaderTextFromCms(cmsWidgetName) {
|
||||||
return this.getCmsContent(cmsWidgetName, 'SubheaderText');
|
return this. getCmsContent(cmsWidgetName, 'SubheaderText');
|
||||||
},
|
},
|
||||||
getBodyTextFromCms(cmsWidgetName) {
|
getBodyTextFromCms(cmsWidgetName) {
|
||||||
return this.getCmsContent(cmsWidgetName, 'BodyText');
|
return this.getCmsContent(cmsWidgetName, 'BodyText');
|
||||||
|
|
@ -161,7 +173,10 @@ export default {
|
||||||
this.$router.navigate(scenario, this.$route);
|
this.$router.navigate(scenario, this.$route);
|
||||||
},
|
},
|
||||||
navigateWithTPAAck() {
|
navigateWithTPAAck() {
|
||||||
this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement});
|
this.mainStore.saveProviderPreferenceData({
|
||||||
|
selectedProvider: this.selectedProvider,
|
||||||
|
tpaAcknowledgement: this.tpaAcknowledgement
|
||||||
|
});
|
||||||
this.navigateForward(this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED);
|
this.navigateForward(this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED);
|
||||||
},
|
},
|
||||||
forwardButtonAction() {
|
forwardButtonAction() {
|
||||||
|
|
@ -183,24 +198,22 @@ export default {
|
||||||
scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED;
|
scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
};
|
default:
|
||||||
|
}
|
||||||
this.navigateForward(scenario);
|
this.navigateForward(scenario);
|
||||||
this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement});
|
this.mainStore.saveProviderPreferenceData({
|
||||||
|
selectedProvider: this.selectedProvider,
|
||||||
|
tpaAcknowledgement: this.tpaAcknowledgement
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openStateSteeringModal() {
|
openStateSteeringModal() {
|
||||||
this.$refs.StateSteeringModal.openModal();
|
this.$refs.StateSteeringModal.openModal();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
setupModalLinks(this);
|
|
||||||
const pageData = this.mainStore.pageData(issPageValues.PROVIDER_PREFERENCE);
|
|
||||||
this.selectedProvider = pageData?.selectedProvider ? pageData.selectedProvider : null;
|
|
||||||
this.tpaAcknowledgement = pageData?.tpaAcknowledgement ? pageData.tpaAcknowledgement : false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" >
|
<style lang="scss" scoped>
|
||||||
#sub-header span{
|
#sub-header span{
|
||||||
color: $black;
|
color: $black;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import shopPreferenceModal from './shop-preference-modal.vue'
|
|
||||||
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage, setupModalLinks } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
|
import shopPreferenceModal from './shop-preference-modal';
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -16,29 +15,6 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
setupModalLinks: jest.fn()
|
setupModalLinks: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('provider-preference.vue', () => {
|
|
||||||
test('Should display state specific steering modal link when in state with steering language', async () => {
|
|
||||||
// Arrange
|
|
||||||
const { wrapper } = setupMocks({showSteeringLink: true});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
|
|
||||||
// Test
|
|
||||||
expect(wrapper.vm.showSteeringLink).toBeTruthy();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Should not display state specific steering modal link when not in state with steering language', async () => {
|
|
||||||
// Arrange
|
|
||||||
const { wrapper } = setupMocks({showSteeringLink: false});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
|
|
||||||
// Test
|
|
||||||
expect(wrapper.vm.showSteeringLink).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks(propsData) {
|
function setupMocks(propsData) {
|
||||||
const mountOptions = getMountOptions({
|
const mountOptions = getMountOptions({
|
||||||
router: {
|
router: {
|
||||||
|
|
@ -48,15 +24,35 @@ function setupMocks(propsData) {
|
||||||
|
|
||||||
mountOptions.propsData = propsData;
|
mountOptions.propsData = propsData;
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
const wrapper = shallowMount(shopPreferenceModal,
|
||||||
shopPreferenceModal,
|
mountOptions);
|
||||||
mountOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {};
|
const apiResponses = {};
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
fetchCmsContentForPage.mockImplementation (() => {});
|
fetchCmsContentForPage.mockImplementation(() => { });
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('provider-preference.vue', () => {
|
||||||
|
test('Should display state specific steering modal link when in state with steering language', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({ showSteeringLink: true });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
// Test
|
||||||
|
expect(wrapper.vm.showSteeringLink).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not display state specific steering modal link when not in state with steering language', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({ showSteeringLink: false });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
|
||||||
|
// Test
|
||||||
|
expect(wrapper.vm.showSteeringLink).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,18 @@
|
||||||
:modalId="ModalName"
|
:modalId="ModalName"
|
||||||
:footerButtonText="ModalCloseButtonText"
|
:footerButtonText="ModalCloseButtonText"
|
||||||
@footer-button-event="footerButtonClick">
|
@footer-button-event="footerButtonClick">
|
||||||
<h5 class="text-center mb-4">{{ModalHeadline}}</h5>
|
<h5 class="text-center mb-4">
|
||||||
<div>
|
{{ ModalHeadline }}
|
||||||
<div class="mb-4" v-html="ModalBodyText"></div>
|
</h5>
|
||||||
<a
|
<div>
|
||||||
|
<div
|
||||||
|
class="mb-4"
|
||||||
|
v-html="ModalBodyText"></div>
|
||||||
|
<a
|
||||||
|
v-if="showSteeringLink"
|
||||||
class="modal-text"
|
class="modal-text"
|
||||||
v-if="showSteeringLink"
|
@click="openSteeringModal"
|
||||||
v-html="ModalSubBodyText"
|
v-html="ModalSubBodyText">
|
||||||
@click="openSteeringModal">
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
|
|
@ -23,6 +27,9 @@ import { states } from '@/constants/states';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'content-group-modal',
|
name: 'content-group-modal',
|
||||||
|
components: {
|
||||||
|
modal
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
showSteeringLink: Boolean
|
showSteeringLink: Boolean
|
||||||
|
|
@ -42,8 +49,8 @@ export default {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'BodyText');
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText');
|
||||||
},
|
},
|
||||||
ModalSubBodyText() {
|
ModalSubBodyText() {
|
||||||
let header = this.getCmsContent(this.cmsWidgetName, 'BodyText2');
|
const header = this.getCmsContent(this.cmsWidgetName, 'BodyText2');
|
||||||
return header.replace('{custom:state}', states[this.mainStore.order.customer.address.state])
|
return header.replace('{custom:state}', states[this.mainStore.order.customer.address.state]);
|
||||||
},
|
},
|
||||||
ModalImage() {
|
ModalImage() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'Image');
|
return this.getCmsContent(this.cmsWidgetName, 'Image');
|
||||||
|
|
@ -59,18 +66,15 @@ export default {
|
||||||
footerButtonClick() {
|
footerButtonClick() {
|
||||||
this.$refs[this.ModalName].closeModal();
|
this.$refs[this.ModalName].closeModal();
|
||||||
},
|
},
|
||||||
openSteeringModal(){
|
openSteeringModal() {
|
||||||
this.$refs[this.ModalName].closeModal();
|
this.$refs[this.ModalName].closeModal();
|
||||||
this.$emit('openSteering');
|
this.$emit('openSteering');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
modal
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.modal {
|
.modal {
|
||||||
&.modal-component {
|
&.modal-component {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import steeringModal from './steering-modal.vue'
|
|
||||||
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage, setupModalLinks } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
|
import steeringModal from './steering-modal';
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -17,31 +16,29 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
setupModalLinks: jest.fn()
|
setupModalLinks: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('steering-modal.vue', () => {
|
function setupMocks() {
|
||||||
test('getStateSpecificText should return true if state matches', () => {
|
|
||||||
const { wrapper } = setupMocks();
|
|
||||||
|
|
||||||
useMainStore().order.customer.address.state = 'OH';
|
|
||||||
expect(wrapper.vm.getStateSpecificText('OH')).toBeTruthy();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks(){
|
|
||||||
const mountOptions = getMountOptions({
|
const mountOptions = getMountOptions({
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
const wrapper = shallowMount(steeringModal,
|
||||||
steeringModal,
|
mountOptions);
|
||||||
mountOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {};
|
const apiResponses = {};
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
fetchCmsContentForPage.mockImplementation (() => {});
|
fetchCmsContentForPage.mockImplementation(() => { });
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('steering-modal.vue', () => {
|
||||||
|
test('getStateSpecificText should return true if state matches', () => {
|
||||||
|
const { wrapper } = setupMocks();
|
||||||
|
|
||||||
|
useMainStore().order.customer.address.state = 'OH';
|
||||||
|
expect(wrapper.vm.getStateSpecificText('OH')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,16 @@
|
||||||
:modalId="ModalName"
|
:modalId="ModalName"
|
||||||
:footerButtonText="ModalCloseButtonText"
|
:footerButtonText="ModalCloseButtonText"
|
||||||
@footer-button-event="footerButtonClick">
|
@footer-button-event="footerButtonClick">
|
||||||
<h5 class="text-center mb-4">{{ModalHeadline}}</h5>
|
<h5 class="text-center mb-4">
|
||||||
|
{{ ModalHeadline }}
|
||||||
|
</h5>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4" v-html="ModalBodyText"></div>
|
<div
|
||||||
<div v-if="ModalSubBodyText" v-html="ModalSubBodyText"></div>
|
class="mb-4"
|
||||||
|
v-html="ModalBodyText"></div>
|
||||||
|
<div
|
||||||
|
v-if="ModalSubBodyText"
|
||||||
|
v-html="ModalSubBodyText"></div>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -19,6 +25,9 @@ import { states } from '@/constants/states';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'content-group-modal',
|
name: 'content-group-modal',
|
||||||
|
components: {
|
||||||
|
modal
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String
|
cmsWidgetName: String
|
||||||
},
|
},
|
||||||
|
|
@ -27,8 +36,8 @@ export default {
|
||||||
return this.cmsWidgetName;
|
return this.cmsWidgetName;
|
||||||
},
|
},
|
||||||
ModalHeadline() {
|
ModalHeadline() {
|
||||||
let header = this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
const header = this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
return header.replace('{custom:state}', states[this.mainStore.order.customer.address.state])
|
return header.replace('{custom:state}', states[this.mainStore.order.customer.address.state]);
|
||||||
},
|
},
|
||||||
ModalSubheadertext() {
|
ModalSubheadertext() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'SubheaderText');
|
return this.getCmsContent(this.cmsWidgetName, 'SubheaderText');
|
||||||
|
|
@ -60,14 +69,11 @@ export default {
|
||||||
getStateSpecificText(value) {
|
getStateSpecificText(value) {
|
||||||
return this.mainStore.order.customer.address.state?.toLowerCase() == value?.toLowerCase();
|
return this.mainStore.order.customer.address.state?.toLowerCase() == value?.toLowerCase();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
modal
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.modal {
|
.modal {
|
||||||
&.modal-component {
|
&.modal-component {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import tpaRecalModal from './tpa-recal-modal.vue'
|
|
||||||
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
|
import tpaRecalModal from './tpa-recal-modal';
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -16,6 +15,24 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
setupModalLinks: jest.fn()
|
setupModalLinks: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks() {
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = shallowMount(tpaRecalModal,
|
||||||
|
mountOptions);
|
||||||
|
|
||||||
|
const apiResponses = {};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => { });
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('tpa-Recal-Modal.vue', () => {
|
describe('tpa-Recal-Modal.vue', () => {
|
||||||
test('should show error if not acknowledged', () => {
|
test('should show error if not acknowledged', () => {
|
||||||
const { wrapper } = setupMocks();
|
const { wrapper } = setupMocks();
|
||||||
|
|
@ -23,7 +40,7 @@ describe('tpa-Recal-Modal.vue', () => {
|
||||||
wrapper.vm.footerButtonClick();
|
wrapper.vm.footerButtonClick();
|
||||||
|
|
||||||
expect(wrapper.vm.showError).toBeTruthy();
|
expect(wrapper.vm.showError).toBeTruthy();
|
||||||
})
|
});
|
||||||
|
|
||||||
test('should not show error if acknowledged', () => {
|
test('should not show error if acknowledged', () => {
|
||||||
const { wrapper } = setupMocks();
|
const { wrapper } = setupMocks();
|
||||||
|
|
@ -31,25 +48,5 @@ describe('tpa-Recal-Modal.vue', () => {
|
||||||
wrapper.vm.footerButtonClick();
|
wrapper.vm.footerButtonClick();
|
||||||
|
|
||||||
expect(wrapper.vm.showError).toBeFalsy();
|
expect(wrapper.vm.showError).toBeFalsy();
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks(){
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
const wrapper = shallowMount(
|
|
||||||
tpaRecalModal,
|
|
||||||
mountOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
fetchCmsContentForPage.mockImplementation (() => {});
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,22 @@
|
||||||
:ref="ModalName"
|
:ref="ModalName"
|
||||||
:modalId="ModalName"
|
:modalId="ModalName"
|
||||||
:footerButtonText="ModalCloseButtonText"
|
:footerButtonText="ModalCloseButtonText"
|
||||||
@footer-button-event="footerButtonClick"
|
:isButtonDisabled="isButtonDisabled"
|
||||||
:isButtonDisabled="isButtonDisabled">
|
@footer-button-event="footerButtonClick">
|
||||||
<div class="form-test-invalid">
|
<div class="form-test-invalid">
|
||||||
<h5 class="text-center mb-4">{{ModalHeadline}}</h5>
|
<h5 class="text-center mb-4">
|
||||||
|
{{ ModalHeadline }}
|
||||||
|
</h5>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4" v-html="ModalBodyText"></div>
|
<div
|
||||||
<tpaRecalToggle class="mb-5" cmsWidgetName="TPARecalModalToggle"/>
|
class="mb-4"
|
||||||
|
v-html="ModalBodyText"></div>
|
||||||
|
<tpaRecalToggle
|
||||||
|
class="mb-5"
|
||||||
|
cmsWidgetName="TPARecalModalToggle" />
|
||||||
<checkBox
|
<checkBox
|
||||||
|
ref="tpaAcknowledgement"
|
||||||
|
v-model="acknowledged"
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
:class="showError && ' has-error'"
|
:class="showError && ' has-error'"
|
||||||
:validationRules="rules.optionRequired"
|
:validationRules="rules.optionRequired"
|
||||||
|
|
@ -19,12 +27,11 @@
|
||||||
:tabIndex="0"
|
:tabIndex="0"
|
||||||
:checkboxLabel="ModalSubBodyText"
|
:checkboxLabel="ModalSubBodyText"
|
||||||
:screenReaderOnlyText="ModalSubBodyText"
|
:screenReaderOnlyText="ModalSubBodyText"
|
||||||
isRequired
|
isRequired />
|
||||||
ref="tpaAcknowledgement"
|
<div
|
||||||
v-model="acknowledged"
|
v-if="showError"
|
||||||
/>
|
class="row form-test-error mt-1">
|
||||||
<div v-if="showError" class="row form-test-error mt-1">
|
<p>{{ ackError }}</p>
|
||||||
<p>{{ackError}}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -33,16 +40,22 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import modal from '@/digital-components/modal/modal';
|
import modal from '@/digital-components/modal/modal';
|
||||||
import tpaRecalToggle from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-toggle/tpa-recal-toggle.vue'
|
import tpaRecalToggle from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-toggle/tpa-recal-toggle';
|
||||||
import checkBox from '@/ux-components/checkbox/checkbox.vue'
|
import checkBox from '@/ux-components/checkbox/checkbox';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'content-group-modal',
|
name: 'content-group-modal',
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
tpaRecalToggle,
|
||||||
|
checkBox
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
ackError: String
|
ackError: String
|
||||||
},
|
},
|
||||||
|
emits: ['buttonClick'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
acknowledged: false,
|
acknowledged: false,
|
||||||
|
|
@ -52,7 +65,6 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
emits: ['buttonClick'],
|
|
||||||
computed: {
|
computed: {
|
||||||
ModalName() {
|
ModalName() {
|
||||||
return this.cmsWidgetName;
|
return this.cmsWidgetName;
|
||||||
|
|
@ -70,7 +82,12 @@ export default {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
},
|
},
|
||||||
isButtonDisabled() {
|
isButtonDisabled() {
|
||||||
return !this.acknowledged
|
return !this.acknowledged;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
acknowledged() {
|
||||||
|
this.showError = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -80,8 +97,7 @@ export default {
|
||||||
|
|
||||||
footerButtonClick() {
|
footerButtonClick() {
|
||||||
// check if acked, if not show error
|
// check if acked, if not show error
|
||||||
if (this.acknowledged)
|
if (this.acknowledged) {
|
||||||
{
|
|
||||||
this.$refs[this.ModalName]?.closeModal();
|
this.$refs[this.ModalName]?.closeModal();
|
||||||
this.$emit('buttonClick');
|
this.$emit('buttonClick');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -89,21 +105,11 @@ export default {
|
||||||
this.showError = true;
|
this.showError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
acknowledged() {
|
|
||||||
this.showError = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
modal,
|
|
||||||
tpaRecalToggle,
|
|
||||||
checkBox
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.modal {
|
.modal {
|
||||||
&.modal-component {
|
&.modal-component {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
/* eslint-env jest */
|
/* eslint-env jest */
|
||||||
import { render } from '@testing-library/vue';
|
import { render } from '@testing-library/vue';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
import { issPageValues } from '@/router/router-constants/issPage-values';
|
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||||
import { queryStrings } from '@/constants/query-strings';
|
import { queryStrings } from '@/constants/query-strings';
|
||||||
import { GaActions } from '@/constants/analytics';
|
import { GaActions } from '@/constants/analytics';
|
||||||
import tpaRecalToggle from './tpa-recal-toggle.vue';
|
import tpaRecalToggle from './tpa-recal-toggle';
|
||||||
|
|
||||||
const mockText = Object.freeze({
|
const mockText = Object.freeze({
|
||||||
HEADER: 'Mock Header',
|
HEADER: 'Mock Header',
|
||||||
|
|
@ -72,7 +71,7 @@ describe('more details section', () => {
|
||||||
test('should toggle when arrow clicked', async () => {
|
test('should toggle when arrow clicked', async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
const { container } = render(tpaRecalToggle, mountOptions);
|
const { container } = render(tpaRecalToggle, mountOptions);
|
||||||
const toggleLink = container.querySelector('#moreDetails');;
|
const toggleLink = container.querySelector('#moreDetails');
|
||||||
|
|
||||||
await user.click(toggleLink);
|
await user.click(toggleLink);
|
||||||
let moreDetailsSection = container.querySelector('#tpa-recal-detail-wrapper');
|
let moreDetailsSection = container.querySelector('#tpa-recal-detail-wrapper');
|
||||||
|
|
|
||||||
|
|
@ -3,41 +3,37 @@
|
||||||
<div
|
<div
|
||||||
class="tpa-toggle"
|
class="tpa-toggle"
|
||||||
:class="[isDetailVisible ? 'active' : '']"
|
:class="[isDetailVisible ? 'active' : '']"
|
||||||
@click="handleClickToggle"
|
@click="handleClickToggle">
|
||||||
>
|
|
||||||
<textLink
|
<textLink
|
||||||
|
id="moreDetails"
|
||||||
linkType="text"
|
linkType="text"
|
||||||
href="#!"
|
href="#!"
|
||||||
:text="textForToggle"
|
:text="textForToggle" />
|
||||||
id="moreDetails"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<Transition>
|
<Transition>
|
||||||
<div
|
<div
|
||||||
v-show="isDetailVisible"
|
v-show="isDetailVisible"
|
||||||
id="tpa-recal-detail-wrapper"
|
id="tpa-recal-detail-wrapper"
|
||||||
class="mt-2"
|
class="mt-2">
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-html="detailContent"
|
|
||||||
id="tpa-recal-detail-content"
|
id="tpa-recal-detail-content"
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
/>
|
v-html="detailContent" />
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
import textLink from '@/ux-components/text-link/text-link';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'tpa-recal-toggle',
|
name: 'tpa-recal-toggle',
|
||||||
props: {
|
|
||||||
cmsWidgetName: String
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
textLink
|
textLink
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: String
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isDetailVisible: false
|
isDetailVisible: false
|
||||||
|
|
@ -58,7 +54,7 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.tpa-recal-toggle {
|
.tpa-recal-toggle {
|
||||||
.tpa-toggle {
|
.tpa-toggle {
|
||||||
&::after {
|
&::after {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2 review">
|
<div class="container-fluid pb-2 review">
|
||||||
<p>Placeholder for review page</p>
|
<p>Placeholder for review page</p>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
cmsWidgetName="SiteFooterWidget"
|
ref="siteFooter"
|
||||||
ref="siteFooter"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="navigateForward"
|
@ForwardClicked="navigateForward"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -27,15 +30,16 @@ import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'review-page',
|
name: 'review-page',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
return { mainStore };
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
@ -46,33 +50,31 @@ export default {
|
||||||
promise: cmsContentPromise
|
promise: cmsContentPromise
|
||||||
}];
|
}];
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods:
|
setup() {
|
||||||
{
|
const mainStore = useMainStore();
|
||||||
backButtonAction() {
|
return { mainStore };
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
},
|
||||||
},
|
data() {
|
||||||
forwardButtonAction() {
|
},
|
||||||
},
|
methods: {
|
||||||
navigateForward() {
|
backButtonAction() {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
this.navigationScenarios.CLICKED_FORWARD,
|
|
||||||
this.$route
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
components: {
|
forwardButtonAction() {
|
||||||
siteHeader,
|
},
|
||||||
siteFooter,
|
navigateForward() {
|
||||||
Form
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
|
||||||
|
this.$route);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.review p{
|
.review p{
|
||||||
margin-bottom:0.75rem;
|
margin-bottom:0.75rem;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2">
|
<div class="container-fluid pb-2">
|
||||||
<p>Placeholder for schedule page</p>
|
<p>Placeholder for schedule page</p>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
class="mt-5"
|
ref="siteFooter"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
class="mt-5"
|
||||||
ref="siteFooter"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -32,16 +35,14 @@ import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'schedule-page',
|
name: 'schedule-page',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
return { mainStore };
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next)
|
|
||||||
{
|
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
||||||
|
|
@ -53,11 +54,18 @@ export default {
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
return { mainStore };
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
|
|
@ -72,13 +80,6 @@ export default {
|
||||||
|
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
components: {
|
};
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
Form
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,24 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import serviceLocation from '@/layouts/service-location/service-location.vue';
|
import serviceLocation from '@/layouts/service-location/service-location';
|
||||||
import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-location-helper';
|
|
||||||
|
|
||||||
// Define Mocks
|
// Define Mocks
|
||||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn(() => {
|
fetchCmsContentForPage: jest.fn(() => Promise.resolve('content'))
|
||||||
return Promise.resolve('content');
|
|
||||||
})
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const mockGetServiceabilityDetails = (mockServiceZipCode) => {
|
function setupMocks() {
|
||||||
|
const wrapper = shallowMount(serviceLocation,
|
||||||
|
getMountOptions({
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockGetServiceabilityDetails = () => {
|
||||||
const serviceabilityDetails = {
|
const serviceabilityDetails = {
|
||||||
isGlassServiceableInshop: true,
|
isGlassServiceableInshop: true,
|
||||||
isRecalibrationServiceableInshop: true,
|
isRecalibrationServiceableInshop: true,
|
||||||
|
|
@ -21,18 +29,15 @@ const mockGetServiceabilityDetails = (mockServiceZipCode) => {
|
||||||
return Promise.resolve(serviceabilityDetails);
|
return Promise.resolve(serviceabilityDetails);
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock(
|
jest.mock('@/helpers/service-location-helper',
|
||||||
'@/helpers/service-location-helper',
|
|
||||||
() => ({
|
() => ({
|
||||||
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode))
|
||||||
return mockGetServiceabilityDetails(mockServiceZipCode);
|
}));
|
||||||
})
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
// linkWidgetName is not defined. This whole spec file needs review.
|
||||||
if (widgetName === linkWidgetName) {
|
if (widgetName === linkWidgetName) {
|
||||||
return mockLinkCmsContent[cmsFieldName];
|
return mockLinkCmsContent[cmsFieldName];
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +135,7 @@ describe('updating service zip', () => {
|
||||||
|
|
||||||
const newServiceZipCodeQuestion = {
|
const newServiceZipCodeQuestion = {
|
||||||
zipCode: '45433',
|
zipCode: '45433',
|
||||||
state: 'OH',
|
state: 'OH'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -140,16 +145,3 @@ describe('updating service zip', () => {
|
||||||
expect(wrapper.vm.zipContainsMilitaryBase).toBe(true);
|
expect(wrapper.vm.zipContainsMilitaryBase).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks() {
|
|
||||||
const wrapper = shallowMount(
|
|
||||||
serviceLocation,
|
|
||||||
getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,50 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" id="sub-header" class="mt-5" />
|
<siteSubHeader
|
||||||
|
id="sub-header"
|
||||||
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
|
class="mt-5" />
|
||||||
<div class="select-car">
|
<div class="select-car">
|
||||||
<div class="container-fluid pb-2">
|
<div class="container-fluid pb-2">
|
||||||
<div class="row px-3">
|
<div class="row px-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="select-car-form rounded">
|
<div class="select-car-form rounded">
|
||||||
<serviceZipModalQuestion
|
<serviceZipModalQuestion
|
||||||
v-model="serviceZipCodeQuestion"
|
|
||||||
ref="serviceZipCodeQuestion"
|
ref="serviceZipCodeQuestion"
|
||||||
|
v-model="serviceZipCodeQuestion"
|
||||||
|
modalWidgetName="ServiceZipModalWidget"
|
||||||
@updated-serviceability="setServiceabilityDetails"
|
@updated-serviceability="setServiceabilityDetails"
|
||||||
@updated-contains-military-base="setContainsMilitaryBase"
|
@updated-contains-military-base="setContainsMilitaryBase" />
|
||||||
modalWidgetName="ServiceZipModalWidget" />
|
|
||||||
<alert
|
<alert
|
||||||
|
v-if="displayMilitaryZipAlert"
|
||||||
ref="alertMilitaryBaseZip"
|
ref="alertMilitaryBaseZip"
|
||||||
class="my-5"
|
class="my-5"
|
||||||
cmsWidgetName="AlertMilitaryBaseZipWidget"
|
cmsWidgetName="AlertMilitaryBaseZipWidget"
|
||||||
v-if="displayMilitaryZipAlert"
|
|
||||||
alertClass="alert-warning" />
|
alertClass="alert-warning" />
|
||||||
<buttonQuestion
|
<buttonQuestion
|
||||||
|
v-model="selectedAppointmentType"
|
||||||
cmsWidgetName="ServiceTypeQuestionWidget"
|
cmsWidgetName="ServiceTypeQuestionWidget"
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="answersFromCms"
|
:answers="answersFromCms"
|
||||||
buttonTypeString="listCard"
|
buttonTypeString="listCard"
|
||||||
isRequired
|
isRequired
|
||||||
v-model="selectedAppointmentType"
|
|
||||||
validationRules="selection-required"
|
validationRules="selection-required"
|
||||||
class="service-location-button-question mb-1"/>
|
class="service-location-button-question mb-1" />
|
||||||
<div class="select-car">
|
<div class="select-car">
|
||||||
<siteFooter
|
<siteFooter
|
||||||
|
ref="siteFooter"
|
||||||
class="mt-5"
|
class="mt-5"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@backClicked="backButtonAction"
|
@backClicked="backButtonAction"
|
||||||
@forwardClicked="forwardButtonAction"
|
@forwardClicked="forwardButtonAction" />
|
||||||
ref="siteFooter"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -62,17 +68,26 @@ import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-loca
|
||||||
// Import Component
|
// Import Component
|
||||||
import alert from '@/ux-components/alert/alert';
|
import alert from '@/ux-components/alert/alert';
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import baseMixin from '@/mixins/base-mixin';
|
|
||||||
import { Form, defineRule } from 'vee-validate';
|
import { Form, defineRule } from 'vee-validate';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
import serviceZipModalQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue';
|
import serviceZipModalQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-modal-question';
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule('selection-required', required(errorMessages.OPTION_REQUIRED));
|
defineRule('selection-required', required(errorMessages.OPTION_REQUIRED));
|
||||||
export default {
|
export default {
|
||||||
name: 'service-location',
|
name: 'service-location',
|
||||||
|
components: {
|
||||||
|
siteFooter,
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
buttonQuestion,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form,
|
||||||
|
serviceZipModalQuestion,
|
||||||
|
alert
|
||||||
|
},
|
||||||
mixins: [baseFormMixin],
|
mixins: [baseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -103,10 +118,8 @@ export default {
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.setData(
|
vm.setData(resultMap.zipCodeData,
|
||||||
resultMap.zipCodeData,
|
resultMap.serviceabilityDetails);
|
||||||
resultMap.serviceabilityDetails
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
|
@ -132,25 +145,25 @@ export default {
|
||||||
return this.getCmsContent('ServiceTypeQuestionWidget', 'Answers');
|
return this.getCmsContent('ServiceTypeQuestionWidget', 'Answers');
|
||||||
},
|
},
|
||||||
serviceZipCodeQuestion: {
|
serviceZipCodeQuestion: {
|
||||||
get: function() {
|
get() {
|
||||||
return {
|
return {
|
||||||
zipCode: this.zipCode,
|
zipCode: this.zipCode,
|
||||||
state: this.state
|
state: this.state
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set(newValue) {
|
||||||
this.zipCode = newValue.zipCode;
|
this.zipCode = newValue.zipCode;
|
||||||
this.state = newValue.state;
|
this.state = newValue.state;
|
||||||
|
|
||||||
|
// TODO: review - this seems like it should be awaited.
|
||||||
this.$nextTick();
|
this.$nextTick();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isServiceableMobile() {
|
isServiceableMobile() {
|
||||||
if (this.isRecalibrationServiceableMobile !== null) {
|
if (this.isRecalibrationServiceableMobile !== null) {
|
||||||
return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
|
return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
|
||||||
} else {
|
|
||||||
return this.isGlassServiceableMobile;
|
|
||||||
}
|
}
|
||||||
|
return this.isGlassServiceableMobile;
|
||||||
},
|
},
|
||||||
displayMilitaryZipAlert() {
|
displayMilitaryZipAlert() {
|
||||||
return this.zipContainsMilitaryBase && this.isServiceableMobile;
|
return this.zipContainsMilitaryBase && this.isServiceableMobile;
|
||||||
|
|
@ -188,26 +201,17 @@ export default {
|
||||||
},
|
},
|
||||||
setServiceabilityDetails(serviceabilityDetails) {
|
setServiceabilityDetails(serviceabilityDetails) {
|
||||||
this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop;
|
this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop;
|
||||||
this.isRecalibrationServiceableInshop =
|
this.isRecalibrationServiceableInshop
|
||||||
serviceabilityDetails.isRecalibrationServiceableInshop;
|
= serviceabilityDetails.isRecalibrationServiceableInshop;
|
||||||
this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile;
|
this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile;
|
||||||
this.isRecalibrationServiceableMobile =
|
this.isRecalibrationServiceableMobile
|
||||||
serviceabilityDetails.isRecalibrationServiceableMobile;
|
= serviceabilityDetails.isRecalibrationServiceableMobile;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
siteFooter,
|
|
||||||
siteHeader,
|
|
||||||
siteSubHeader,
|
|
||||||
buttonQuestion,
|
|
||||||
Form,
|
|
||||||
serviceZipModalQuestion,
|
|
||||||
alert
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.page-container-grouped-styles {
|
.page-container-grouped-styles {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import { mount, shallowMount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import serviceZipModalQuestion from './service-zip-modal-question';
|
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
import serviceZipModalQuestion from './service-zip-modal-question';
|
||||||
|
|
||||||
global.crypto = crypto;
|
global.crypto = crypto;
|
||||||
|
|
||||||
jest.mock('@/digital-components/textbox-question/textbox-question', () => ({
|
jest.mock('@/digital-components/textbox-question/textbox-question', () => ({
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => widgetName[cmsFieldName])
|
||||||
return widgetName[cmsFieldName];
|
|
||||||
})
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/digital-components/modal/modal', () => ({
|
jest.mock('@/digital-components/modal/modal', () => ({
|
||||||
|
|
@ -17,7 +15,7 @@ jest.mock('@/digital-components/modal/modal', () => ({
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const mockGetServiceabilityDetails = (mockServiceZipCode) => {
|
const mockGetServiceabilityDetails = () => {
|
||||||
const serviceabilityDetails = {
|
const serviceabilityDetails = {
|
||||||
isGlassServiceableInshop: true,
|
isGlassServiceableInshop: true,
|
||||||
isRecalibrationServiceableInshop: true,
|
isRecalibrationServiceableInshop: true,
|
||||||
|
|
@ -53,19 +51,13 @@ const mockGetZipCodeData = (mockServiceZipCode) => {
|
||||||
state: null,
|
state: null,
|
||||||
zipCodeCtu: null
|
zipCodeCtu: null
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
jest.mock(
|
jest.mock('@/helpers/service-location-helper',
|
||||||
'@/helpers/service-location-helper',
|
|
||||||
() => ({
|
() => ({
|
||||||
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode)),
|
||||||
return mockGetServiceabilityDetails(mockServiceZipCode);
|
getZipCodeData: jest.fn((mockServiceZipCode) => mockGetZipCodeData(mockServiceZipCode))
|
||||||
}),
|
}));
|
||||||
getZipCodeData: jest.fn((mockServiceZipCode) => {
|
|
||||||
return mockGetZipCodeData(mockServiceZipCode);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const linkWidgetName = 'linkWidgetName';
|
const linkWidgetName = 'linkWidgetName';
|
||||||
const modalWidgetName = 'modalWidgetName';
|
const modalWidgetName = 'modalWidgetName';
|
||||||
|
|
@ -91,12 +83,12 @@ const mockMixin = {
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
describe('service-zip-modal-question.vue', () => {
|
describe('service-zip-modal-question.vue', () => {
|
||||||
it('Initial state on load with existing location info', async () => {
|
it('Initial state on load with existing location info', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'OH',
|
state: 'OH',
|
||||||
zipCode: '43235'
|
zipCode: '43235'
|
||||||
};
|
};
|
||||||
|
|
@ -105,19 +97,19 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
linkWidgetName: linkWidgetName,
|
linkWidgetName,
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.html()).not.toEqual(expect.stringContaining(mockLinkCmsContent['BodyText']));
|
expect(wrapper.html()).not.toEqual(expect.stringContaining(mockLinkCmsContent.BodyText));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should emit update:modelValue on setZipCode for a valid, serviceable zip', async () => {
|
it('Should emit update:modelValue on setZipCode for a valid, serviceable zip', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'IL',
|
state: 'IL',
|
||||||
zipCode: '61606'
|
zipCode: '61606'
|
||||||
};
|
};
|
||||||
|
|
@ -129,7 +121,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
mobileFeePart: {},
|
mobileFeePart: {},
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
@ -139,7 +131,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
|
|
||||||
await wrapper.vm.setZipCode();
|
await wrapper.vm.setZipCode();
|
||||||
|
|
||||||
let expectedEmit = [[{ state: 'OH', zipCode: '43235' }]];
|
const expectedEmit = [[{ state: 'OH', zipCode: '43235' }]];
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.emitted('update:modelValue')).toEqual(expectedEmit);
|
expect(wrapper.emitted('update:modelValue')).toEqual(expectedEmit);
|
||||||
|
|
@ -147,7 +139,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
|
|
||||||
it('Should not emit update:modelValue on setZipCode for an invalid zip', async () => {
|
it('Should not emit update:modelValue on setZipCode for an invalid zip', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'IL',
|
state: 'IL',
|
||||||
zipCode: '61606'
|
zipCode: '61606'
|
||||||
};
|
};
|
||||||
|
|
@ -158,7 +150,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
@ -173,7 +165,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
|
|
||||||
it('Should display invalid zip alerts for invalid ip inputs', async () => {
|
it('Should display invalid zip alerts for invalid ip inputs', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'IL',
|
state: 'IL',
|
||||||
zipCode: '61606'
|
zipCode: '61606'
|
||||||
};
|
};
|
||||||
|
|
@ -184,7 +176,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
@ -199,7 +191,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
|
|
||||||
it('Should reset all alerts on onModalClosed', async () => {
|
it('Should reset all alerts on onModalClosed', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'IL',
|
state: 'IL',
|
||||||
zipCode: '61606'
|
zipCode: '61606'
|
||||||
};
|
};
|
||||||
|
|
@ -210,7 +202,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
@ -226,7 +218,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
|
|
||||||
it('Should prepopulate the zip on onModalOpened', async () => {
|
it('Should prepopulate the zip on onModalOpened', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let serviceZipCodeQuestion = {
|
const serviceZipCodeQuestion = {
|
||||||
state: 'IL',
|
state: 'IL',
|
||||||
zipCode: '61606'
|
zipCode: '61606'
|
||||||
};
|
};
|
||||||
|
|
@ -237,7 +229,7 @@ describe('service-zip-modal-question.vue', () => {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin],
|
||||||
props: {
|
props: {
|
||||||
modelValue: serviceZipCodeQuestion,
|
modelValue: serviceZipCodeQuestion,
|
||||||
modalWidgetName: modalWidgetName
|
modalWidgetName
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
linkType="text"
|
linkType="text"
|
||||||
:text="serviceZipLinkText"
|
:text="serviceZipLinkText"
|
||||||
href="#!"
|
href="#!"
|
||||||
@click-event="openModal"
|
aria-label="Modal window"
|
||||||
aria-label="Modal window" />
|
@click-event="openModal" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<modal
|
<modal
|
||||||
|
|
@ -16,40 +16,38 @@
|
||||||
:onModalOpenedCallback="onModalOpened"
|
:onModalOpenedCallback="onModalOpened"
|
||||||
:onModalClosedCallback="onModalClosed"
|
:onModalClosedCallback="onModalClosed"
|
||||||
:footerButtonText="modalFooterText"
|
:footerButtonText="modalFooterText"
|
||||||
@footer-button-event="setZipCode" >
|
@footer-button-event="setZipCode">
|
||||||
<serviceZipQuestion
|
<serviceZipQuestion
|
||||||
ref="serviceZipCodeQuestion"
|
ref="serviceZipCodeQuestion"
|
||||||
customInputId="serviceZipCode"
|
|
||||||
v-model="internalModel.zipCode"
|
v-model="internalModel.zipCode"
|
||||||
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }"
|
customInputId="serviceZipCode"
|
||||||
:cmsWidgetName="textboxQuestionWidgetName" />
|
:cmsWidgetName="textboxQuestionWidgetName"
|
||||||
|
v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertInvalidZip"
|
|
||||||
v-if="displayInvalidZipAlert"
|
v-if="displayInvalidZipAlert"
|
||||||
|
ref="alertInvalidZip"
|
||||||
class="my-4"
|
class="my-4"
|
||||||
:cmsWidgetName="alertInvalidZipWidgetName"
|
:cmsWidgetName="alertInvalidZipWidgetName"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import textLink from '@/ux-components/text-link/text-link';
|
import textLink from '@/ux-components/text-link/text-link';
|
||||||
import serviceZipQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-question/service-zip-question';
|
import serviceZipQuestion from '@/layouts/service-location/service-zip-modal-question/service-zip-question/service-zip-question';
|
||||||
import modal from '@/digital-components/modal/modal.vue'
|
import modal from '@/digital-components/modal/modal';
|
||||||
import alert from '@/ux-components/alert/alert';
|
import alert from '@/ux-components/alert/alert';
|
||||||
|
|
||||||
import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-location-helper';
|
import { getServiceabilityDetails, getZipCodeData } from '@/helpers/service-location-helper';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'service-zip-modal-question',
|
name: 'service-zip-modal-question',
|
||||||
emits: ['update:modelValue', 'updated-serviceability', 'updated-contains-military-base'],
|
components: {
|
||||||
data() {
|
textLink,
|
||||||
return {
|
modal,
|
||||||
internalModel: this.copyModel(this.modelValue),
|
serviceZipQuestion,
|
||||||
serviceZipCodeTextInputId: '',
|
alert
|
||||||
displayInvalidZipAlert: false
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
|
@ -61,6 +59,7 @@ export default {
|
||||||
},
|
},
|
||||||
modalWidgetName: String
|
modalWidgetName: String
|
||||||
},
|
},
|
||||||
|
emits: ['update:modelValue', 'updated-serviceability', 'updated-contains-military-base'],
|
||||||
setup() {
|
setup() {
|
||||||
const textboxQuestionWidgetName = 'ServiceZipQuestionWidget';
|
const textboxQuestionWidgetName = 'ServiceZipQuestionWidget';
|
||||||
const alertInvalidZipWidgetName = 'AlertInvalidZipWidget';
|
const alertInvalidZipWidgetName = 'AlertInvalidZipWidget';
|
||||||
|
|
@ -69,11 +68,19 @@ export default {
|
||||||
alertInvalidZipWidgetName
|
alertInvalidZipWidgetName
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
internalModel: this.copyModel(this.modelValue),
|
||||||
|
serviceZipCodeTextInputId: '',
|
||||||
|
displayInvalidZipAlert: false
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
serviceZipLinkText() {
|
serviceZipLinkText() {
|
||||||
if (this.modelValue.zipCode && this.modelValue.zipCode.length > 0) {
|
if (this.modelValue.zipCode && this.modelValue.zipCode.length > 0) {
|
||||||
return this.modelValue.state + ', ' + this.modelValue.zipCode;
|
return `${this.modelValue.state}, ${this.modelValue.zipCode}`;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
modalHeaderText() {
|
modalHeaderText() {
|
||||||
return this.getCmsContent(this.textboxQuestionWidgetName, 'QuestionText');
|
return this.getCmsContent(this.textboxQuestionWidgetName, 'QuestionText');
|
||||||
|
|
@ -85,6 +92,16 @@ export default {
|
||||||
return this.modalWidgetName;
|
return this.modalWidgetName;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
modelValue(newValue) {
|
||||||
|
this.internalModel = this.copyModel(newValue);
|
||||||
|
},
|
||||||
|
'internalModel.zipCode': {
|
||||||
|
handler() {
|
||||||
|
this.resetsOnZipInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetAlerts() {
|
resetAlerts() {
|
||||||
this.displayInvalidZipAlert = false;
|
this.displayInvalidZipAlert = false;
|
||||||
|
|
@ -152,22 +169,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getZipCodeData
|
getZipCodeData
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
modelValue(newValue) {
|
|
||||||
this.internalModel = this.copyModel(newValue);
|
|
||||||
},
|
|
||||||
'internalModel.zipCode': {
|
|
||||||
handler() {
|
|
||||||
this.resetsOnZipInput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
textLink,
|
|
||||||
modal,
|
|
||||||
serviceZipQuestion,
|
|
||||||
alert
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ describe('service-zip-question.vue', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const modelValueText = wrapper.vm.value;
|
|
||||||
wrapper.vm.value = 'test also';
|
wrapper.vm.value = 'test also';
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
ref="zipInputTextQuestion"
|
ref="zipInputTextQuestion"
|
||||||
:cmsWidgetName="cmsWidgetName"
|
|
||||||
v-model="value"
|
v-model="value"
|
||||||
|
:cmsWidgetName="cmsWidgetName"
|
||||||
inputId="serviceZipCode"
|
inputId="serviceZipCode"
|
||||||
questionAlignment="center"
|
questionAlignment="center"
|
||||||
cornerStyle="rounded"
|
cornerStyle="rounded"
|
||||||
|
|
@ -26,6 +26,9 @@ defineRule('zip-format', regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVIC
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'service-zip-question',
|
name: 'service-zip-question',
|
||||||
|
components: {
|
||||||
|
textboxQuestion
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
serviceZipCode: String
|
serviceZipCode: String
|
||||||
|
|
@ -34,16 +37,13 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
value: {
|
value: {
|
||||||
get: function () {
|
get() {
|
||||||
return this.modelValue;
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set(newValue) {
|
||||||
this.$emit('update:modelValue', newValue);
|
this.$emit('update:modelValue', newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
textboxQuestion
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,38 @@
|
||||||
export const allGlassPartsAndItemsHavePrices = (lineItems) => {
|
const hasPrice = (lineItem) => {
|
||||||
if (lineItems.glassParts && Array.isArray(lineItems.glassParts)) {
|
const value = (!!lineItem?.kitPrice && lineItem.kitPrice !== 0)
|
||||||
if (!processLineItems(lineItems.glassParts))
|
|| (!!lineItem?.laborAmount && lineItem.laborAmount !== 0)
|
||||||
{
|
|| (!!lineItem?.sellingPrice && lineItem.sellingPrice !== 0);
|
||||||
return false;
|
return value;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (lineItems.supportingItems && Array.isArray(lineItems.supportingItems)) {
|
|
||||||
if (!processLineItems(lineItems.supportingItems))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (lineItems.vaps && Array.isArray(lineItems.vaps)) {
|
|
||||||
if (!processLineItems(lineItems.vaps))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const processLineItems = (lineItems) => {
|
const processLineItems = (lineItems) => {
|
||||||
let returnVal = true;
|
let returnVal = true;
|
||||||
lineItems.forEach( lineItem => {
|
lineItems.forEach((lineItem) => {
|
||||||
if (!hasPrice(lineItem)) {
|
if (!hasPrice(lineItem)) {
|
||||||
returnVal = false;
|
returnVal = false;
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
};
|
||||||
|
|
||||||
const hasPrice = (lineItem) => {
|
export const allGlassPartsAndItemsHavePrices = (lineItems) => {
|
||||||
const value = (!!lineItem?.kitPrice && lineItem.kitPrice != 0) ||
|
if (lineItems.glassParts && Array.isArray(lineItems.glassParts)) {
|
||||||
(!!lineItem?.laborAmount && lineItem.laborAmount != 0) ||
|
if (!processLineItems(lineItems.glassParts)) {
|
||||||
(!!lineItem?.sellingPrice && lineItem.sellingPrice != 0);
|
return false;
|
||||||
return value;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineItems.supportingItems && Array.isArray(lineItems.supportingItems)) {
|
||||||
|
if (!processLineItems(lineItems.supportingItems)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineItems.vaps && Array.isArray(lineItems.vaps)) {
|
||||||
|
if (!processLineItems(lineItems.vaps)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { allGlassPartsAndItemsHavePrices } from './service-package-helper';
|
||||||
|
|
||||||
it('service package helper should return false when line item has missing price', () => {
|
it('service package helper should return false when line item has missing price', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockData = { glassParts: [{partNumber: 'DW01571GBNNOEE', sellingPrice: 25}], supportingItems: [{ laborAmount: 0 }] }
|
const mockData = { glassParts: [{ partNumber: 'DW01571GBNNOEE', sellingPrice: 25 }], supportingItems: [{ laborAmount: 0 }] };
|
||||||
// Act
|
// Act
|
||||||
const actual = allGlassPartsAndItemsHavePrices(mockData);
|
const actual = allGlassPartsAndItemsHavePrices(mockData);
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -11,7 +11,7 @@ it('service package helper should return false when line item has missing price'
|
||||||
|
|
||||||
it('service package helper should return true when line item has all prices', () => {
|
it('service package helper should return true when line item has all prices', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const mockData = { glassParts: [{partNumber: 'DW01571GBNNOEE', sellingPrice: 25}], laborAmount: [{ sellingPrice: 10 }] }
|
const mockData = { glassParts: [{ partNumber: 'DW01571GBNNOEE', sellingPrice: 25 }], laborAmount: [{ sellingPrice: 10 }] };
|
||||||
// Act
|
// Act
|
||||||
const actual = allGlassPartsAndItemsHavePrices(mockData);
|
const actual = allGlassPartsAndItemsHavePrices(mockData);
|
||||||
// Assert
|
// Assert
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<buttonQuestion ref="buttonQuestion"
|
<buttonQuestion
|
||||||
:answers="servicePackageAnswers"
|
ref="buttonQuestion"
|
||||||
:groupName="groupName"
|
v-model="selectedPackageName"
|
||||||
buttonTypeString="servicePackageRadio"
|
:answers="servicePackageAnswers"
|
||||||
:buttonTypeObject="servicePackageRadio"
|
:groupName="groupName"
|
||||||
v-model="selectedPackageName"
|
buttonTypeString="servicePackageRadio"
|
||||||
:validationRules="validationRules"
|
:buttonTypeObject="servicePackageRadio"
|
||||||
:isRequired="isRequired" />
|
:validationRules="validationRules"
|
||||||
|
:isRequired="isRequired" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -16,7 +17,7 @@ import { damageLocationsSelected as glassLocations } from '@/constants/damage-lo
|
||||||
import servicePackageRadio from '@/layouts/service-packages/service-package-question/service-package-radio/service-package-radio';
|
import servicePackageRadio from '@/layouts/service-packages/service-package-question/service-package-radio/service-package-radio';
|
||||||
import { partTypeStrings } from '@/constants/part-type-strings';
|
import { partTypeStrings } from '@/constants/part-type-strings';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { allGlassPartsAndItemsHavePrices } from '@/layouts/service-packages/service-package-helper/service-package-helper'
|
import { allGlassPartsAndItemsHavePrices } from '@/layouts/service-packages/service-package-helper/service-package-helper';
|
||||||
|
|
||||||
const packageNames = {
|
const packageNames = {
|
||||||
TIER_ONE: 'TierOne',
|
TIER_ONE: 'TierOne',
|
||||||
|
|
@ -27,8 +28,10 @@ const packageNames = {
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'servicePackageQuestion',
|
name: 'service-package-question',
|
||||||
emits: ['vapsItemsSelected'],
|
components: {
|
||||||
|
buttonQuestion
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
groupName: String,
|
groupName: String,
|
||||||
|
|
@ -36,23 +39,13 @@ export default {
|
||||||
isRequired: Boolean,
|
isRequired: Boolean,
|
||||||
availableLineItems: []
|
availableLineItems: []
|
||||||
},
|
},
|
||||||
|
emits: ['vapsItemsSelected'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
servicePackageRadio: servicePackageRadio,
|
servicePackageRadio,
|
||||||
selectedPackageName: packageNames.TIER_ONE
|
selectedPackageName: packageNames.TIER_ONE
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
availableLineItems() {
|
|
||||||
if (allGlassPartsAndItemsHavePrices(store.order.lineItems)) {
|
|
||||||
this.selectDefaultPackage();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectedPackageName(newValue) {
|
|
||||||
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
|
||||||
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
nullSafeAvailableLineItems() {
|
nullSafeAvailableLineItems() {
|
||||||
if (this.availableLineItems?.lineItems) {
|
if (this.availableLineItems?.lineItems) {
|
||||||
|
|
@ -64,27 +57,20 @@ export default {
|
||||||
servicePackageAnswers() {
|
servicePackageAnswers() {
|
||||||
if (!this.cmsWidgetName) return [];
|
if (!this.cmsWidgetName) return [];
|
||||||
const cmsAnswersContent = [];
|
const cmsAnswersContent = [];
|
||||||
cmsAnswersContent.push(
|
cmsAnswersContent.push({
|
||||||
{
|
Name: 'TierOne',
|
||||||
Name: 'TierOne',
|
cmsWidgetName: 'EconomyServicePackage'
|
||||||
cmsWidgetName: 'EconomyServicePackage'
|
});
|
||||||
}
|
if (this.shouldDisplayTierTwoPackage) {
|
||||||
);
|
cmsAnswersContent.push({
|
||||||
if (this.shouldDisplayTierTwoPackage)
|
Name: 'TierTwo',
|
||||||
{
|
cmsWidgetName: 'StandardServicePackage'
|
||||||
cmsAnswersContent.push(
|
});
|
||||||
{
|
|
||||||
Name: 'TierTwo',
|
|
||||||
cmsWidgetName: 'StandardServicePackage'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
cmsAnswersContent.push(
|
cmsAnswersContent.push({
|
||||||
{
|
Name: 'TierThree',
|
||||||
Name: 'TierThree',
|
cmsWidgetName: 'PremiumServicePackage'
|
||||||
cmsWidgetName: 'PremiumServicePackage'
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
// if cms content has not yet loaded, skip
|
// if cms content has not yet loaded, skip
|
||||||
if (this.getCmsContent(cmsAnswersContent[0].cmsWidgetName, 'HeaderText') == '') {
|
if (this.getCmsContent(cmsAnswersContent[0].cmsWidgetName, 'HeaderText') == '') {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -104,24 +90,20 @@ export default {
|
||||||
return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION);
|
return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION);
|
||||||
},
|
},
|
||||||
frontWipersApplicableForTierTwo() {
|
frontWipersApplicableForTierTwo() {
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
|
||||||
partTypeStrings.FRONT_WIPER
|
|
||||||
);
|
|
||||||
const glassToReplaceContainsWindshield = this.glassToReplaceContainsGlassLocation(glassLocations.WINDSHIELD);
|
const glassToReplaceContainsWindshield = this.glassToReplaceContainsGlassLocation(glassLocations.WINDSHIELD);
|
||||||
|
|
||||||
if(frontWipersAreAvailable && (useMainStore().order.damage.isRepair || glassToReplaceContainsWindshield))
|
if (frontWipersAreAvailable && (useMainStore().order.damage.isRepair || glassToReplaceContainsWindshield)) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
},
|
},
|
||||||
rearWiperApplicableForTierTwo() {
|
rearWiperApplicableForTierTwo() {
|
||||||
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
||||||
return (
|
return (
|
||||||
this.glassToReplaceContainsGlassLocation(glassLocations.REAR) &&
|
this.glassToReplaceContainsGlassLocation(glassLocations.REAR)
|
||||||
rearWiperIsAvailable
|
&& rearWiperIsAvailable
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
frontWipersApplicableForTierThree() {
|
frontWipersApplicableForTierThree() {
|
||||||
|
|
@ -129,29 +111,39 @@ export default {
|
||||||
return frontWipersAreAvailable;
|
return frontWipersAreAvailable;
|
||||||
},
|
},
|
||||||
rearWiperApplicableForTierThree() {
|
rearWiperApplicableForTierThree() {
|
||||||
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
|
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
|
||||||
return (
|
return (
|
||||||
rearWiperIsAvailable &&
|
rearWiperIsAvailable
|
||||||
(this.glassToReplaceContainsGlassLocation(glassLocations.REAR) ||
|
&& (this.glassToReplaceContainsGlassLocation(glassLocations.REAR)
|
||||||
!frontWipersAreAvailable)
|
|| !frontWipersAreAvailable)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
rainDefenseApplicableForTierThree() {
|
rainDefenseApplicableForTierThree() {
|
||||||
if (
|
if (
|
||||||
this.rearWiperApplicableForTierTwo &&
|
this.rearWiperApplicableForTierTwo
|
||||||
!this.frontWipersApplicableForTierTwo &&
|
&& !this.frontWipersApplicableForTierTwo
|
||||||
this.frontWipersApplicableForTierThree
|
&& this.frontWipersApplicableForTierThree
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
shouldDisplayTierTwoPackage() {
|
shouldDisplayTierTwoPackage() {
|
||||||
return this.frontWipersApplicableForTierTwo || this.rearWiperApplicableForTierTwo;
|
return this.frontWipersApplicableForTierTwo || this.rearWiperApplicableForTierTwo;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
availableLineItems() {
|
||||||
|
if (allGlassPartsAndItemsHavePrices(store.order.lineItems)) {
|
||||||
|
this.selectDefaultPackage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectedPackageName(newValue) {
|
||||||
|
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
||||||
|
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
processIfStatements,
|
processIfStatements,
|
||||||
getHeaderTextFromCms(cmsWidgetName) {
|
getHeaderTextFromCms(cmsWidgetName) {
|
||||||
|
|
@ -170,7 +162,7 @@ export default {
|
||||||
},
|
},
|
||||||
getPackagePriceString(packageName) {
|
getPackagePriceString(packageName) {
|
||||||
const formattedPriceFloat = parseFloat(this.getPackagePrice(packageName)).toFixed(2);
|
const formattedPriceFloat = parseFloat(this.getPackagePrice(packageName)).toFixed(2);
|
||||||
return '+$' + formattedPriceFloat + '*';
|
return `+$${formattedPriceFloat}*`;
|
||||||
},
|
},
|
||||||
getPackagePrice(packageName) {
|
getPackagePrice(packageName) {
|
||||||
let priceFloat = 0;
|
let priceFloat = 0;
|
||||||
|
|
@ -184,12 +176,12 @@ export default {
|
||||||
getTierTwoPackageVapsPrice() {
|
getTierTwoPackageVapsPrice() {
|
||||||
let vapsPrice = 0;
|
let vapsPrice = 0;
|
||||||
const priceFrontWipers = this.frontWipersApplicableForTierTwo;
|
const priceFrontWipers = this.frontWipersApplicableForTierTwo;
|
||||||
const priceRearWipers = this.rearWiperApplicableForTierTwo;
|
const priceRearWipers = this.rearWiperApplicableForTierTwo;
|
||||||
this.nullSafeAvailableLineItems.forEach((item) => {
|
this.nullSafeAvailableLineItems.forEach((item) => {
|
||||||
if (
|
if (
|
||||||
(priceFrontWipers &&
|
(priceFrontWipers
|
||||||
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
|
&& item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER)
|
||||||
(priceRearWipers && item.partType.toUpperCase() === partTypeStrings.REAR_WIPER)
|
|| (priceRearWipers && item.partType.toUpperCase() === partTypeStrings.REAR_WIPER)
|
||||||
) {
|
) {
|
||||||
vapsPrice += this.getTotalLineItemPrice(item);
|
vapsPrice += this.getTotalLineItemPrice(item);
|
||||||
}
|
}
|
||||||
|
|
@ -199,16 +191,16 @@ export default {
|
||||||
getTierThreePackageVapsPrice() {
|
getTierThreePackageVapsPrice() {
|
||||||
let vapsPrice = 0;
|
let vapsPrice = 0;
|
||||||
const priceFrontWipers = this.frontWipersApplicableForTierThree;
|
const priceFrontWipers = this.frontWipersApplicableForTierThree;
|
||||||
const priceRearWipers = this.rearWiperApplicableForTierThree;
|
const priceRearWipers = this.rearWiperApplicableForTierThree;
|
||||||
const priceRainDefense = this.rainDefenseApplicableForTierThree;
|
const priceRainDefense = this.rainDefenseApplicableForTierThree;
|
||||||
this.nullSafeAvailableLineItems.forEach((item) => {
|
this.nullSafeAvailableLineItems.forEach((item) => {
|
||||||
if (
|
if (
|
||||||
(priceFrontWipers &&
|
(priceFrontWipers
|
||||||
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
|
&& item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER)
|
||||||
(priceRearWipers &&
|
|| (priceRearWipers
|
||||||
item.partType.toUpperCase() === partTypeStrings.REAR_WIPER) ||
|
&& item.partType.toUpperCase() === partTypeStrings.REAR_WIPER)
|
||||||
(priceRainDefense &&
|
|| (priceRainDefense
|
||||||
item.partType.toUpperCase() === partTypeStrings.RAIN_DEFENSE)
|
&& item.partType.toUpperCase() === partTypeStrings.RAIN_DEFENSE)
|
||||||
) {
|
) {
|
||||||
vapsPrice += this.getTotalLineItemPrice(item);
|
vapsPrice += this.getTotalLineItemPrice(item);
|
||||||
}
|
}
|
||||||
|
|
@ -220,16 +212,15 @@ export default {
|
||||||
let lowestTierForPackage = packageNames.TIER_ONE;
|
let lowestTierForPackage = packageNames.TIER_ONE;
|
||||||
if (vapsFromStore?.length > 0) {
|
if (vapsFromStore?.length > 0) {
|
||||||
vapsFromStore.every((vapsItem) => {
|
vapsFromStore.every((vapsItem) => {
|
||||||
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
const lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
||||||
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
||||||
lowestTierForPackage = packageNames.TIER_THREE;
|
lowestTierForPackage = packageNames.TIER_THREE;
|
||||||
return false;
|
return false;
|
||||||
} else if (lowestTierForThisItem === packageNames.TIER_TWO) {
|
} if (lowestTierForThisItem === packageNames.TIER_TWO) {
|
||||||
lowestTierForPackage = packageNames.TIER_TWO;
|
lowestTierForPackage = packageNames.TIER_TWO;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.selectedPackageName = lowestTierForPackage;
|
this.selectedPackageName = lowestTierForPackage;
|
||||||
|
|
@ -259,6 +250,7 @@ export default {
|
||||||
lowestTierForThisItem = packageNames.TIER_THREE;
|
lowestTierForThisItem = packageNames.TIER_THREE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
return lowestTierForThisItem;
|
return lowestTierForThisItem;
|
||||||
},
|
},
|
||||||
|
|
@ -266,30 +258,20 @@ export default {
|
||||||
const vapsLineItemsForSelectedPackage = [];
|
const vapsLineItemsForSelectedPackage = [];
|
||||||
if (packageName === packageNames.TIER_TWO) {
|
if (packageName === packageNames.TIER_TWO) {
|
||||||
if (this.frontWipersApplicableForTierTwo) {
|
if (this.frontWipersApplicableForTierTwo) {
|
||||||
vapsLineItemsForSelectedPackage.push(
|
vapsLineItemsForSelectedPackage.push(...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER));
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (this.rearWiperApplicableForTierTwo) {
|
if (this.rearWiperApplicableForTierTwo) {
|
||||||
vapsLineItemsForSelectedPackage.push(
|
vapsLineItemsForSelectedPackage.push(...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER));
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (packageName === packageNames.TIER_THREE) {
|
} else if (packageName === packageNames.TIER_THREE) {
|
||||||
if (this.frontWipersApplicableForTierThree) {
|
if (this.frontWipersApplicableForTierThree) {
|
||||||
vapsLineItemsForSelectedPackage.push(
|
vapsLineItemsForSelectedPackage.push(...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER));
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (this.rearWiperApplicableForTierThree) {
|
if (this.rearWiperApplicableForTierThree) {
|
||||||
vapsLineItemsForSelectedPackage.push(
|
vapsLineItemsForSelectedPackage.push(...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER));
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (this.rainDefenseApplicableForTierThree) {
|
if (this.rainDefenseApplicableForTierThree) {
|
||||||
vapsLineItemsForSelectedPackage.push(
|
vapsLineItemsForSelectedPackage.push(...this.getLineItemsContainingPartType(partTypeStrings.RAIN_DEFENSE));
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.RAIN_DEFENSE)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vapsLineItemsForSelectedPackage;
|
return vapsLineItemsForSelectedPackage;
|
||||||
|
|
@ -313,9 +295,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLineItemsContainingPartType(partType) {
|
getLineItemsContainingPartType(partType) {
|
||||||
const partTypeMatches = this.nullSafeAvailableLineItems.filter(
|
const partTypeMatches = this.nullSafeAvailableLineItems.filter((lineItem) => lineItem.partType.toUpperCase() === partType);
|
||||||
(lineItem) => lineItem.partType.toUpperCase() === partType
|
|
||||||
);
|
|
||||||
return partTypeMatches;
|
return partTypeMatches;
|
||||||
},
|
},
|
||||||
lineItemsContainsPartType(partType) {
|
lineItemsContainsPartType(partType) {
|
||||||
|
|
@ -324,18 +304,13 @@ export default {
|
||||||
},
|
},
|
||||||
glassToReplaceContainsGlassLocation(glassLocation) {
|
glassToReplaceContainsGlassLocation(glassLocation) {
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
const glassLocationMatches =
|
const glassLocationMatches
|
||||||
store.order.damage.glassToReplace?.filter(
|
= store.order.damage.glassToReplace?.filter((glassToReplace) => glassToReplace.glassLocation === glassLocation) ?? [];
|
||||||
(glassToReplace) => glassToReplace.glassLocation === glassLocation
|
|
||||||
) ?? [];
|
|
||||||
return !!glassLocationMatches.length;
|
return !!glassLocationMatches.length;
|
||||||
},
|
},
|
||||||
getTotalLineItemPrice(lineItem) {
|
getTotalLineItemPrice(lineItem) {
|
||||||
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
|
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,113 +1,6 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import servicePackageRadio from './service-package-radio';
|
|
||||||
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
||||||
|
import servicePackageRadio from './service-package-radio';
|
||||||
describe('service-package-radio.vue', () => {
|
|
||||||
it('Should include buttonLabel in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabel']));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should include buttonLabelAuxillaryCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabelAuxillaryCopy']));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should include buttonLabelSubCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonLabelSubCopy']));
|
|
||||||
});
|
|
||||||
it('Should include buttonFooterCopy in html', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const outputHtml = wrapper.html();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(outputHtml).toEqual(expect.stringContaining(mockProps['buttonFooterCopy']));
|
|
||||||
});
|
|
||||||
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when provided with a dashed (x5) buttonBodyCopy', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(results.length).toBe(5);
|
|
||||||
});
|
|
||||||
it('Should get strings from getArrayOfListItemsFromRawCmsCopy without dashes when provided with a dashed buttonBodyCopy', async () => {
|
|
||||||
// Arrange
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: mockProps,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const fileredResults = results.filter((result) => {
|
|
||||||
return result.includes(' -');
|
|
||||||
});
|
|
||||||
expect(fileredResults.length).toBe(0);
|
|
||||||
});
|
|
||||||
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ', async () => {
|
|
||||||
// Arrange
|
|
||||||
const moddedProps = mockProps;
|
|
||||||
moddedProps['buttonBodyCopy'] = '- buttonBodyCopy test copy - 2 - 3 - 4 - 5 -';
|
|
||||||
let { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
propsData: moddedProps
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(results.length).toBe(5);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
buttonLabel: 'buttonLabel test copy',
|
buttonLabel: 'buttonLabel test copy',
|
||||||
|
|
@ -125,3 +18,109 @@ function setupMocks({ mountOptionsMockData = {} }) {
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('service-package-radio.vue', () => {
|
||||||
|
it('Should include buttonLabel in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabel));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should include buttonLabelAuxillaryCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabelAuxillaryCopy));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should include buttonLabelSubCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonLabelSubCopy));
|
||||||
|
});
|
||||||
|
it('Should include buttonFooterCopy in html', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const outputHtml = wrapper.html();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(outputHtml).toEqual(expect.stringContaining(mockProps.buttonFooterCopy));
|
||||||
|
});
|
||||||
|
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when provided with a dashed (x5) buttonBodyCopy', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(results.length).toBe(5);
|
||||||
|
});
|
||||||
|
it('Should get strings from getArrayOfListItemsFromRawCmsCopy without dashes when provided with a dashed buttonBodyCopy', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: mockProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const fileredResults = results.filter((result) => result.includes(' -'));
|
||||||
|
expect(fileredResults.length).toBe(0);
|
||||||
|
});
|
||||||
|
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
|
||||||
|
async () => {
|
||||||
|
// Arrange
|
||||||
|
const moddedProps = mockProps;
|
||||||
|
moddedProps.buttonBodyCopy = '- buttonBodyCopy test copy - 2 - 3 - 4 - 5 -';
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: moddedProps
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(results.length).toBe(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,58 @@
|
||||||
<template>
|
<template>
|
||||||
<baseInputButton v-bind="$props" v-model="selectedValue">
|
<baseInputButton
|
||||||
<div class="package-label mb-4"
|
v-bind="$props"
|
||||||
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
|
v-model="selectedValue">
|
||||||
for="testradio">
|
<div
|
||||||
|
class="package-label mb-4"
|
||||||
|
:class="[buttonLabelSubCopy ? 'has-subheader' : '']"
|
||||||
|
for="testradio">
|
||||||
<div class="package-specs">
|
<div class="package-specs">
|
||||||
<p class="m-0">
|
<p class="m-0">
|
||||||
<span v-html="this.buttonLabel"></span>
|
<span v-html="buttonLabel"></span>
|
||||||
<span class="pricing-info" v-html="this.buttonAuxiliaryCopy"></span>
|
<span
|
||||||
|
class="pricing-info"
|
||||||
|
v-html="buttonAuxiliaryCopy"></span>
|
||||||
</p>
|
</p>
|
||||||
<p class="sub-label m-0"
|
<p
|
||||||
v-if="this.buttonLabelSubCopy"
|
v-if="buttonLabelSubCopy"
|
||||||
v-html="this.buttonLabelSubCopy"></p>
|
class="sub-label m-0"
|
||||||
|
v-html="buttonLabelSubCopy"></p>
|
||||||
<div>
|
<div>
|
||||||
<ul >
|
<ul>
|
||||||
<li v-for="listItem in this.arrayOfListItemsFromBodyText" :key="listItem" class="mb-0">
|
<li
|
||||||
|
v-for="listItem in arrayOfListItemsFromBodyText"
|
||||||
|
:key="listItem"
|
||||||
|
class="mb-0">
|
||||||
<!-- no textLink -->
|
<!-- no textLink -->
|
||||||
<span v-if="!doesCopyContainTextLink(listItem)"
|
<span
|
||||||
v-html="listItem"></span>
|
v-if="!doesCopyContainTextLink(listItem)"
|
||||||
|
v-html="listItem"></span>
|
||||||
<!-- with textLink -->
|
<!-- with textLink -->
|
||||||
<template v-else
|
<template
|
||||||
v-for="copy in splitCopyOnCMSPlaceHolder(listItem)"
|
v-for="copy in splitCopyOnCMSPlaceHolder(listItem)"
|
||||||
:key="copy">
|
v-else
|
||||||
<span v-if="!doesCopyContainTextLink(copy)" v-html="copy"></span>
|
:key="copy">
|
||||||
|
<span
|
||||||
|
v-if="!doesCopyContainTextLink(copy)"
|
||||||
|
v-html="copy"></span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<textLink linkType="text"
|
<textLink
|
||||||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
linkType="text"
|
||||||
href="#!"
|
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||||
@click-event="textLinkEmit(copy)"
|
href="#!"
|
||||||
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
||||||
aria-label="Modal window" />
|
aria-label="Modal window"
|
||||||
|
@click-event="textLinkEmit(copy)" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- End of body text parsing -->
|
<!-- End of body text parsing -->
|
||||||
<!--ms-n6-->
|
<!--ms-n6-->
|
||||||
<div class="package-footer fw-bold caption mt-4 ml-n4 mr-3"
|
<div
|
||||||
v-if="this.buttonFooterCopy"
|
v-if="buttonFooterCopy"
|
||||||
v-html="this.buttonFooterCopy"></div>
|
class="package-footer fw-bold caption mt-4 ml-n4 mr-3"
|
||||||
|
v-html="buttonFooterCopy"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -45,8 +60,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import baseInputButton from '@/digital-components/base-input-button/base-input-button';
|
import baseInputButton from '@/digital-components/base-input-button/base-input-button';
|
||||||
import textLink from '@/ux-components/text-link/text-link';
|
import textLink from '@/ux-components/text-link/text-link';
|
||||||
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
|
||||||
import {
|
import {
|
||||||
getRouterLinkDisplayTextFromCopy,
|
getRouterLinkDisplayTextFromCopy,
|
||||||
|
|
@ -54,14 +69,15 @@ import {
|
||||||
splitCopyOnCMSPlaceHolder,
|
splitCopyOnCMSPlaceHolder,
|
||||||
doesCopyContainTextLink
|
doesCopyContainTextLink
|
||||||
} from '@/helpers/cms-content-helper';
|
} from '@/helpers/cms-content-helper';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'servicePackageRadio',
|
name: 'service-package-radio',
|
||||||
emits:['link-event'],
|
|
||||||
mixins: [inputButtonWrapperMixin],
|
|
||||||
components: {
|
components: {
|
||||||
baseInputButton,
|
baseInputButton,
|
||||||
textLink
|
textLink
|
||||||
},
|
},
|
||||||
|
mixins: [inputButtonWrapperMixin],
|
||||||
|
emits: ['link-event'],
|
||||||
computed: {
|
computed: {
|
||||||
arrayOfListItemsFromBodyText() {
|
arrayOfListItemsFromBodyText() {
|
||||||
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
|
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
|
||||||
|
|
@ -81,6 +97,7 @@ export default {
|
||||||
.split('- ') // At some point we'll want a better delimiter
|
.split('- ') // At some point we'll want a better delimiter
|
||||||
.filter((lineItem) => lineItem);
|
.filter((lineItem) => lineItem);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
textLinkEmit(copy) {
|
textLinkEmit(copy) {
|
||||||
this.$parent.$emit('link-event', {
|
this.$parent.$emit('link-event', {
|
||||||
|
|
@ -263,4 +280,4 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,91 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition sub-container make-tall">
|
<div class="fade-on-route-transition sub-container make-tall">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget"
|
<siteSubHeader
|
||||||
justification="left"
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
issContainingPage="service-packages"
|
justification="left"
|
||||||
/>
|
issContainingPage="service-packages" />
|
||||||
<div class="mx-5">
|
<div class="mx-5">
|
||||||
<servicePackageQuestion ref="servicePackage"
|
<servicePackageQuestion
|
||||||
cmsWidgetName="ServicePackage"
|
ref="servicePackage"
|
||||||
groupName="ServicePackageQuestion"
|
cmsWidgetName="ServicePackage"
|
||||||
:availableLineItems="availableLineItems"
|
groupName="ServicePackageQuestion"
|
||||||
@vapsItemsSelected="vapsItemsSelectedAction"
|
:availableLineItems="availableLineItems"
|
||||||
v-on:link-event="openModalAction"
|
:validationRules="rules.optionRequired"
|
||||||
:validationRules="rules.optionRequired"
|
isRequired
|
||||||
isRequired
|
@vapsItemsSelected="vapsItemsSelectedAction"
|
||||||
/>
|
@link-event="openModalAction" />
|
||||||
<p class="caption disclaimer" v-html="PriceDisclaimerText"></p>
|
<p
|
||||||
<siteFooter cmsWidgetName="SiteFooterWidget"
|
class="caption disclaimer"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
v-html="PriceDisclaimerText"></p>
|
||||||
@back-clicked="backButtonAction"
|
<siteFooter
|
||||||
@ForwardClicked="forwardButtonAction" />
|
cmsWidgetName="SiteFooterWidget"
|
||||||
|
:isForwardActionDisabled="!meta.valid"
|
||||||
|
@back-clicked="backButtonAction"
|
||||||
|
@ForwardClicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<loadingModal ref="loadingModal" />
|
<loadingModal ref="loadingModal" />
|
||||||
<contentGroupModal ref="RainDefenseModal" cmsWidgetName="RainDefenseModal" />
|
<contentGroupModal
|
||||||
<contentGroupModal ref="FrontWiperModal" cmsWidgetName="FrontWiperModal" />
|
ref="RainDefenseModal"
|
||||||
<contentGroupModal ref="RearWiperModal" cmsWidgetName="RearWiperModal" />
|
cmsWidgetName="RainDefenseModal" />
|
||||||
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
|
<contentGroupModal
|
||||||
|
ref="FrontWiperModal"
|
||||||
|
cmsWidgetName="FrontWiperModal" />
|
||||||
|
<contentGroupModal
|
||||||
|
ref="RearWiperModal"
|
||||||
|
cmsWidgetName="RearWiperModal" />
|
||||||
|
<contentGroupModal
|
||||||
|
ref="RecalModal"
|
||||||
|
cmsWidgetName="RecalModal" />
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
import servicePackageQuestion from './service-package-question/service-package-question';
|
import textBlock from '@/digital-components/text-block/text-block';
|
||||||
import textBlock from '@/digital-components/text-block/text-block';
|
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal';
|
||||||
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal';
|
import loadingModal from '@/iss-components/loading-modal/loading-modal';
|
||||||
import loadingModal from '@/iss-components/loading-modal/loading-modal.vue';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { useMainStore } from '@/store';
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { required } from '@/helpers/validation-rules';
|
import { Form } from 'vee-validate';
|
||||||
import { errorMessages } from '@/constants/error-messages';
|
import { allGlassPartsAndItemsHavePrices } from '@/layouts/service-packages/service-package-helper/service-package-helper';
|
||||||
import { Form, defineRule } from 'vee-validate';
|
|
||||||
import { allGlassPartsAndItemsHavePrices } from '@/layouts/service-packages/service-package-helper/service-package-helper'
|
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
|
import servicePackageQuestion from './service-package-question/service-package-question';
|
||||||
|
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'service-packages',
|
name: 'service-packages',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
siteSubHeader,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form,
|
||||||
|
servicePackageQuestion,
|
||||||
|
loadingModal,
|
||||||
|
contentGroupModal
|
||||||
|
},
|
||||||
mixins: [baseFormMixin],
|
mixins: [baseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
||||||
const wipersPromise = await store.getWipers();
|
const wipersPromise = await store.getWipers();
|
||||||
const rainDefensePromise = await store.getRainDefense();
|
const rainDefensePromise = await store.getRainDefense();
|
||||||
const supportingItemsPromise = await store.getSupportingItems();
|
const supportingItemsPromise = await store.getSupportingItems();
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
|
|
@ -101,17 +122,17 @@ export default {
|
||||||
// Call the "next" function to complete the transition to this page.
|
// Call the "next" function to complete the transition to this page.
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.pricedGlassParts = clonedGlassParts;
|
vm.pricedGlassParts = clonedGlassParts;
|
||||||
vm.supportingItems = resultMap.supportingItems;
|
vm.supportingItems = resultMap.supportingItems;
|
||||||
vm.availableLineItems = pricingResults;
|
vm.availableLineItems = pricingResults;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedVaps: [],
|
selectedVaps: [],
|
||||||
availableLineItems: [],
|
availableLineItems: [],
|
||||||
supportingItems: [],
|
supportingItems: [],
|
||||||
pricedGlassParts: [],
|
pricedGlassParts: [],
|
||||||
rules: {
|
rules: {
|
||||||
optionRequired: globalRules.OPTION_REQUIRED
|
optionRequired: globalRules.OPTION_REQUIRED
|
||||||
}
|
}
|
||||||
|
|
@ -128,12 +149,12 @@ export default {
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return (
|
return (
|
||||||
store.order.serviceLocation.zipCode &&
|
store.order.serviceLocation.zipCode
|
||||||
store.order.serviceLocation.zipCodeCtu &&
|
&& store.order.serviceLocation.zipCodeCtu
|
||||||
(store.order.damage.isRepair ||
|
&& (store.order.damage.isRepair
|
||||||
(store.order.lineItems?.glassParts != null &&
|
|| (store.order.lineItems?.glassParts != null
|
||||||
store.order.lineItems.glassParts.length > 0)) &&
|
&& store.order.lineItems.glassParts.length > 0))
|
||||||
store.order.referralNumber?.length !== 6
|
&& store.order.referralNumber?.length !== 6
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||||
|
|
@ -155,21 +176,11 @@ export default {
|
||||||
|
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
siteSubHeader,
|
|
||||||
Form, /* eslint-disable-line */
|
|
||||||
textBlock,
|
|
||||||
servicePackageQuestion,
|
|
||||||
loadingModal,
|
|
||||||
contentGroupModal
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.subheader-secondary {
|
.subheader-secondary {
|
||||||
margin-top: .5rem;
|
margin-top: .5rem;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue