Merge branch 'develop' into feature/digital/SSR-621

This commit is contained in:
katie 2023-09-11 10:41:09 -04:00
commit d13e51a702
125 changed files with 2810 additions and 1548 deletions

View file

@ -18,8 +18,8 @@ module.exports = {
'vue/attribute-hyphenation': ['warn', 'never'], 'vue/attribute-hyphenation': ['warn', 'never'],
'vue/v-on-event-hyphenation': ['warn', 'never'], 'vue/v-on-event-hyphenation': ['warn', 'never'],
'object-curly-newline': ['error', { consistent: true }], 'object-curly-newline': ['error', { consistent: true }],
'function-paren-newline': ['error', 'never'], 'function-paren-newline': ['error', 'multiline'],
'operator-linebreak': ['error', 'before', { overrides: { '=': 'after' }}], 'operator-linebreak': ['error', 'before', { overrides: { '=': 'after' } }],
'implicit-arrow-linebreak': ['off'], 'implicit-arrow-linebreak': ['off'],
'comma-dangle': ['error', 'never'], 'comma-dangle': ['error', 'never'],
indent: ['error', 4, { SwitchCase: 1 }], indent: ['error', 4, { SwitchCase: 1 }],
@ -33,6 +33,7 @@ module.exports = {
'jsdoc/check-tag-names': ['error', { 'jsdoc/check-tag-names': ['error', {
definedTags: ['store', 'endpoint', 'category', 'subcategory', 'remarks'] definedTags: ['store', 'endpoint', 'category', 'subcategory', 'remarks']
}], }],
'jsdoc/require-jsdoc': 0,
'vue/html-self-closing': ['error', { 'vue/html-self-closing': ['error', {
html: { html: {
void: 'any', void: 'any',

View file

@ -1,7 +1,7 @@
const coverageStatuses = Object.freeze({ const coverageStatuses = Object.freeze({
PENDING: 'Pending', PENDING: 0,
NO_COMP: 'No Comp', NO_COMP: 1,
VERIFIED: 'Verified' VERIFIED: 2
}); });
export default coverageStatuses; export default coverageStatuses;

View file

@ -129,6 +129,10 @@ const endpoints = Object.freeze({
RegisterClaim: { RegisterClaim: {
url: '/coverage/api/v1/coverage/register-claim', url: '/coverage/api/v1/coverage/register-claim',
method: 'POST' method: 'POST'
},
SaveSession: {
url: '/order/api/v1/order/save-session/iss',
method: 'POST'
} }
}); });

View file

@ -27,6 +27,7 @@ const errorMessages = Object.freeze({
SERVICE_ZIP_FORMAT: 'Please enter a valid service ZIP', SERVICE_ZIP_FORMAT: 'Please enter a valid service ZIP',
VIN_REQUIRED: 'Please enter your VIN', VIN_REQUIRED: 'Please enter your VIN',
VIN_FORMAT: VIN_FORMAT:
// eslint-disable-next-line max-len
'Invalid VIN. Please make sure that you entered the correct 17-digit, alpha-numeric number. VINs do not contain the letters I, O, or Q', 'Invalid VIN. Please make sure that you entered the correct 17-digit, alpha-numeric number. VINs do not contain the letters I, O, or Q',
OPTION_REQUIRED: 'Please select an option', OPTION_REQUIRED: 'Please select an option',
VEHICLE_REQUIRED: 'Please select a vehicle', VEHICLE_REQUIRED: 'Please select a vehicle',

View file

@ -50,9 +50,11 @@ export default {
}; };
const { handleChange, meta, errors } = const { handleChange, meta, errors } =
useField(toRef(props, 'groupName'), useField(
toRef(props, 'groupName'),
toRef(props, 'validationRules'), toRef(props, 'validationRules'),
fieldOptions); fieldOptions
);
return { return {
handleChange, handleChange,
@ -72,7 +74,8 @@ export default {
return this.modelValue.includes(this.value); return this.modelValue.includes(this.value);
} }
if (!this.isMultiSelect) { if (!this.isMultiSelect) {
return this.modelValue === this.value; // eslint-disable-next-line eqeqeq
return this.modelValue == this.value;
} }
return false; return false;
}, },

View file

@ -62,8 +62,10 @@ describe('buttonQuestion.vue', () => {
describe('selectedValues', () => { describe('selectedValues', () => {
test('is radio => should emit captured value', async () => { test('is radio => should emit captured value', async () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
setupMocks({ propsData: { groupName: 'group-name' } })); buttonQuestion,
setupMocks({ propsData: { groupName: 'group-name' } })
);
await wrapper.setProps({ await wrapper.setProps({
answers: ['2022', '2021', '2020'], answers: ['2022', '2021', '2020'],
isMultiSelect: false, isMultiSelect: false,
@ -78,8 +80,10 @@ describe('buttonQuestion.vue', () => {
}); });
test('is checkbox => should emit captured value', async () => { test('is checkbox => should emit captured value', async () => {
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
setupMocks({ propsData: { groupName: 'group-name' } })); buttonQuestion,
setupMocks({ propsData: { groupName: 'group-name' } })
);
await wrapper.setProps({ await wrapper.setProps({
answers: ['2022', '2021', '2020'], answers: ['2022', '2021', '2020'],
isMultiSelect: false, isMultiSelect: false,
@ -104,7 +108,8 @@ describe('buttonQuestion.vue', () => {
describe('buttonLabel', () => { describe('buttonLabel', () => {
test('answers have buttonLabel properties => buttonsInfo buttonsLabel properties are correct', () => { test('answers have buttonLabel properties => buttonsInfo buttonsLabel properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -116,7 +121,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -128,7 +134,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Text properties, no buttonLabel properties => buttonsInfo buttonsLabel properties are correct', () => { test('answers have Text properties, no buttonLabel properties => buttonsInfo buttonsLabel properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -140,7 +147,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -152,7 +160,8 @@ describe('buttonQuestion.vue', () => {
test('answers have buttonLabel and Text properties => buttonsInfo buttonsLabel properties are correct', () => { test('answers have buttonLabel and Text properties => buttonsInfo buttonsLabel properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -166,7 +175,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -178,12 +188,14 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => buttonLabel is answer values', () => { test('answers is an array of strings => buttonLabel is answer values', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -197,7 +209,8 @@ describe('buttonQuestion.vue', () => {
describe('altText', () => { describe('altText', () => {
test('answers have altText properties => buttonsInfo altText properties are correct', () => { test('answers have altText properties => buttonsInfo altText properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -209,7 +222,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -221,7 +235,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Name properties, no buttonLabel properties => buttonsInfo altText properties are correct', () => { test('answers have Name properties, no buttonLabel properties => buttonsInfo altText properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -233,7 +248,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -245,7 +261,8 @@ describe('buttonQuestion.vue', () => {
test('answers have altText and Name properties => buttonsInfo altText properties are correct', () => { test('answers have altText and Name properties => buttonsInfo altText properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -259,7 +276,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -271,12 +289,14 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => altText is answer values', () => { test('answers is an array of strings => altText is answer values', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -290,7 +310,8 @@ describe('buttonQuestion.vue', () => {
describe('buttonLabelSubCopy', () => { describe('buttonLabelSubCopy', () => {
test('answers have buttonLabelSubCopy properties => buttonsInfo buttonLabelSubCopy properties are correct', () => { test('answers have buttonLabelSubCopy properties => buttonsInfo buttonLabelSubCopy properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -302,7 +323,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -314,7 +336,8 @@ describe('buttonQuestion.vue', () => {
test('answers have SubText properties, no buttonLabelSubCopy properties => buttonsInfo buttonLabelSubCopy properties are correct', () => { test('answers have SubText properties, no buttonLabelSubCopy properties => buttonsInfo buttonLabelSubCopy properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -326,7 +349,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -338,7 +362,8 @@ describe('buttonQuestion.vue', () => {
test('answers have buttonLabelSubCopy and SubText properties => buttonsInfo buttonLabelSubCopy properties are correct', () => { test('answers have buttonLabelSubCopy and SubText properties => buttonsInfo buttonLabelSubCopy properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -352,7 +377,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -364,12 +390,14 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => there are no buttonLabelSubCopy properties', () => { test('answers is an array of strings => there are no buttonLabelSubCopy properties', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -383,7 +411,8 @@ describe('buttonQuestion.vue', () => {
describe('buttonImage', () => { describe('buttonImage', () => {
test('answers have buttonImage properties => buttonsInfo buttonImage properties are correct', () => { test('answers have buttonImage properties => buttonsInfo buttonImage properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -395,7 +424,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -407,7 +437,8 @@ describe('buttonQuestion.vue', () => {
test('answers have AnswerImageUrl properties, no buttonImage properties => buttonsInfo buttonImage properties are correct', () => { test('answers have AnswerImageUrl properties, no buttonImage properties => buttonsInfo buttonImage properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -419,7 +450,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -431,7 +463,8 @@ describe('buttonQuestion.vue', () => {
test('answers have buttonImage and AnswerImageUrl properties => buttonsInfo buttonImage properties are correct', () => { test('answers have buttonImage and AnswerImageUrl properties => buttonsInfo buttonImage properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -445,7 +478,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -457,12 +491,14 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => there are no buttonImage properties', () => { test('answers is an array of strings => there are no buttonImage properties', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -476,7 +512,8 @@ describe('buttonQuestion.vue', () => {
describe('buttonImageId', () => { describe('buttonImageId', () => {
test('answers have buttonImageId properties => buttonsInfo buttonImageId properties are correct', () => { test('answers have buttonImageId properties => buttonsInfo buttonImageId properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -488,7 +525,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -500,7 +538,8 @@ describe('buttonQuestion.vue', () => {
test('answers have ImageId properties, no buttonImageId properties => buttonsInfo buttonImage properties are correct', () => { test('answers have ImageId properties, no buttonImageId properties => buttonsInfo buttonImage properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -512,7 +551,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -524,7 +564,8 @@ describe('buttonQuestion.vue', () => {
test('answers have buttonImageId and ImageId properties => buttonsInfo buttonImageId properties are correct', () => { test('answers have buttonImageId and ImageId properties => buttonsInfo buttonImageId properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: [ answers: [
@ -538,7 +579,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -550,12 +592,14 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => there are no buttonImageId properties', () => { test('answers is an array of strings => there are no buttonImageId properties', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -568,16 +612,19 @@ describe('buttonQuestion.vue', () => {
describe('groupName', () => { describe('groupName', () => {
const answers = [[['answer 1', 'answer 2']], [[{ value: 1 }, { value: 2 }]]]; const answers = [[['answer 1', 'answer 2']], [[{ value: 1 }, { value: 2 }]]];
test.each(answers)('answers have groupName properties with spaces => buttonsInfo groupName properties are correct', test.each(answers)(
'answers have groupName properties with spaces => buttonsInfo groupName properties are correct',
(answerGroup) => { (answerGroup) => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: answerGroup, answers: answerGroup,
groupName: 'this is my group name' groupName: 'this is my group name'
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -585,18 +632,22 @@ describe('buttonQuestion.vue', () => {
// Assert // Assert
expect(buttonsInfo[0].groupName).toEqual('this-is-my-group-name'); expect(buttonsInfo[0].groupName).toEqual('this-is-my-group-name');
expect(buttonsInfo[1].groupName).toEqual('this-is-my-group-name'); expect(buttonsInfo[1].groupName).toEqual('this-is-my-group-name');
}); }
);
test.each(answers)('answers have groupName properties with no spaces => buttonsInfo groupName properties are correct', test.each(answers)(
'answers have groupName properties with no spaces => buttonsInfo groupName properties are correct',
(answerGroup) => { (answerGroup) => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
answers: answerGroup, answers: answerGroup,
groupName: 'this-is-my-group-name' groupName: 'this-is-my-group-name'
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -604,14 +655,16 @@ describe('buttonQuestion.vue', () => {
// Assert // Assert
expect(buttonsInfo[0].groupName).toEqual('this-is-my-group-name'); expect(buttonsInfo[0].groupName).toEqual('this-is-my-group-name');
expect(buttonsInfo[1].groupName).toEqual('this-is-my-group-name'); expect(buttonsInfo[1].groupName).toEqual('this-is-my-group-name');
}); }
);
}); });
describe('value', () => { describe('value', () => {
describe('useTextForValue is true', () => { describe('useTextForValue is true', () => {
test('answers have value properties => buttonsInfo value properties are correct', () => { test('answers have value properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -624,7 +677,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -636,7 +690,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Text properties => buttonsInfo value properties are correct', () => { test('answers have Text properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -649,7 +704,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -661,7 +717,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Name properties => buttonsInfo value properties are correct', () => { test('answers have Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -674,7 +731,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -686,7 +744,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value and Text properties, no Name properties => buttonsInfo value properties are correct', () => { test('answers have value and Text properties, no Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -701,7 +760,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -713,7 +773,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value and Name properties, no Text properties => buttonsInfo value properties are correct', () => { test('answers have value and Name properties, no Text properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -728,7 +789,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -740,7 +802,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Text and Name properties, no value properties => buttonsInfo value properties are correct', () => { test('answers have Text and Name properties, no value properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -755,7 +818,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -767,7 +831,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value, Text, and Name properties => buttonsInfo value properties are correct', () => { test('answers have value, Text, and Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
@ -784,7 +849,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -796,13 +862,15 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => buttonInfo value property values are values from array', () => { test('answers is an array of strings => buttonInfo value property values are values from array', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: true, useTextForValue: true,
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -816,7 +884,8 @@ describe('buttonQuestion.vue', () => {
describe('useTextForValue is false', () => { describe('useTextForValue is false', () => {
test('answers have value properties => buttonsInfo value properties are correct', () => { test('answers have value properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -829,7 +898,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -841,7 +911,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Text properties => buttonsInfo value properties are correct', () => { test('answers have Text properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -854,7 +925,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -866,7 +938,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Name properties => buttonsInfo value properties are correct', () => { test('answers have Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -879,7 +952,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -891,7 +965,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value and Text properties, no Name properties => buttonsInfo value properties are correct', () => { test('answers have value and Text properties, no Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -906,7 +981,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -918,7 +994,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value and Name properties, no Text properties => buttonsInfo value properties are correct', () => { test('answers have value and Name properties, no Text properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -933,7 +1010,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -945,7 +1023,8 @@ describe('buttonQuestion.vue', () => {
test('answers have Text and Name properties, no value properties => buttonsInfo value properties are correct', () => { test('answers have Text and Name properties, no value properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -960,7 +1039,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -972,7 +1052,8 @@ describe('buttonQuestion.vue', () => {
test('answers have value, Text, and Name properties => buttonsInfo value properties are correct', () => { test('answers have value, Text, and Name properties => buttonsInfo value properties are correct', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
@ -989,7 +1070,8 @@ describe('buttonQuestion.vue', () => {
} }
] ]
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;
@ -1001,13 +1083,15 @@ describe('buttonQuestion.vue', () => {
test('answers is an array of strings => buttonInfo value property values are values from array', () => { test('answers is an array of strings => buttonInfo value property values are values from array', () => {
// Arrange // Arrange
const wrapper = shallowMount(buttonQuestion, const wrapper = shallowMount(
buttonQuestion,
setupMocks({ setupMocks({
propsData: { propsData: {
useTextForValue: false, useTextForValue: false,
answers: ['answer 1', 'answer 2'] answers: ['answer 1', 'answer 2']
} }
})); })
);
// Act // Act
const { buttonsInfo } = wrapper.vm; const { buttonsInfo } = wrapper.vm;

View file

@ -79,14 +79,19 @@ export default {
initialValue initialValue
}; };
const { errorMessage, handleBlur, handleChange, meta, errors } = useField(props.inputId, props.validationRules, fieldOptions); const { errorMessage,
handleBlur,
handleChange,
meta, errors,
setErrors } = useField(props.inputId, props.validationRules, fieldOptions);
return { return {
errorMessage, errorMessage,
handleBlur, handleBlur,
handleChange, handleChange,
meta, meta,
errors errors,
setErrors
}; };
}, },
computed: { computed: {
@ -123,6 +128,11 @@ export default {
} }
}, },
watch: { watch: {
isDisabled(newValue, oldValue) {
if (newValue !== oldValue) {
this.setErrors([]);
}
},
selectedOption(newValue) { selectedOption(newValue) {
this.handleChange(newValue); this.handleChange(newValue);
} }

View file

@ -84,15 +84,8 @@ export default {
initialValue initialValue
}; };
const { errorMessage, const { errorMessage, handleChange, handleBlur, validate, errors, resetField } =
handleChange, useField(props.inputId, props.validationRules, fieldOptions);
handleBlur,
validate,
errors,
resetField } =
useField(props.inputId,
props.validationRules,
fieldOptions);
return { return {
errorMessage, errorMessage,

View file

@ -131,9 +131,8 @@ export default {
}; };
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
const { errorMessage, handleBlur, handleChange, meta, validate, errors } = useField(props.inputId, const { errorMessage, handleBlur, handleChange, meta, validate, errors } =
props.validationRules, useField(props.inputId, props.validationRules, fieldOptions);
fieldOptions);
return { return {
errorMessage, errorMessage,

View file

@ -7,44 +7,45 @@ import { GaCategories, GaActions, GaLabels } from '@/constants/analytics';
import headerKeys from '@/constants/header-keys'; import headerKeys from '@/constants/header-keys';
export default { export default {
callHttpClient({ method, endpoint, payload, logApiCall = true}) { callHttpClient({ method, endpoint, payload, logApiCall = true }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const store = useMainStore(); const store = useMainStore();
const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO;
const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: 'SelfService' }); const payloadAndAnalyticsData = { ...payload, AppName: 'SelfService' };
const headers = { const headers = {
[headerKeys.EXPERIMENT]: JSON.stringify(store.experimentSettings) [headerKeys.EXPERIMENT]: JSON.stringify(store.experimentSettings)
}; };
axios({ axios({
method: method, method,
url: cfDistroUrl + endpoint, url: cfDistroUrl + endpoint,
data: payloadAndAnalyticsData, data: payloadAndAnalyticsData,
crossDomain: true, crossDomain: true,
responseType: 'json', responseType: 'json',
headers: headers, headers
}) })
.then((response) => { .then(
if (logApiCall) { (response) => {
analyticsMixIn.methods.pushEventToGA( if (logApiCall) {
GaCategories.API_RESPONSE, analyticsMixIn.methods.pushEventToGA(
GaActions.RESULT, GaCategories.API_RESPONSE,
`${GaLabels.SUCCESS}_${endpoint}`, GaActions.RESULT,
true `${GaLabels.SUCCESS}_${endpoint}`,
); true
} );
return resolve(response); }
}, return resolve(response);
error => { },
console.error(error); (error) => {
window.console.error(error);
// implement if analytics service is down // implement if analytics service is down
if (endpoint.includes('analytics')) { if (endpoint.includes('analytics')) {
return resolve({data: ''}); return resolve({ data: '' });
} }
return reject(error.response); return reject(error.response);
} }
); );
}); });
}, },
@ -52,19 +53,18 @@ export default {
// used for mocked services // used for mocked services
async mockCallHttpClient(method, endpoint) { async mockCallHttpClient(method, endpoint) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios({ axios({
method: method, method,
url: endpoint, url: endpoint,
crossDomain: true, crossDomain: true,
responseType: {} responseType: {}
}) })
.then((response) => { .then(
return resolve(response); (response) => resolve(response),
}, (error) => {
error => { window.console.error(error);
console.error(error); return reject(error.response);
return reject(error.response); }
}
); );
}); });
} }

View file

@ -7,10 +7,54 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
jest.mock('axios'); jest.mock('axios');
jest.mock('@/mixins/analytics-mixin'); jest.mock('@/mixins/analytics-mixin');
/** @ignore */
function setupMocksForHttpClient({
endpoint = null,
isError = false,
additionalData = null
}) {
// Clear node module
axios.mockClear();
getMountOptions();
// Success Response
const response = {
status: 200,
data: {
message: 'Success',
additionalData
}
};
// Error Response
const error = {
response: {
status: 500,
data: {
message: 'Error',
additionalData
}
}
};
// Error interceptor on Axios returns a different object, so we need to mimic that.
if (isError) {
axios.mockRejectedValue(error);
} else {
axios.mockResolvedValue(response);
}
return {
endpoint,
logApiCall: true
};
}
it('Global Methods - Call Http Client - Should Resolve Promise', () => { it('Global Methods - Call Http Client - Should Resolve Promise', () => {
// Arrange // Arrange
const endpoint = 'https://mock.safelite.com'; const endpoint = 'https://mock.safelite.com';
const httpArgs = setupMocksForHttpClient({ endpoint: endpoint }); const httpArgs = setupMocksForHttpClient({ endpoint });
// Act // Act
globalMethods.callHttpClient(httpArgs).then((response) => { globalMethods.callHttpClient(httpArgs).then((response) => {
@ -25,7 +69,7 @@ it('Global Methods - Call Http Client - Should Reject Promise', () => {
// Arrange // Arrange
const endpoint = 'https://mock.safelite.com'; const endpoint = 'https://mock.safelite.com';
const httpArgs = setupMocksForHttpClient({ const httpArgs = setupMocksForHttpClient({
endpoint: endpoint, endpoint,
isError: true isError: true
}); });
analyticsMixIn.methods.pushEventToGA = jest.fn(); analyticsMixIn.methods.pushEventToGA = jest.fn();
@ -38,46 +82,3 @@ it('Global Methods - Call Http Client - Should Reject Promise', () => {
expect(err.status).toEqual(500); expect(err.status).toEqual(500);
}); });
}); });
function setupMocksForHttpClient({
endpoint = null,
isError = false,
additionalData = null
}) {
// Clear node module
axios.mockClear();
const mountOptions = getMountOptions();
// Success Response
const response = {
status: 200,
data: {
message: 'Success',
additionalData: additionalData
}
};
// Error Response
const error = {
response: {
status: 500,
data: {
message: 'Error',
additionalData: additionalData
}
}
};
// Error interceptor on Axios returns a different object, so we need to mimic that.
if (isError) {
axios.mockRejectedValue(error);
} else {
axios.mockResolvedValue(response);
}
return {
endpoint: endpoint,
logApiCall: true
};
}

View file

@ -4,11 +4,10 @@ const validateISSClientTag = (clientTag) => {
const store = useMainStore(); const store = useMainStore();
return store.validateClientTag(clientTag) return store.validateClientTag(clientTag)
.then((response) => .then(
// Success (response) => response,
response, () => null
// Error );
() => null);
}; };
export default validateISSClientTag; export default validateISSClientTag;

View file

@ -55,8 +55,11 @@ export function getCookieDomainValue() {
Used to create a cookie. Used to create a cookie.
`useDefaultISSCookieAttributes` will set the path and domain to our defaults `useDefaultISSCookieAttributes` will set the path and domain to our defaults
*/ */
function createOrUpdateCookie(key, value = '', function createOrUpdateCookie(
{ useDefaultISSCookieAttributes = true, maxAge, isSecure = true }) { key,
value = '',
{ useDefaultISSCookieAttributes = true, maxAge, isSecure = true }
) {
let cookieToAdd = `${key}=${value}; `; let cookieToAdd = `${key}=${value}; `;
if (useDefaultISSCookieAttributes) { if (useDefaultISSCookieAttributes) {
@ -122,7 +125,8 @@ export function updateOrCreateISSCookie() {
ReferralNumber: store.order.referralNumber, ReferralNumber: store.order.referralNumber,
ReferralDate: store.order.referralDate, ReferralDate: store.order.referralDate,
ReferralCorrelationId: store.order.referralCorrelationId, ReferralCorrelationId: store.order.referralCorrelationId,
ReferralParentAccountNumber: store.order.accountNumber ReferralParentAccountNumber: store.order.accountNumber,
SavedSessionId: store.applicationUser.savedSessionId
}); });
} }
@ -188,8 +192,10 @@ export function updateSessionIdCookie() {
createOrUpdateCookie(cookieNames.SESSION_ID, getSessionIdValue(), { maxAge: 60 * 30 }); createOrUpdateCookie(cookieNames.SESSION_ID, getSessionIdValue(), { maxAge: 60 * 30 });
} }
export function setCookieProperties(properties, export function setCookieProperties(
{ useDefaultISSCookieAttributes = true, maxAge, isSecure }) { properties,
{ useDefaultISSCookieAttributes = true, maxAge, isSecure }
) {
if (typeof properties === 'object') { if (typeof properties === 'object') {
Object.keys(properties).forEach((key) => { Object.keys(properties).forEach((key) => {
createOrUpdateCookie(key, properties[key], { createOrUpdateCookie(key, properties[key], {

View file

@ -26,8 +26,10 @@ describe('event-bus.js', () => {
useMainStore().eventBusItem.mockReturnValueOnce(event); useMainStore().eventBusItem.mockReturnValueOnce(event);
// TODO: Use or remove // TODO: Use or remove
const eventValue = eventBus.readAndPopEventFromBus(globalEvents.Categories.GLOBAL_ALERT, const eventValue = eventBus.readAndPopEventFromBus(
globalEvents.SubCategories.PAGE_NOT_FOUND); globalEvents.Categories.GLOBAL_ALERT,
globalEvents.SubCategories.PAGE_NOT_FOUND
);
expect(useMainStore().eventBusItem).toBeCalledTimes(1); expect(useMainStore().eventBusItem).toBeCalledTimes(1);
expect(useMainStore().removeEventFromBus).toBeCalledTimes(1); expect(useMainStore().removeEventFromBus).toBeCalledTimes(1);
@ -37,8 +39,10 @@ describe('event-bus.js', () => {
useMainStore().eventBusItem.mockReturnValueOnce(undefined); useMainStore().eventBusItem.mockReturnValueOnce(undefined);
// TODO: Use or remove // TODO: Use or remove
const eventValue = eventBus.readAndPopEventFromBus(globalEvents.Categories.GLOBAL_ALERT, const eventValue = eventBus.readAndPopEventFromBus(
globalEvents.SubCategories.PAGE_NOT_FOUND); globalEvents.Categories.GLOBAL_ALERT,
globalEvents.SubCategories.PAGE_NOT_FOUND
);
expect(useMainStore().eventBusItem).toBeCalledTimes(1); expect(useMainStore().eventBusItem).toBeCalledTimes(1);
expect(useMainStore().removeEventFromBus).toBeCalledTimes(0); expect(useMainStore().removeEventFromBus).toBeCalledTimes(0);
@ -47,17 +51,21 @@ describe('event-bus.js', () => {
it('returns event from bus', () => { it('returns event from bus', () => {
useMainStore().eventBusItem.mockReturnValueOnce(event); useMainStore().eventBusItem.mockReturnValueOnce(event);
const eventValue = eventBus.readEventFromBus(globalEvents.Categories.GLOBAL_ALERT, const eventValue = eventBus.readEventFromBus(
globalEvents.SubCategories.PAGE_NOT_FOUND); globalEvents.Categories.GLOBAL_ALERT,
globalEvents.SubCategories.PAGE_NOT_FOUND
);
expect(eventValue).toBe(event); expect(eventValue).toBe(event);
}); });
it('Reads event from bus, should have event value.', () => { it('Reads event from bus, should have event value.', () => {
// Arrange / Act // Arrange / Act
eventBus.addEventToBus(globalEvents.Categories.GLOBAL_ALERT, eventBus.addEventToBus(
globalEvents.Categories.GLOBAL_ALERT,
globalEvents.SubCategories.PAGE_NOT_FOUND, globalEvents.SubCategories.PAGE_NOT_FOUND,
event); event
);
expect(useMainStore().addEventToBus).toHaveBeenCalled(); expect(useMainStore().addEventToBus).toHaveBeenCalled();
}); });

View file

@ -9,10 +9,14 @@ import { required, regex } from '@/helpers/validation-rules';
function defineGlobalNameRules() { function defineGlobalNameRules() {
defineRule(globalRules.FIRST_NAME_REQUIRED, required(errorMessages.FIRST_NAME_REQUIRED)); defineRule(globalRules.FIRST_NAME_REQUIRED, required(errorMessages.FIRST_NAME_REQUIRED));
defineRule(globalRules.LAST_NAME_REQUIRED, required(errorMessages.LAST_NAME_REQUIRED)); defineRule(globalRules.LAST_NAME_REQUIRED, required(errorMessages.LAST_NAME_REQUIRED));
defineRule(globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED, defineRule(
required(errorMessages.POLICYHOLDER_FIRST_NAME_REQUIRED)); globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
defineRule(globalRules.POLICYHOLDER_LAST_NAME_REQUIRED, required(errorMessages.POLICYHOLDER_FIRST_NAME_REQUIRED)
required(errorMessages.POLICYHOLDER_LAST_NAME_REQUIRED)); );
defineRule(
globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
required(errorMessages.POLICYHOLDER_LAST_NAME_REQUIRED)
);
} }
/** /**
@ -20,9 +24,13 @@ function defineGlobalNameRules() {
*/ */
function defineGlobalEmailRules() { function defineGlobalEmailRules() {
defineRule(globalRules.EMAIL_ADDRESS_REQUIRED, required(errorMessages.EMAIL_ADDRESS_REQUIRED)); defineRule(globalRules.EMAIL_ADDRESS_REQUIRED, required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(globalRules.EMAIL_ADDRESS_FORMAT, defineRule(
regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, globalRules.EMAIL_ADDRESS_FORMAT,
errorMessages.EMAIL_ADDRESS_FORMAT)); regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT
)
);
} }
/** /**
@ -30,9 +38,13 @@ function defineGlobalEmailRules() {
*/ */
function defineGlobalPhoneNumberRules() { function defineGlobalPhoneNumberRules() {
defineRule(globalRules.PHONE_NUMBER_REQUIRED, required(errorMessages.PHONE_NUMBER_REQUIRED)); defineRule(globalRules.PHONE_NUMBER_REQUIRED, required(errorMessages.PHONE_NUMBER_REQUIRED));
defineRule(globalRules.PHONE_NUMBER_FORMAT, defineRule(
regex(/^(\([0-9]{3}\)|[0-9]{3}) *[-.]? *[0-9]{3} *[-.]? *[0-9]{4}$/, globalRules.PHONE_NUMBER_FORMAT,
errorMessages.PHONE_NUMBER_FORMAT)); regex(
/^(\([0-9]{3}\)|[0-9]{3}) *[-.]? *[0-9]{3} *[-.]? *[0-9]{4}$/,
errorMessages.PHONE_NUMBER_FORMAT
)
);
} }
/** /**

View file

@ -1,4 +1,4 @@
export function settleAllPromises(promiseResultMap) { const settleAllPromises = (promiseResultMap) => {
// Pull our keys out of the promise 'table' // Pull our keys out of the promise 'table'
const promiseNames = Object.entries(promiseResultMap); const promiseNames = Object.entries(promiseResultMap);
@ -22,4 +22,6 @@ export function settleAllPromises(promiseResultMap) {
return resultMap; return resultMap;
}); });
} };
export default settleAllPromises;

View file

@ -1,4 +1,4 @@
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
it('layout-helper: Should settle all promises and return mapped promise results', () => { it('layout-helper: Should settle all promises and return mapped promise results', () => {
// Arrange // Arrange

View file

@ -0,0 +1,29 @@
import { useMainStore } from '@/store';
import { updateOrCreateISSCookie } from '@/helpers/cookie-helper';
/*
Will call API to save existing order, or create new one depending where it's called from.
This will also set Referral information in the store after saving, and then
update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue
*/
export async function saveSession({ shouldAwaitSaveSessionQueue = false }) {
const store = useMainStore();
var saveSessionPromise = store.applicationUser.saveSessionPromise
? store.applicationUser.saveSessionPromise.then(() => { return saveSessionHelper(store); })
: saveSessionHelper(store);
store.setSaveSessionPromise(saveSessionPromise);
if (!store.applicationUser.savedSessionId || shouldAwaitSaveSessionQueue) {
await saveSessionPromise;
}
}
/*
Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing
*/
async function saveSessionHelper(store) {
const savedSessionInfo = await store.saveSession();
store.setSaveSessionInfo(savedSessionInfo.data);
updateOrCreateISSCookie();
}

View file

@ -1,11 +1,13 @@
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
export async function getServiceabilityDetails(serviceZipCode, lineItems) { export async function getServiceabilityDetails(serviceZipCode, lineItems) {
const serviceabilityDetails = await useMainStore().getServiceabilityDetails({ const serviceabilityDetails = await useMainStore().getServiceabilityDetails(
serviceZipCode, {
lineItems serviceZipCode,
}, lineItems
false); },
false
);
return Promise.resolve(serviceabilityDetails); return Promise.resolve(serviceabilityDetails);
} }

View file

@ -1,6 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */
import { RouterLinkStub } from '@vue/test-utils'; import { RouterLinkStub } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import vehicleCategories from '@/constants/vehicle-categories.js'; import vehicleCategories from '@/constants/vehicle-categories.js';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';
import cookieNames from '@/constants/cookie-names'; import cookieNames from '@/constants/cookie-names';
@ -59,7 +60,9 @@ export function getMountOptions(mockData) {
// Heritage integration common methods // Heritage integration common methods
export const cookies = { export const cookies = {
[cookieNames.ISS_SESSION_INFO]: '{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false}', [cookieNames.ISS_SESSION_INFO]:
// eslint-disable-next-line max-len
'{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false}',
UNIQUE_SESSION_ID: '33756020-b58e-4ec7-b8b8-3f1576719c40', UNIQUE_SESSION_ID: '33756020-b58e-4ec7-b8b8-3f1576719c40',
anotherCookie: '{}', anotherCookie: '{}',
someOtherCookie: '{}', someOtherCookie: '{}',

View file

@ -311,7 +311,8 @@ describe('address-questions.vue', () => {
describe('alerts', () => { describe('alerts', () => {
const places = [null, { address_components: null }, undefined, {}]; const places = [null, { address_components: null }, undefined, {}];
test.each(places)('selected place/place properties is null => display verification alert', test.each(places)(
'selected place/place properties is null => display verification alert',
async (place) => { async (place) => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -336,7 +337,8 @@ describe('address-questions.vue', () => {
const noMatchAlert = wrapper.findComponent({ ref: 'alertNoMatchWarning' }); const noMatchAlert = wrapper.findComponent({ ref: 'alertNoMatchWarning' });
expect(noMatchAlert.exists()).toBe(false); expect(noMatchAlert.exists()).toBe(false);
}); }
);
test('user enters address that yields no autocomplete results => show noMatch alert', async () => { test('user enters address that yields no autocomplete results => show noMatch alert', async () => {
// Arrange // Arrange

View file

@ -208,9 +208,11 @@ export default {
}); });
// Standard place_changed event handling // Standard place_changed event handling
const autocompleteListener = window.google.maps.event.addListener(autocomplete, const autocompleteListener = window.google.maps.event.addListener(
autocomplete,
'place_changed', 'place_changed',
fillInAddress); fillInAddress
);
addressField1.addEventListener('focus', () => { addressField1.addEventListener('focus', () => {
// Wrapping the addressField1 element in the Google Address Autocomplete object // Wrapping the addressField1 element in the Google Address Autocomplete object
@ -265,14 +267,16 @@ export default {
const firstResult = item.textContent; const firstResult = item.textContent;
const geocoder = new window.google.maps.Geocoder(); const geocoder = new window.google.maps.Geocoder();
geocoder.geocode({ geocoder.geocode(
address: firstResult {
}, address: firstResult
(results, status) => { },
if (status === window.google.maps.GeocoderStatus.OK) { (results, status) => {
fillInAddress(results[0]); if (status === window.google.maps.GeocoderStatus.OK) {
fillInAddress(results[0]);
}
} }
}); );
} else { } else {
// No addresses found for the input // No addresses found for the input
self.matchFound = false; self.matchFound = false;

View file

@ -48,7 +48,8 @@ export default {
// Display modal // Display modal
this.isModalVisible = true; this.isModalVisible = true;
// Force page reload on back button // Force page reload on back button
window.addEventListener('pageshow', window.addEventListener(
'pageshow',
(evt) => { (evt) => {
if (evt.persisted) { if (evt.persisted) {
setTimeout(() => { setTimeout(() => {
@ -56,7 +57,8 @@ export default {
}, 10); }, 10);
} }
}, },
false); false
);
}, },
hideModal() { hideModal() {
this.isModalVisible = false; this.isModalVisible = false;

View file

@ -65,8 +65,10 @@ export default ({
this.$nextTick(this.setupHeader); this.$nextTick(this.setupHeader);
// Check if alert event is on the bus // Check if alert event is on the bus
const alertEvent = eventBus.readAndPopEventFromBus(globalEvents.Categories.GLOBAL_ALERT, const alertEvent = eventBus.readAndPopEventFromBus(
globalEvents.SubCategories.PAGE_NOT_FOUND); globalEvents.Categories.GLOBAL_ALERT,
globalEvents.SubCategories.PAGE_NOT_FOUND
);
// If alert event is on the bus, then display the alert // If alert event is on the bus, then display the alert
if (alertEvent !== undefined) { if (alertEvent !== undefined) {
this.displayGlobalAlert = true; this.displayGlobalAlert = true;

View file

@ -57,8 +57,10 @@ export default {
return this.getCmsContent(this.cmsWidgetName, this.contentProperty ?? 'SubHeaderText'); return this.getCmsContent(this.cmsWidgetName, this.contentProperty ?? 'SubHeaderText');
}, },
subText() { subText() {
let subTextFromCms = this.getCmsContent(this.cmsWidgetName, let subTextFromCms = this.getCmsContent(
this.subContentProperty ?? 'SecondaryText'); this.cmsWidgetName,
this.subContentProperty ?? 'SecondaryText'
);
if (this.stripRteStyle) { if (this.stripRteStyle) {
subTextFromCms = stripRteStyle(subTextFromCms); subTextFromCms = stripRteStyle(subTextFromCms);

View file

@ -0,0 +1,29 @@
<template>
<div class="page-container-grouped-styles access-denied">
<div class="fade-on-route-transition position-relative">
<div class="container-fluid px-5">
<div class="row mt-5">
<div class="col d-flex justify-content-center">
<span>Unauthorized Access</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
// Supporting files
import BaseFormMixin from '@/mixins/base-form-mixin.js';
export default {
name: 'access-denied',
mixins: [BaseFormMixin],
data() {
return {};
},
methods: {}
};
</script>
<style lang="scss"></style>

View file

@ -2,11 +2,11 @@
import addressLookup from '@/layouts/address-lookup/address-lookup.vue'; import addressLookup from '@/layouts/address-lookup/address-lookup.vue';
// Supporting Files // Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper.js'; import settleAllPromises from '@/helpers/layout-helper.js';
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 { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
jest.mock('@/helpers/damage-helper', () => ({ jest.mock('@/helpers/damage-helper', () => ({
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true), isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
@ -14,9 +14,7 @@ jest.mock('@/helpers/damage-helper', () => ({
})); }));
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
/** @ignore */ /** @ignore */
function setupMocks({ function setupMocks({
@ -47,7 +45,8 @@ function setupMocks({
} }
})); }));
const wrapper = shallowMount(addressLookup, const wrapper = shallowMount(
addressLookup,
getMountOptions({ getMountOptions({
route: route || undefined, route: route || undefined,
router: { router: {
@ -71,7 +70,8 @@ function setupMocks({
} }
} }
})); })
);
const apiResponses = { const apiResponses = {
vinLookupResponse: { vinLookupResponse: {
@ -348,11 +348,13 @@ describe('address-lookup.vue', () => {
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
undefined, undefined,
{}, {},
{}, {},
carsFound); carsFound
);
}); });
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
@ -393,11 +395,14 @@ describe('address-lookup.vue', () => {
await wrapper.vm.navigateForward(carsFound); await wrapper.vm.navigateForward(carsFound);
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
undefined, undefined,
{}, {},
{ displayVehicleChangeAlert: true }); { displayVehicleChangeAlert: true }
}); );
}
);
test('single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => { test('single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => {
// Arrange // Arrange

View file

@ -87,12 +87,12 @@ import { Form } from 'vee-validate';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper'; import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper';
import vinPagesMixin from '@/mixins/vin-pages-mixin'; import vinPagesMixin from '@/mixins/vin-pages-mixin';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store/index.js';
export default { export default {
name: 'address-lookup', name: 'address-lookup',
@ -142,15 +142,17 @@ export default {
}, },
computed: { computed: {
AlertMatchedDifferentVehicleHeader() { AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:damage}', getDamageString()); 'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
AlertMatchedDifferentVehicleBody() { AlertMatchedDifferentVehicleBody() {
const vinYmmFound = const vinYmmFound =
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`; `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
const vinYmmExpected = const vinYmmExpected =
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`; `${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model}`;
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText') return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
.replaceAll('{custom:damage}', getDamageString()) .replaceAll('{custom:damage}', getDamageString())
@ -158,8 +160,10 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected); .replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
}, },
AlertMatchedTwoIdenticalYMMVehicleHeader() { AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:damage}', getDamageString()); 'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
AlertMatchedTwoIdenticalYMMVehicleBody() { AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound = const vinYmmsFound =
@ -167,7 +171,7 @@ export default {
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`; `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
const vinYmmsExpected = const vinYmmsExpected =
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`; `${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model} ${useMainStore().order.vehicle.style}`;
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText') return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
.replaceAll('{custom:damage}', getDamageString()) .replaceAll('{custom:damage}', getDamageString())
@ -179,7 +183,7 @@ export default {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`; `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
const vinYmmExpected = const vinYmmExpected =
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`; `${useMainStore().order.vehicle.year} ${useMainStore().order.vehicle.make} ${useMainStore().order.vehicle.model}`;
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase()); return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
} }
}, },
@ -199,7 +203,7 @@ export default {
}, },
methods: { methods: {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
return this.mainStore.order.vehicle.carId !== null; return useMainStore().order.vehicle.carId !== null;
}, },
backButtonAction() { backButtonAction() {
@ -208,10 +212,12 @@ export default {
}, },
attachCustomEvents() { attachCustomEvents() {
this.prependActionToMethod(this, this.forwardButtonAction, () => { this.prependActionToMethod(this, this.forwardButtonAction, () => {
this.pushEventToGA(this.$route.query[this.queryStrings.ISS_PAGE], this.pushEventToGA(
this.$route.query[this.queryStrings.ISS_PAGE],
this.GaActions.SUBMITTED, this.GaActions.SUBMITTED,
this.GaLabels.ADDRESS_LOOKUP, this.GaLabels.ADDRESS_LOOKUP,
true); true
);
}); });
}, },
@ -277,7 +283,7 @@ export default {
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin }); vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
} else if (carsFound.length > 1) { } else if (carsFound.length > 1) {
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info // If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
const matchingCars = carsFound.filter((vin) => vin.vehicle.carId === this.mainStore.order.vehicle.carId); const matchingCars = carsFound.filter((vin) => vin.vehicle.carId === useMainStore().order.vehicle.carId);
if (matchingCars.length === 1) { if (matchingCars.length === 1) {
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, { vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {
@ -292,22 +298,24 @@ export default {
} }
// Save vehicle, customer, service and registration information // Save vehicle, customer, service and registration information
await useMainStore().saveRegistrationAddressLookup({ await useMainStore().saveRegistrationAddressLookup(
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle, {
vehicleInfo: isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
Object.keys(vehicleInfoToCommit).length === 0 vehicleInfo:
? null Object.keys(vehicleInfoToCommit).length === 0
: vehicleInfoToCommit, ? null
registrationInfo: { : vehicleInfoToCommit,
firstName: this.customerQuestions.firstName, registrationInfo: {
lastName: this.customerQuestions.lastName, firstName: this.customerQuestions.firstName,
address: this.customerQuestions.addressQuestions.streetAddress, lastName: this.customerQuestions.lastName,
city: this.customerQuestions.addressQuestions.city, address: this.customerQuestions.addressQuestions.streetAddress,
state: this.customerQuestions.addressQuestions.state, city: this.customerQuestions.addressQuestions.city,
zipCode: this.customerQuestions.addressQuestions.zipCode state: this.customerQuestions.addressQuestions.state,
} zipCode: this.customerQuestions.addressQuestions.zipCode
}, }
false); },
false
);
return this.navigateForward(carsFound); return this.navigateForward(carsFound);
}, },
@ -322,18 +330,22 @@ export default {
this.isCarIdDifferent this.isCarIdDifferent
&& !this.isSelectedGlassAvailableForVehicle && !this.isSelectedGlassAvailableForVehicle
) { ) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, this.$router.navigate(
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route, this.$route,
{}, {},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }); { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else if (matchingCars.length === 1) { } else if (matchingCars.length === 1) {
await this.navigateForwardWithSingleCarMatch(); await this.navigateForwardWithSingleCarMatch();
} else { } else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES, this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
this.$route, this.$route,
{}, {},
{}, {},
carsFound); carsFound
);
} }
}, },
resetWarningsAndErrors() { resetWarningsAndErrors() {

View file

@ -58,8 +58,10 @@ export default {
emits: ['update: modelValue'], emits: ['update: modelValue'],
computed: { computed: {
differentVehicleAlertHeader() { differentVehicleAlertHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'HeadlineText').replaceAll('{custom:damage}', return this.getCmsContent(
getDamageString()); 'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
differentVehicleAlertBody() { differentVehicleAlertBody() {
const vinYmmFound = const vinYmmFound =
@ -73,11 +75,14 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected); .replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
}, },
AlertMatchedTwoIdenticalYMMVehicleHeader() { AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:damage}', getDamageString()); 'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
AlertMatchedTwoIdenticalYMMVehicleBody() { AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound = const vinYmmsFound =
// eslint-disable-next-line max-len
`${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model} ${this.selectedVehicle?.vehicle.style}`; `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model} ${this.selectedVehicle?.vehicle.style}`;
const vinYmmsExpected = const vinYmmsExpected =
`${this.vehicleSelected?.year} ${this.vehicleSelected?.make} ${this.vehicleSelected?.model} ${this.vehicleSelected?.style}`; `${this.vehicleSelected?.year} ${this.vehicleSelected?.make} ${this.vehicleSelected?.model} ${this.vehicleSelected?.style}`;

View file

@ -1,5 +1,5 @@
import addressVehicles from '@/layouts/address-vehicles/address-vehicles.vue'; import addressVehicles from '@/layouts/address-vehicles/address-vehicles.vue';
import { settleAllPromises } from '@/helpers/layout-helper.js'; import settleAllPromises from '@/helpers/layout-helper.js';
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 { useMainStore } from '@/store'; import { useMainStore } from '@/store';
@ -21,9 +21,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({
})); }));
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
function setupMocks({ function setupMocks({
route = null, route = null,
@ -209,7 +207,8 @@ describe('address-vehicles.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate).toBeCalledTimes(1); expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
}); }
);
test('carId is not different on navigateForward (car was found) => Should handle navigating forward with car match', async () => { test('carId is not different on navigateForward (car was found) => Should handle navigating forward with car match', async () => {
// Arrange // Arrange
@ -233,10 +232,12 @@ describe('address-vehicles.vue', () => {
useMainStore().order.vehicle.carId = 'CR00000395'; useMainStore().order.vehicle.carId = 'CR00000395';
// Act // Act
addressVehicles.beforeRouteEnter.call(wrapper.vm, addressVehicles.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'address-vehicles' } }, { query: { issPage: 'address-vehicles' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();

View file

@ -65,7 +65,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
@ -148,8 +148,10 @@ export default {
return this.VehiclesForQuestions.length; return this.VehiclesForQuestions.length;
}, },
AlertFoundMultipleVehiclesHeader() { AlertFoundMultipleVehiclesHeader() {
return this.getCmsContent('FoundMultipleVehicles', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:vehicleCount}', this.vehicleCount); 'FoundMultipleVehicles',
'HeadlineText'
).replaceAll('{custom:vehicleCount}', this.vehicleCount);
}, },
isTwoIdenticalYMMVehicleFound() { isTwoIdenticalYMMVehicleFound() {
const vinYmmFound = const vinYmmFound =
@ -224,7 +226,7 @@ export default {
getRouterLinkRouteFromCopy, getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy, getRouterLinkDisplayTextFromCopy,
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
if (this.mainStore.order.vehicle.carId) { if (useMainStore().order.vehicle.carId) {
return true; return true;
} }
return false; return false;
@ -242,14 +244,16 @@ export default {
return; return;
} }
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId); this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
await useMainStore().saveVin({ await useMainStore().saveVin(
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, { {
vin: this.selectedVehicle.vin vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
}), vin: this.selectedVehicle.vin
isSelectedGlassAvailableForVehicle: }),
this.isSelectedGlassAvailableForVehicle isSelectedGlassAvailableForVehicle:
}, this.isSelectedGlassAvailableForVehicle
false); },
false
);
await this.navigateForward(); await this.navigateForward();
}, },
@ -257,10 +261,12 @@ export default {
// If the vehicle selected on this page is different from the one originally entered and the selected glass is not available // If the vehicle selected on this page is different from the one originally entered and the selected glass is not available
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page. // for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) { if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, this.$router.navigate(
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route, this.$route,
{}, {},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }); { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else { } else {
await this.navigateForwardWithSingleCarMatch(); await this.navigateForwardWithSingleCarMatch();
} }

View file

@ -74,7 +74,7 @@ import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
export default { export default {
@ -134,11 +134,13 @@ export default {
return this.navigateForward(); return this.navigateForward();
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route, this.$route,
{}, {},
{}, {},
this.bailoutPageModel); this.bailoutPageModel
);
}, },
getBailoutPageModelFromStore() { getBailoutPageModelFromStore() {
return { return {

View file

@ -21,7 +21,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
// Import Component // Import Component
import baseFormMixin from '@/mixins/base-form-mixin'; import baseFormMixin from '@/mixins/base-form-mixin';
@ -101,17 +101,21 @@ export default {
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, const updatedGlass = this.setupInitialData(
glass,
index, index,
alreadyAnsweredQuestions); alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions // Set up watch for each set of glass questions
this.$watch(`selectedAnswers.${glass.answerKey}`, this.$watch(
`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;
}); });
}, },

View file

@ -16,7 +16,7 @@ import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import issPageValues from '@/router/router-constants/issPage-values.js'; import issPageValues from '@/router/router-constants/issPage-values.js';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
export default { export default {

View file

@ -6,7 +6,7 @@ import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { getRandomString, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js'; import { getRandomString, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import { useMainStore } from '@/store/index.js'; import { useMainStore } from '@/store/index.js';
describe('contactDetails.vue', () => { describe('contactDetails.vue', () => {

View file

@ -205,8 +205,10 @@ export default {
notesForTechnician: this.notesForTechnician notesForTechnician: this.notesForTechnician
}; };
useMainStore().updateContactInfo(contactInfo); useMainStore().updateContactInfo(contactInfo);
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -5,14 +5,13 @@ import coverageStatement from '@/layouts/coverage-statement/coverage-statement.v
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import { getRandomString, getRandomInt } from '@/helpers/data-generation.js'; import { getRandomString, getRandomInt } from '@/helpers/data-generation.js';
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 routerParams from '@/router/router-constants/router-params';
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
fetchCmsContentForPage: jest.fn(), fetchCmsContentForPage: jest.fn(),
@ -459,7 +458,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
test('If Verified Deductible, navigate forward with CLICKED_FORWARD scenario', () => { test('If Verified Deductible, navigate forward with CLICKED_FORWARD scenario', () => {
// Arrange // Arrange
@ -495,7 +498,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
test('If Verified ITAC and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => { test('If Verified ITAC and selected Safelite, navigate forward with CLICKED_FORWARD_WITH_SAFELITE scenario', () => {
// Arrange // Arrange
@ -532,7 +539,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
test('If Verified ITAC, selected other shop, and TPA enabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_ENABLED', () => { test('If Verified ITAC, selected other shop, and TPA enabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_ENABLED', () => {
// Arrange // Arrange
@ -572,7 +583,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
test('If Verified ITAC, selected other shop, and TPA disabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_DISABLED', () => { test('If Verified ITAC, selected other shop, and TPA disabled, navigate forward w/ CLICKED_FORWARD_WITH_TPA_DISABLED', () => {
// Arrange // Arrange
@ -612,7 +627,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
test('If No Comp and selected Safelite, navigate forward with CLICKED_FORWARD scenario', () => { test('If No Comp and selected Safelite, navigate forward with CLICKED_FORWARD scenario', () => {
// Arrange // Arrange
@ -638,7 +657,11 @@ describe('coverageStatement.vue', () => {
// Assert // Assert
expect(wrapper.vm.$router.navigate) expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, undefined); .toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
undefined,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true });
}); });
}); });
describe('ADAS', () => { describe('ADAS', () => {

View file

@ -113,13 +113,14 @@ import loadingModal from '@/iss-components/loading-modal/loading-modal.vue';
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage, setupModalLinks, processIfStatements } from '@/helpers/cms-content-helper.js'; import { fetchCmsContentForPage, setupModalLinks, processIfStatements } from '@/helpers/cms-content-helper.js';
import { settleAllPromises } from '@/helpers/layout-helper.js'; import settleAllPromises from '@/helpers/layout-helper.js';
import { getDamageString } from '@/helpers/damage-helper.js'; import { getDamageString } from '@/helpers/damage-helper.js';
import { useMainStore } from '@/store/index.js'; import { useMainStore } from '@/store/index.js';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin.js'; import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin.js';
import globalRules from '@/constants/global-rules.js'; import globalRules from '@/constants/global-rules.js';
import baseFormMixin from '@/mixins/base-form-mixin.js'; import baseFormMixin from '@/mixins/base-form-mixin.js';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios.js'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import routerParams from '@/router/router-constants/router-params';
export default { export default {
name: 'coverage-statement', name: 'coverage-statement',
@ -192,12 +193,16 @@ export default {
}, },
computed: { computed: {
verifiedITACAlertHeader() { verifiedITACAlertHeader() {
return this.getCmsContent('VerifiedITACAlert', return this.getCmsContent(
'HeadlineText'); 'VerifiedITACAlert',
'HeadlineText'
);
}, },
verifiedITACAlertBody() { verifiedITACAlertBody() {
return this.getCmsContent('VerifiedITACAlert', return this.getCmsContent(
'BodyText')?.replaceAll('{custom:costSavings}', this.costSavings); 'VerifiedITACAlert',
'BodyText'
)?.replaceAll('{custom:costSavings}', this.costSavings);
}, },
coverageStatementSubHeader() { coverageStatementSubHeader() {
return this.getSubheaderTextFromCms('SiteSubHeaderWidget'); return this.getSubheaderTextFromCms('SiteSubHeaderWidget');
@ -331,22 +336,42 @@ export default {
}, },
async navigateForward() { async navigateForward() {
if (this.unverified || this.verifiedDeductible) { if (this.unverified || this.verifiedDeductible) {
this.$router.navigate(navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); navigationScenarios.CLICKED_FORWARD,
this.$route,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
);
} else if (this.verifiedITAC || this.verifiedNoComp) { } else if (this.verifiedITAC || this.verifiedNoComp) {
if (this.selectedProvider === 'Safelite') { if (this.selectedProvider === 'Safelite') {
this.$router.navigate(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, this.$router.navigate(
this.$route); navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
this.$route,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
);
} else if (useMainStore().issConfig.enableTPAFlow) { } else if (useMainStore().issConfig.enableTPAFlow) {
this.$router.navigate(navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED, this.$router.navigate(
this.$route); navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED,
this.$route,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
);
} else { } else {
this.$router.navigate(navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED, this.$router.navigate(
this.$route); navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED,
this.$route,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
);
} }
} else { } else {
this.$router.navigate(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE, this.$router.navigate(
this.$route); navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE,
this.$route,
{},
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true }
);
} }
}, },
openModalAction(modalName) { openModalAction(modalName) {
@ -428,7 +453,7 @@ export default {
line-height: 1.5rem; line-height: 1.5rem;
} }
::v-deep p { :deep p {
line-height: 1.5rem; line-height: 1.5rem;
font-size: 0.875rem; font-size: 0.875rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
@ -437,7 +462,7 @@ export default {
} }
} }
::v-deep .question-text { :deep .question-text {
margin-top: 1.5rem; margin-top: 1.5rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
font-size: 1rem; font-size: 1rem;
@ -447,7 +472,7 @@ export default {
} }
} }
::v-deep .deductible-modal { :deep .deductible-modal {
p { p {
margin-bottom: 0 !important; margin-bottom: 0 !important;
font-size: 1rem; font-size: 1rem;

View file

@ -74,7 +74,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .recal-modal-body { :deep .recal-modal-body {
h5 { h5 {
color: $black; color: $black;
} }

View file

@ -2,14 +2,12 @@
import entryPage from '@/layouts/entry-page/entry-page.vue'; import entryPage from '@/layouts/entry-page/entry-page.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';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -26,8 +24,10 @@ function setupMocks(queryString) {
route: { queryString } route: { queryString }
}); });
const wrapper = shallowMount(entryPage, const wrapper = shallowMount(
mountOptions); entryPage,
mountOptions
);
const apiResponses = {}; const apiResponses = {};

View file

@ -36,8 +36,10 @@ export default {
methods: methods:
{ {
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.MOVE_FORWARD_ENTRY_PAGE, this.$router.navigate(
this.$route); this.navigationScenarios.MOVE_FORWARD_ENTRY_PAGE,
this.$route
);
}, },
parseQueryParms() { parseQueryParms() {
// Dump the query string parameters into an array. Remove casing on the key for easy compare. // Dump the query string parameters into an array. Remove casing on the key for easy compare.

View file

@ -2,11 +2,11 @@
import licensePlateLookup from '@/layouts/license-plate-lookup/license-plate-lookup.vue'; import licensePlateLookup from '@/layouts/license-plate-lookup/license-plate-lookup.vue';
// Supporting Files // Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper.js'; import settleAllPromises from '@/helpers/layout-helper.js';
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 { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
jest.mock('@/helpers/damage-helper', () => ({ jest.mock('@/helpers/damage-helper', () => ({
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true), isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
@ -14,9 +14,7 @@ jest.mock('@/helpers/damage-helper', () => ({
})); }));
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -57,7 +55,8 @@ function setupMocks({
} }
})); }));
const wrapper = shallowMount(licensePlateLookup, const wrapper = shallowMount(
licensePlateLookup,
getMountOptions({ getMountOptions({
route: route || undefined, route: route || undefined,
router: { router: {
@ -75,7 +74,8 @@ function setupMocks({
} }
} }
})); })
);
const apiResponses = { const apiResponses = {
serviceZipValidationResponse: { serviceZipValidationResponse: {
@ -183,10 +183,12 @@ describe('license-plate-lookup.vue', () => {
} }
}); });
// Act // Act
licensePlateLookup.beforeRouteEnter.call(wrapper.vm, licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'license-plate-lookup' } }, { query: { issPage: 'license-plate-lookup' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
await wrapper.vm.backButtonAction(); await wrapper.vm.backButtonAction();
// Assert // Assert
@ -242,11 +244,14 @@ describe('license-plate-lookup.vue', () => {
await wrapper.vm.navigateForward(carsFound); await wrapper.vm.navigateForward(carsFound);
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
undefined, undefined,
{}, {},
{ displayVehicleChangeAlert: true }); { displayVehicleChangeAlert: true }
}); );
}
);
}); });
describe('miscellaneous', () => { describe('miscellaneous', () => {
@ -256,10 +261,12 @@ describe('license-plate-lookup.vue', () => {
useMainStore().order.vehicle.carId = 'CR00000395'; useMainStore().order.vehicle.carId = 'CR00000395';
// Act // Act
licensePlateLookup.beforeRouteEnter.call(wrapper.vm, licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'license-plate-lookup' } }, { query: { issPage: 'license-plate-lookup' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();

View file

@ -78,7 +78,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
@ -154,8 +154,10 @@ export default {
}, },
computed: { computed: {
AlertMatchedDifferentVehicleHeader() { AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:damage}', getDamageString()); 'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
AlertMatchedDifferentVehicleBody() { AlertMatchedDifferentVehicleBody() {
const vinYmmFound = const vinYmmFound =
@ -170,8 +172,10 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected); .replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
}, },
AlertMatchedTwoIdenticalYMMVehicleHeader() { AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', return this.getCmsContent(
'HeadlineText').replaceAll('{custom:damage}', getDamageString()); 'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
}, },
AlertMatchedTwoIdenticalYMMVehicleBody() { AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound = const vinYmmsFound =
@ -214,7 +218,7 @@ export default {
}, },
methods: { methods: {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
return this.mainStore.order.vehicle.carId !== null; return useMainStore().order.vehicle.carId !== null;
}, },
loadDefaultsFromStore() { loadDefaultsFromStore() {
this.customerQuestions = this.mainStore.customerData.addressQuestions.state; this.customerQuestions = this.mainStore.customerData.addressQuestions.state;
@ -225,10 +229,12 @@ export default {
}, },
attachCustomEvents() { attachCustomEvents() {
this.prependActionToMethod(this, this.forwardButtonAction, () => { this.prependActionToMethod(this, this.forwardButtonAction, () => {
this.pushEventToGA(this.$route.query[this.queryStrings.ISS_PAGE], this.pushEventToGA(
this.$route.query[this.queryStrings.ISS_PAGE],
this.GaActions.SUBMITTED, this.GaActions.SUBMITTED,
this.GaLabels.LICENSE_PLATE_LOOKUP, this.GaLabels.LICENSE_PLATE_LOOKUP,
true); true
);
}); });
}, },
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked // NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
@ -287,15 +293,17 @@ export default {
} }
// Save vehicle, license plate, and registration information // Save vehicle, license plate, and registration information
await useMainStore().saveRegistrationLicensePlateLookup({ await useMainStore().saveRegistrationLicensePlateLookup(
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle, {
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }), isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
registrationInfo: { vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
licensePlate: this.licensePlate, registrationInfo: {
state: this.licenseState licensePlate: this.licensePlate,
} state: this.licenseState
}, }
false); },
false
);
return this.navigateForward(); return this.navigateForward();
}, },
@ -304,10 +312,12 @@ export default {
// not available for that vehicle then navigate back to "vehicle-damage" // not available for that vehicle then navigate back to "vehicle-damage"
// display vehicle changed alert on that page. // display vehicle changed alert on that page.
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) { if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, this.$router.navigate(
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route, this.$route,
{}, {},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }); { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else { } else {
await this.navigateForwardWithSingleCarMatch(); await this.navigateForwardWithSingleCarMatch();
} }

View file

@ -22,7 +22,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin'; import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
@ -70,8 +70,10 @@ export default {
}, },
computed: { computed: {
AlertFewMoreQuestionsHeader() { AlertFewMoreQuestionsHeader() {
return this.getCmsContent('AdditionalPartsQuestionsAlert', return this.getCmsContent(
'HeadlineText'); 'AdditionalPartsQuestionsAlert',
'HeadlineText'
);
}, },
AlertFewMoreQuestionsCopy() { AlertFewMoreQuestionsCopy() {
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText'); return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
@ -105,18 +107,24 @@ export default {
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, const updatedGlass = this.setupInitialData(
glass,
index, index,
alreadyAnsweredQuestions); alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions // Set up watch for each set of glass questions
this.$watch(`selectedAnswers.${glass.answerKey}`, this.$watch(
`selectedAnswers.${glass.answerKey}`,
(newValue) => { (newValue) => {
if (newValue && Object.keys(newValue).length > 0) { if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, this.handleAnswerUpdates(
glass.answerKey); newValue,
glass.answerKey
);
} }
}, },
{ deep: true }); { deep: true }
);
return updatedGlass; return updatedGlass;
}); });
}, },

View file

@ -26,7 +26,7 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';
@ -63,8 +63,10 @@ export default {
return this.navigateForward(); return this.navigateForward();
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -91,6 +91,7 @@ const baseStoreGettersPageData = () => ({
{ {
questionSequence: 1, questionSequence: 1,
questionText: questionText:
// eslint-disable-next-line max-len
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?', 'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
answers: [ answers: [
{ {
@ -122,12 +123,14 @@ const baseStoreGettersDamage = () => ({
answeredQuestions: [ answeredQuestions: [
{ {
questionText: questionText:
// eslint-disable-next-line max-len
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?', 'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
selectedAnswerText: 'Yes', selectedAnswerText: 'Yes',
questionNum: 1 questionNum: 1
}, },
{ {
questionText: questionText:
// eslint-disable-next-line max-len
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?', 'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
selectedAnswerText: 'Yes', selectedAnswerText: 'Yes',
questionNum: 2 questionNum: 2

View file

@ -24,7 +24,7 @@ import questionsPageLayout from '@/iss-components/questions-page-layout/question
// Supporting Files // Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
@ -96,13 +96,15 @@ export default {
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(`selectedAnswers.${glass.answerKey}`, this.$watch(
`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;
}); });

View file

@ -27,7 +27,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';

View file

@ -3,15 +3,13 @@ import policyHolderDetails from '@/layouts/policy-holder-details/policy-holder-d
// 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 { 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';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -20,7 +18,8 @@ jest.mock('@/helpers/cms-content-helper', () => ({
/** @ignore */ /** @ignore */
function setupMocks() { function setupMocks() {
const wrapper = shallowMount(policyHolderDetails, const wrapper = shallowMount(
policyHolderDetails,
getMountOptions({ getMountOptions({
router: { router: {
navigate: jest.fn() navigate: jest.fn()
@ -32,7 +31,8 @@ function setupMocks() {
} }
} }
} }
})); })
);
const policies = [{ const policies = [{
vehicles: [ vehicles: [
{ {
@ -165,10 +165,12 @@ describe('navigation', () => {
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
undefined, undefined,
{}, {},
{}, {},
mockvehicles); mockvehicles
);
}); });
}); });

View file

@ -59,7 +59,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
@ -131,14 +131,18 @@ export default {
navigateForward() { navigateForward() {
if (this.vehiclesCount > 0) { if (this.vehiclesCount > 0) {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED, this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED,
this.$route, this.$route,
{}, {},
{}, {},
this.vehiclesFound); this.vehiclesFound
);
} else { } else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
this.$route
);
} }
}, },

View file

@ -1,10 +1,10 @@
import policyVehicles from '@/layouts/policy-vehicles/policy-vehicles.vue'; import policyVehicles from '@/layouts/policy-vehicles/policy-vehicles.vue';
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';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import baseMixin from '@/mixins/base-mixin'; 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';
@ -23,9 +23,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({
})); }));
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
const mockMixin = { const mockMixin = {
methods: { methods: {
@ -90,7 +88,9 @@ describe('policy-vehicles.vue', () => {
describe('forwardButtonAction', () => { describe('forwardButtonAction', () => {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
test('Selected VIN matches vehicle listed in system => update vehicle and navigate forward with CLICKED_FORWARD_LISTED_VEHICLE scenario.', test(
// eslint-disable-next-line max-len
'Selected VIN matches vehicle listed in system => update vehicle and navigate forward with CLICKED_FORWARD_LISTED_VEHICLE scenario.',
async () => { async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -127,13 +127,17 @@ 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(navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
undefined, undefined,
{}, {},
{}); {}
}); );
}
);
test('Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', test(
'Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.',
async () => { async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -152,11 +156,14 @@ describe('policy-vehicles.vue', () => {
// Assert // Assert
expect(wrapper.vm.bailout).toBeTruthy(); expect(wrapper.vm.bailout).toBeTruthy();
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
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 () => {
// Arrange // Arrange
@ -170,10 +177,12 @@ describe('policy-vehicles.vue', () => {
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
undefined, undefined,
{}, {},
{}); {}
);
}); });
}); });

View file

@ -189,13 +189,16 @@ export default {
}, },
navigateForward() { navigateForward() {
if (this.bailout) { if (this.bailout) {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
this.$route, this.$route,
{}, {},
{}); {}
);
} else if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) { } else if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
this.$router this.$router
.navigate(this.navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE, .navigate(
this.navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
this.$route, this.$route,
{}, {},
{}); {});
@ -205,10 +208,12 @@ export default {
{}, {},
{}); {});
} else { } else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE, this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
this.$route, this.$route,
{}, {},
{}); {}
);
} }
}, },
async lookupVehicleByVin(vin) { async lookupVehicleByVin(vin) {

View file

@ -107,7 +107,8 @@ describe('provider-pref-radio.vue', () => {
const fileredResults = results.filter((result) => result.includes(' -')); const fileredResults = results.filter((result) => result.includes(' -'));
expect(fileredResults.length).toBe(0); expect(fileredResults.length).toBe(0);
}); });
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ', it(
'Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
async () => { async () => {
// Arrange // Arrange
const moddedProps = mockProps; const moddedProps = mockProps;
@ -123,5 +124,6 @@ describe('provider-pref-radio.vue', () => {
// Assert // Assert
expect(results.length).toBe(5); expect(results.length).toBe(5);
}); }
);
}); });

View file

@ -1,16 +1,14 @@
import ProviderPreference from '@/layouts/provider-preference/provider-preference.vue'; import ProviderPreference from '@/layouts/provider-preference/provider-preference.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 { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -27,8 +25,10 @@ function setupMocks(mockApiResponses) {
route: 'provider-preference' route: 'provider-preference'
}); });
const wrapper = shallowMount(ProviderPreference, const wrapper = shallowMount(
mountOptions); ProviderPreference,
mountOptions
);
useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => Promise.resolve({ useMainStore().getCoveragePolicyInfo = jest.fn().mockImplementation(() => Promise.resolve({
data: {} data: {}

View file

@ -52,7 +52,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage, setupModalLinks } 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.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';

View file

@ -1,13 +1,11 @@
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 shopPreferenceModal from '@/layouts/provider-preference/shop-preference-modal/shop-preference-modal.vue'; import shopPreferenceModal from '@/layouts/provider-preference/shop-preference-modal/shop-preference-modal.vue';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -25,8 +23,10 @@ function setupMocks(propsData) {
mountOptions.propsData = propsData; mountOptions.propsData = propsData;
const wrapper = shallowMount(shopPreferenceModal, const wrapper = shallowMount(
mountOptions); shopPreferenceModal,
mountOptions
);
const apiResponses = {}; const apiResponses = {};

View file

@ -1,14 +1,12 @@
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 { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import steeringModal from '@/layouts/provider-preference/steering-modal/steering-modal.vue'; import steeringModal from '@/layouts/provider-preference/steering-modal/steering-modal.vue';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -24,8 +22,10 @@ function setupMocks() {
} }
}); });
const wrapper = shallowMount(steeringModal, const wrapper = shallowMount(
mountOptions); steeringModal,
mountOptions
);
const apiResponses = {}; const apiResponses = {};

View file

@ -1,13 +1,11 @@
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 '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-modal.vue'; import tpaRecalModal from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-modal.vue';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -23,8 +21,10 @@ function setupMocks() {
} }
}); });
const wrapper = shallowMount(tpaRecalModal, const wrapper = shallowMount(
mountOptions); tpaRecalModal,
mountOptions
);
const apiResponses = {}; const apiResponses = {};

View file

@ -26,7 +26,7 @@ import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';
@ -68,8 +68,10 @@ export default {
forwardButtonAction() { forwardButtonAction() {
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -28,7 +28,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';

View file

@ -9,12 +9,14 @@ jest.mock('@/helpers/cms-content-helper', () => ({
/** @ignore */ /** @ignore */
function setupMocks() { function setupMocks() {
const wrapper = shallowMount(serviceLocation, const wrapper = shallowMount(
serviceLocation,
getMountOptions({ getMountOptions({
router: { router: {
navigate: jest.fn() navigate: jest.fn()
} }
})); })
);
return { wrapper }; return { wrapper };
} }
@ -30,10 +32,12 @@ const mockGetServiceabilityDetails = () => {
return Promise.resolve(serviceabilityDetails); return Promise.resolve(serviceabilityDetails);
}; };
jest.mock('@/helpers/service-location-helper', jest.mock(
'@/helpers/service-location-helper',
() => ({ () => ({
getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode)) getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode))
})); })
);
const mockMixin = { const mockMixin = {
methods: { methods: {

View file

@ -58,7 +58,7 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
import buttonQuestion from '@/digital-components/button-question/button-question.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
@ -118,8 +118,7 @@ export default {
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
vm.setData(resultMap.zipCodeData, vm.setData(resultMap.zipCodeData, resultMap.serviceabilityDetails);
resultMap.serviceabilityDetails);
}); });
}, },
setup() { setup() {
@ -170,8 +169,11 @@ export default {
} }
}, },
methods: { methods: {
arePagePrerequisiteValid() { arePagePrerequisitesValid() {
return true; return (
useMainStore().lineItems.supportingItems !== null
&& useMainStore().order.serviceLocation.zipCode !== null
);
}, },
backButtonAction() { backButtonAction() {
/** /**

View file

@ -53,11 +53,13 @@ const mockGetZipCodeData = (mockServiceZipCode) => {
}; };
}; };
jest.mock('@/helpers/service-location-helper', jest.mock(
'@/helpers/service-location-helper',
() => ({ () => ({
getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode)), getServiceabilityDetails: jest.fn((mockServiceZipCode) => mockGetServiceabilityDetails(mockServiceZipCode)),
getZipCodeData: jest.fn((mockServiceZipCode) => mockGetZipCodeData(mockServiceZipCode)) getZipCodeData: jest.fn((mockServiceZipCode) => mockGetZipCodeData(mockServiceZipCode))
})); })
);
const linkWidgetName = 'linkWidgetName'; const linkWidgetName = 'linkWidgetName';
const modalWidgetName = 'modalWidgetName'; const modalWidgetName = 'modalWidgetName';

View file

@ -107,7 +107,8 @@ describe('service-package-radio.vue', () => {
const fileredResults = results.filter((result) => result.includes(' -')); const fileredResults = results.filter((result) => result.includes(' -'));
expect(fileredResults.length).toBe(0); expect(fileredResults.length).toBe(0);
}); });
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ', it(
'Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
async () => { async () => {
// Arrange // Arrange
const moddedProps = mockProps; const moddedProps = mockProps;
@ -123,5 +124,6 @@ describe('service-package-radio.vue', () => {
// Assert // Assert
expect(results.length).toBe(5); expect(results.length).toBe(5);
}); }
);
}); });

View file

@ -58,7 +58,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue'; import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal.vue';
import loadingModal from '@/iss-components/loading-modal/loading-modal.vue'; 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 { Form } from 'vee-validate'; import { Form } from 'vee-validate';

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" /> @backClicked="backButtonAction" />
</div> </div>
</div> </div>
</div> </div>
@ -22,11 +22,11 @@
</template> </template>
<script> <script>
// Components // Components
import siteHeader from '@/iss-components/site-header/site-header'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';
@ -36,6 +36,7 @@ export default {
components: { components: {
siteHeader, siteHeader,
siteFooter, siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form Form
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
@ -70,8 +71,10 @@ export default {
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" /> @backClicked="backButtonAction" />
</div> </div>
</div> </div>
</div> </div>
@ -22,11 +22,11 @@
</template> </template>
<script> <script>
// Components // Components
import siteHeader from '@/iss-components/site-header/site-header'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';
@ -65,8 +65,10 @@ export default {
return this.navigateForward(); return this.navigateForward();
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" /> @backClicked="backButtonAction" />
</div> </div>
</div> </div>
</div> </div>
@ -22,12 +22,12 @@
</template> </template>
<script> <script>
// Components // Components
import siteHeader from '@/iss-components/site-header/site-header'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; 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';
@ -37,6 +37,7 @@ export default {
components: { components: {
siteHeader, siteHeader,
siteFooter, siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form Form
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
@ -76,8 +77,10 @@ export default {
}, },
navigateForward() { navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
} }
} }
}; };

View file

@ -1,51 +1,8 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import damageLocationQuestion from '@/layouts/vehicle-damage/damage-location-question/damage-location-question'; import damageLocationQuestion from '@/layouts/vehicle-damage/damage-location-question/damage-location-question.vue';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
describe('damage-location-question.vue', () => { /** @ignore */
test('Selected location option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const locationToSelect = ['Backseat'];
// Act
wrapper.setValue({ modelValue: locationToSelect });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
test('Answers to display filtered by data from api.', async () => {
// Arrange
const { wrapper, cmsContent, damageOptions } = setupMocks({
dataFromStoreApi: {
driverSideOptions: {
availableReplacementOptions: ['Quarter', 'Front']
},
windshieldOptions: {
availableReplacementOptions: ['Single']
},
backGlassOptions: {
availableReplacementOptions: []
}
}
});
// Act
damageLocationQuestion.methods.initializeComponent.call(wrapper.vm,
damageOptions,
'car-group');
// Assert
expect(wrapper.vm.damageOptions).toStrictEqual({
backGlassOptions: { availableReplacementOptions: [] },
driverSideOptions: { availableReplacementOptions: ['Quarter', 'Front'] },
windshieldOptions: { availableReplacementOptions: ['Single'] }
});
});
});
function setupMocks({ function setupMocks({
modelValueProp = ['Windshield', 'SideDoor'], modelValueProp = ['Windshield', 'SideDoor'],
isMultiSelect = false, isMultiSelect = false,
@ -79,3 +36,49 @@ function setupMocks({
const damageOptions = dataFromStoreApi; const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions }; return { wrapper, cmsContent, damageOptions };
} }
describe('damage-location-question.vue', () => {
test('Selected location option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const locationToSelect = ['Backseat'];
// Act
wrapper.setValue({ modelValue: locationToSelect });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
test('Answers to display filtered by data from api.', async () => {
// Arrange
const { wrapper, cmsContent, damageOptions } = setupMocks({
dataFromStoreApi: {
driverSideOptions: {
availableReplacementOptions: ['Quarter', 'Front']
},
windshieldOptions: {
availableReplacementOptions: ['Single']
},
backGlassOptions: {
availableReplacementOptions: []
}
}
});
// Act
damageLocationQuestion.methods.initializeComponent.call(
wrapper.vm,
damageOptions,
'car-group'
);
// Assert
expect(wrapper.vm.damageOptions).toStrictEqual({
backGlassOptions: { availableReplacementOptions: [] },
driverSideOptions: { availableReplacementOptions: ['Quarter', 'Front'] },
windshieldOptions: { availableReplacementOptions: ['Single'] }
});
});
});

View file

@ -13,7 +13,7 @@
</template> </template>
<script> <script>
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import { defineRule } from 'vee-validate'; import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';

View file

@ -1,86 +1,8 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question'; import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
describe('replace-options-question.vue', () => { /** @ignore */
test('Selected damage option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const damageToSelect = ['Backseat'];
// Act
wrapper.setValue({ modelValue: damageToSelect });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
});
describe('replace-options-question.vue', () => {
test('Answers to display filtered by data from api.', async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
dataFromStoreApi: ['Windshield', 'FrontDoor'],
filterByVehicleCategory: true
});
// Act
replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm,
replaceOptions,
'car-group');
// Assert
expect(wrapper.vm.replaceOptions).toStrictEqual(['Windshield', 'FrontDoor']);
});
});
describe('replace-options-question.vue', () => {
test('when updateSelectedValues method is called with a single answerToDisplay it will call to update this.selectedReplaceOptions', async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
modelValueProp: []
});
wrapper.setData({
answersFromCms: [
{
Name: 'Stationary'
},
{
Name: 'Slider'
}
]
});
wrapper.setData({ replaceOptions: ['Stationary'] });
// Act
wrapper.vm.$options.methods.updateSelectedValues.call(wrapper.vm);
expect(wrapper.vm.selectedValues).toEqual([]);
});
});
describe('replace-options-question.vue', () => {
test('when isAvailable is true, will run updateSelectedValues method', async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
isAvailable: false,
methodsToMock: ['updateSelectedValues']
});
// Act
wrapper.vm.$options.methods.initializeComponent.call(wrapper.vm,
cmsContent,
replaceOptions,
'car-group');
wrapper.vm.$options.watch.isAvailable.call(wrapper.vm, true);
// Assert
expect(replaceOptionsQuestion.methods.updateSelectedValues).toHaveBeenCalled();
wrapper.unmount();
});
});
function setupMocks({ function setupMocks({
modelValueProp = ['Windshield'], modelValueProp = ['Windshield'],
isAvailable = true, isAvailable = true,
@ -92,7 +14,7 @@ function setupMocks({
dataFromStoreApi = [], dataFromStoreApi = [],
methodsToMock = [] methodsToMock = []
}) { }) {
const mountOptions = getMountOptions({ }); const mountOptions = getMountOptions({});
// Mock props // Mock props
const mockMixin = { const mockMixin = {
@ -124,3 +46,88 @@ function setupMocks({
const replaceOptions = dataFromStoreApi; const replaceOptions = dataFromStoreApi;
return { wrapper, cmsContent, replaceOptions }; return { wrapper, cmsContent, replaceOptions };
} }
describe('replace-options-question.vue', () => {
test('Selected damage option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const damageToSelect = ['Backseat'];
// Act
wrapper.setValue({ modelValue: damageToSelect });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
});
describe('replace-options-question.vue', () => {
test('Answers to display filtered by data from api.', async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
dataFromStoreApi: ['Windshield', 'FrontDoor'],
filterByVehicleCategory: true
});
// Act
replaceOptionsQuestion.methods.initializeComponent.call(
wrapper.vm,
replaceOptions,
'car-group'
);
// Assert
expect(wrapper.vm.replaceOptions).toStrictEqual(['Windshield', 'FrontDoor']);
});
});
describe('replace-options-question.vue', () => {
test('when updateSelectedValues method is called with a single answerToDisplay it will call to update this.selectedReplaceOptions',
async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
modelValueProp: []
});
wrapper.setData({
answersFromCms: [
{
Name: 'Stationary'
},
{
Name: 'Slider'
}
]
});
wrapper.setData({ replaceOptions: ['Stationary'] });
// Act
wrapper.vm.$options.methods.updateSelectedValues.call(wrapper.vm);
expect(wrapper.vm.selectedValues).toEqual([]);
}
);
});
describe('replace-options-question.vue', () => {
test('when isAvailable is true, will run updateSelectedValues method', async () => {
// Arrange
const { wrapper, cmsContent, replaceOptions } = setupMocks({
isAvailable: false,
methodsToMock: ['updateSelectedValues']
});
// Act
wrapper.vm.$options.methods.initializeComponent.call(
wrapper.vm,
cmsContent,
replaceOptions,
'car-group'
);
wrapper.vm.$options.watch.isAvailable.call(wrapper.vm, true);
// Assert
expect(replaceOptionsQuestion.methods.updateSelectedValues).toHaveBeenCalled();
wrapper.unmount();
});
});

View file

@ -23,7 +23,7 @@
</template> </template>
<script> <script>
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default { export default {
name: 'replace-options-question', name: 'replace-options-question',

View file

@ -1,91 +1,9 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import sideDoorOptions from '@/layouts/vehicle-damage/side-door-options/side-door-options'; import sideDoorOptions from '@/layouts/vehicle-damage/side-door-options/side-door-options.vue';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question'; import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
describe('replace-options-question.vue', () => {
test('Selected side door option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const sideDoorOptions = ['Backseat'];
// Act
wrapper.setValue({ modelValue: sideDoorOptions });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
});
describe('replace-options-question.vue', () => {
test('Selected door side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedDoorSidesValues = ['DriverSide'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
describe('replace-options-question.vue', () => {
test('Selected driver side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedDriverSideReplaceOptionsValues = ['FrontDoor'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
describe('replace-options-question.vue', () => {
test('Selected passenger side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedPassengerSideReplaceOptionsValues = ['BacktDoor'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
describe('replace-options-question.vue', () => {
test('Answers to display filtered by data from api.', async () => {
// Arrange
const {
wrapper,
cmsContent,
driverSideReplaceOptions,
passengerSideReplaceOptions,
driverSideOptions,
passengerSideOptions
} = setupMocks({});
// Act
sideDoorOptions.methods.initializeComponent.call(wrapper.vm,
cmsContent,
driverSideReplaceOptions,
passengerSideReplaceOptions,
driverSideOptions,
passengerSideOptions,
'car-group');
// Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([]);
});
});
/** @ignore */
function setupMocks({ function setupMocks({
modelValueProp = ['DriverSide'], modelValueProp = ['DriverSide'],
groupName = 'sideDoorOptions', groupName = 'sideDoorOptions',
@ -133,3 +51,91 @@ function setupMocks({
passengerSideOptions passengerSideOptions
}; };
} }
describe('replace-options-question.vue', () => {
test('Selected side door option is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: ['Windshield'] });
const sideDoorOptions = ['Backseat'];
// Act
wrapper.setValue({ modelValue: sideDoorOptions });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: ['Backseat'] }]);
});
});
// TODO: Add () to toHaveBeenCalled and ensure the test passes
describe.skip('replace-options-question.vue', () => {
test('Selected door side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedDoorSidesValues = ['DriverSide'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
// TODO: Add () to toHaveBeenCalled and ensure the test passes
describe.skip('replace-options-question.vue', () => {
test('Selected driver side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedDriverSideReplaceOptionsValues = ['FrontDoor'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
// TODO: Add () to toHaveBeenCalled and ensure the test passes
describe.skip('replace-options-question.vue', () => {
test('Selected passenger side option is updated when selection made.', async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
wrapper.vm.selectedPassengerSideReplaceOptionsValues = ['BacktDoor'];
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.getSideDoorReplacementOptions()).toHaveBeenCalled;
});
});
describe('replace-options-question.vue', () => {
test('Answers to display filtered by data from api.', async () => {
// Arrange
const {
wrapper,
cmsContent,
driverSideReplaceOptions,
passengerSideReplaceOptions,
driverSideOptions,
passengerSideOptions
} = setupMocks({});
// Act
sideDoorOptions.methods.initializeComponent.call(
wrapper.vm,
cmsContent,
driverSideReplaceOptions,
passengerSideReplaceOptions,
driverSideOptions,
passengerSideOptions,
'car-group'
);
// Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([]);
});
});

View file

@ -42,8 +42,8 @@
</template> </template>
<script> <script>
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question'; import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import { defineRule } from 'vee-validate'; import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
@ -87,9 +87,11 @@ export default {
return this.selectedValues.selectedDoorSides; return this.selectedValues.selectedDoorSides;
}, },
set(newValue) { set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(newValue, this.selectedValues = this.getSideDoorReplacementOptions(
newValue,
this.selectedValues.selectedDriverSideReplaceOptions, this.selectedValues.selectedDriverSideReplaceOptions,
this.selectedValues.selectedPassengerSideReplaceOptions); this.selectedValues.selectedPassengerSideReplaceOptions
);
} }
}, },
selectedDriverSideReplaceOptionsValues: { selectedDriverSideReplaceOptionsValues: {
@ -97,9 +99,11 @@ export default {
return this.selectedValues.selectedDriverSideReplaceOptions; return this.selectedValues.selectedDriverSideReplaceOptions;
}, },
set(newValue) { set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides, this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
newValue, newValue,
this.selectedValues.selectedPassengerSideReplaceOptions); this.selectedValues.selectedPassengerSideReplaceOptions
);
} }
}, },
selectedPassengerSideReplaceOptionsValues: { selectedPassengerSideReplaceOptionsValues: {
@ -107,9 +111,11 @@ export default {
return this.selectedValues.selectedPassengerSideReplaceOptions; return this.selectedValues.selectedPassengerSideReplaceOptions;
}, },
set(newValue) { set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides, this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
this.selectedValues.selectedDriverSideReplaceOptions, this.selectedValues.selectedDriverSideReplaceOptions,
newValue); newValue
);
} }
}, },
answersToDisplay() { answersToDisplay() {
@ -148,9 +154,11 @@ export default {
this.$refs.driverSideOptions.initializeComponent(driverSideOptions); this.$refs.driverSideOptions.initializeComponent(driverSideOptions);
this.$refs.passengerSideOptions.initializeComponent(passengerSideOptions); this.$refs.passengerSideOptions.initializeComponent(passengerSideOptions);
}, },
getSideDoorReplacementOptions(selectedDoorSides, getSideDoorReplacementOptions(
selectedDoorSides,
selectedDriverSideReplaceOptions, selectedDriverSideReplaceOptions,
selectedPassengerSideReplaceOptions) { selectedPassengerSideReplaceOptions
) {
return { return {
selectedDoorSides, selectedDoorSides,
selectedDriverSideReplaceOptions, selectedDriverSideReplaceOptions,

View file

@ -1,8 +1,9 @@
/* eslint-env jest */ /* eslint-env jest */
import { mount, flushPromises } from '@vue/test-utils'; import { mount, flushPromises } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import { useMainStore } from '@/store';
import vehicleCategories from '@/constants/vehicle-categories'; import vehicleCategories from '@/constants/vehicle-categories';
import VehicleDamageComponent from '@/layouts/vehicle-damage/vehicle-damage.vue'; import VehicleDamageComponent from '@/layouts/vehicle-damage/vehicle-damage.vue';
@ -69,6 +70,21 @@ describe('vehicle-damage.vue', () => {
const wrapper = mount(VehicleDamageComponent, mountOptions); const wrapper = mount(VehicleDamageComponent, mountOptions);
const siteFooterWrapper = wrapper.getComponent({ ref: 'siteFooter' }); const siteFooterWrapper = wrapper.getComponent({ ref: 'siteFooter' });
useMainStore().getSupportingItems = jest.fn().mockImplementation(() => Promise.resolve({
data: { data: [
{
description: null,
partNumber: 'SUPPLIES-REPAIR',
partType: 'REPAIR FEE'
},
{
description: null,
partNumber: 'WSREPAIR',
partType: 'REPAIR FEE'
}
] }
}));
siteFooterWrapper.vm.$emit('forwardClicked'); siteFooterWrapper.vm.$emit('forwardClicked');
await flushPromises(); await flushPromises();

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -72,20 +72,20 @@
<script> <script>
// Components // Components
import siteHeader from '@/iss-components/site-header/site-header'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner'; import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import sideDoorOptions from '@/layouts/vehicle-damage/side-door-options/side-door-options'; import sideDoorOptions from '@/layouts/vehicle-damage/side-door-options/side-door-options.vue';
import damageLocationQuestion from '@/layouts/vehicle-damage/damage-location-question/damage-location-question'; import damageLocationQuestion from '@/layouts/vehicle-damage/damage-location-question/damage-location-question.vue';
import windshieldOptions from '@/layouts/vehicle-damage/windshield-options/windshield-options'; import windshieldOptions from '@/layouts/vehicle-damage/windshield-options/windshield-options.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question'; import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
// Supporting files // Supporting files
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { Form, defineRule } from 'vee-validate'; import { Form, defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
@ -138,8 +138,10 @@ export default {
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
vm.$refs.damageLocation.initializeComponent(resultMap.damageOptions); vm.$refs.damageLocation.initializeComponent(resultMap.damageOptions);
vm.$refs.sideDoorOptions.initializeComponent(resultMap.damageOptions.driverSideOptions.availableReplacementOptions, vm.$refs.sideDoorOptions.initializeComponent(
resultMap.damageOptions.passengerSideOptions.availableReplacementOptions); resultMap.damageOptions.driverSideOptions.availableReplacementOptions,
resultMap.damageOptions.passengerSideOptions.availableReplacementOptions
);
vm.$refs.windshieldOptions.initializeComponent(resultMap.damageOptions.windshieldOptions.availableReplacementOptions); vm.$refs.windshieldOptions.initializeComponent(resultMap.damageOptions.windshieldOptions.availableReplacementOptions);
vm.$refs.backGlassOptions.initializeComponent(resultMap.damageOptions.backGlassOptions.availableReplacementOptions); vm.$refs.backGlassOptions.initializeComponent(resultMap.damageOptions.backGlassOptions.availableReplacementOptions);
}); });
@ -228,7 +230,7 @@ export default {
}, },
methods: { methods: {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
if (this.mainStore.order.vehicle.carId) { if (useMainStore().order.vehicle.carId) {
return true; return true;
} }
return false; return false;
@ -285,8 +287,7 @@ export default {
&& glass.glassName === damageLocationsSelected.SINGLE && glass.glassName === damageLocationsSelected.SINGLE
)) ))
) { ) {
windShieldOptions.selectedWindshieldDamageType windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPLACE;
= damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.SINGLE); windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.SINGLE);
} }
@ -296,8 +297,7 @@ export default {
&& glass.glassName === damageLocationsSelected.DRIVER && glass.glassName === damageLocationsSelected.DRIVER
)) ))
) { ) {
windShieldOptions.selectedWindshieldDamageType windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPLACE;
= damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.DRIVER); windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.DRIVER);
} }
@ -307,8 +307,7 @@ export default {
&& glass.glassName === damageLocationsSelected.PASSENGER && glass.glassName === damageLocationsSelected.PASSENGER
)) ))
) { ) {
windShieldOptions.selectedWindshieldDamageType windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPLACE;
= damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.PASSENGER); windShieldOptions.selectedWindshieldReplaceOptions.push(damageLocationsSelected.PASSENGER);
} }
} }
@ -365,23 +364,37 @@ export default {
}, },
async forwardButtonAction() { async forwardButtonAction() {
await this.mainStore.saveVehicleDamage(this.isWindshieldRepair, this.mainStore.saveVehicleDamage(
this.isWindshieldRepair,
this.selectedGlassToReplace(), this.selectedGlassToReplace(),
this.selectedWindshieldOptions.selectedWindshieldChipCount); this.selectedWindshieldOptions.selectedWindshieldChipCount
);
if (this.isWindshieldRepair) {
const supportingItems = await useMainStore().getSupportingItems();
this.mainStore.saveSupportingItems(supportingItems.data);
}
return this.navigateForward(); return this.navigateForward();
}, },
navigateForward() { navigateForward() {
if (this.mainStore.damage.isRepair) { if (this.mainStore.damage.isRepair) {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_REPAIR, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD_WITH_REPAIR,
this.$route
);
} else if (this.mainStore.order.vehicle.vin) { } else if (this.mainStore.order.vehicle.vin) {
// If vin already exists, navigate directly to vin-lookup // If vin already exists, navigate directly to vin-lookup
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_VIN, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD_WITH_VIN,
this.$route
);
} else { } else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
this.$route
);
} }
}, },

View file

@ -1,28 +1,9 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import windshieldChipCountQuestion from '@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question'; // eslint-disable-next-line max-len
import windshieldChipCountQuestion from '@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
describe('windshield-chip-count-question.vue', () => { /** @ignore */
test('Selected chip count is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: 1 });
// Act
wrapper.vm.selectedValue = '2';
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([2]);
});
test('selectedValue matches modelValue', () => {
// Arrange/Act
const { wrapper } = setupMocks({ modelValueProp: 2 });
// Assert
expect(wrapper.vm.selectedValue).toBe(2);
});
});
function setupMocks({ function setupMocks({
modelValueProp = ['Two'], modelValueProp = ['Two'],
groupName = 'WindshieldChipCountQuestion', groupName = 'WindshieldChipCountQuestion',
@ -55,3 +36,24 @@ function setupMocks({
const damageOptions = dataFromStoreApi; const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions }; return { wrapper, cmsContent, damageOptions };
} }
describe('windshield-chip-count-question.vue', () => {
test('Selected chip count is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: 1 });
// Act
wrapper.vm.selectedValue = '2';
// Assert
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([2]);
});
test('selectedValue matches modelValue', () => {
// Arrange/Act
const { wrapper } = setupMocks({ modelValueProp: 2 });
// Assert
expect(wrapper.vm.selectedValue).toBe(2);
});
});

View file

@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default { export default {
name: 'windshield-options', name: 'windshield-options',

View file

@ -1,22 +1,9 @@
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import windshieldDamageTypeQuestion from '@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question'; // eslint-disable-next-line max-len
import windshieldDamageTypeQuestion from '@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue';
import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { getMountOptions } from '@/helpers/unit-test-helper.js';
describe('windshield-damage-type-question.vue', () => { /** @ignore */
test('Selected windshield damage is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: 'Repair' });
// Act
wrapper.setValue({ modelValue: 'Replace' });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.selectedValues).toEqual('Repair');
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: 'Replace' }]);
});
});
function setupMocks({ function setupMocks({
modelValueProp = '', modelValueProp = '',
groupName = 'WindshieldDamageTypeQuestion', groupName = 'WindshieldDamageTypeQuestion',
@ -42,10 +29,25 @@ function setupMocks({
// Mock CMS content // Mock CMS content
const cmsContent = { const cmsContent = {
groupName: groupName, groupName,
QuestionText: cmsQuestionText, QuestionText: cmsQuestionText,
Answers: cmsAnswers Answers: cmsAnswers
}; };
const damageOptions = dataFromStoreApi; const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions }; return { wrapper, cmsContent, damageOptions };
} }
describe('windshield-damage-type-question.vue', () => {
test('Selected windshield damage is emitted upon selection.', async () => {
// Arrange
const { wrapper } = setupMocks({ modelValueProp: 'Repair' });
// Act
wrapper.setValue({ modelValue: 'Replace' });
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.selectedValues).toEqual('Repair');
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([{ modelValue: 'Replace' }]);
});
});

View file

@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default { export default {
name: 'windshield-damage-type-question', name: 'windshield-damage-type-question',

View file

@ -40,11 +40,11 @@
<script> <script>
import windshieldDamageTypeQuestion from import windshieldDamageTypeQuestion from
'@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question'; '@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question.vue';
import windshieldChipCountQuestion from import windshieldChipCountQuestion from
'@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question'; '@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question'; import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
import { defineRule } from 'vee-validate'; import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
@ -52,20 +52,28 @@ import errorMessages from '@/constants/error-messages';
import damageLocationsSelected from '@/constants/damage-locations-selected.js'; import damageLocationsSelected from '@/constants/damage-locations-selected.js';
// DEFINE VALIDATION RULES // DEFINE VALIDATION RULES
defineRule('windshield-damage-type-required', defineRule(
required(errorMessages.WINDSHIELD_DAMAGE_TYPE_REQUIRED)); 'windshield-damage-type-required',
defineRule('windshield-chip-count-required', required(errorMessages.WINDSHIELD_DAMAGE_TYPE_REQUIRED)
required(errorMessages.WINDSHIELD_CHIP_COUNT_REQUIRED)); );
defineRule('windshield-replace-options-required', defineRule(
required(errorMessages.WINDSHIELD_REPLACE_OPTIONS_REQUIRED)); 'windshield-chip-count-required',
required(errorMessages.WINDSHIELD_CHIP_COUNT_REQUIRED)
);
defineRule(
'windshield-replace-options-required',
required(errorMessages.WINDSHIELD_REPLACE_OPTIONS_REQUIRED)
);
defineRule('check-for-repair-and-replace', defineRule(
'check-for-repair-and-replace',
(selectedWindshieldDamageType, selectedDamageLocations) => ( (selectedWindshieldDamageType, selectedDamageLocations) => (
selectedWindshieldDamageType.toString() !== damageLocationsSelected.REPAIR selectedWindshieldDamageType.toString() !== damageLocationsSelected.REPAIR
|| (!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) || (!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD)
&& !selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD)) && !selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD))
|| selectedDamageLocations[0].length === 1 || selectedDamageLocations[0].length === 1
)); )
);
defineRule('repair-only', (value) => value.toString() === damageLocationsSelected.REPAIR); defineRule('repair-only', (value) => value.toString() === damageLocationsSelected.REPAIR);
defineRule('prevent-split-and-single-together', (value) => { defineRule('prevent-split-and-single-together', (value) => {
if ( if (
@ -126,9 +134,11 @@ export default {
return this.selectedValues.selectedWindshieldChipCount; return this.selectedValues.selectedWindshieldChipCount;
}, },
set(newValue) { set(newValue) {
this.selectedValues = this.getWindshieldOptions(this.selectedWindshieldDamageTypeValue, this.selectedValues = this.getWindshieldOptions(
this.selectedWindshieldDamageTypeValue,
newValue, newValue,
null); null
);
} }
}, },
selectedWindshieldReplaceOptionsValues: { selectedWindshieldReplaceOptionsValues: {
@ -136,9 +146,11 @@ export default {
return this.selectedValues.selectedWindshieldReplaceOptions; return this.selectedValues.selectedWindshieldReplaceOptions;
}, },
set(newValue) { set(newValue) {
this.selectedValues = this.getWindshieldOptions(this.selectedWindshieldDamageTypeValue, this.selectedValues = this.getWindshieldOptions(
this.selectedWindshieldDamageTypeValue,
null, null,
newValue); newValue
);
} }
}, },
isWindshieldDamageLocation() { isWindshieldDamageLocation() {
@ -182,8 +194,8 @@ export default {
}, },
windshieldDamageTypeQuestionValidationRules() { windshieldDamageTypeQuestionValidationRules() {
// Note: the validation rules string is not dynamic (it cannot be changed once component has been created) // Note: the validation rules string is not dynamic (it cannot be changed once component has been created)
let validationRules let validationRules =
= 'windshield-damage-type-required|check-for-repair-and-replace:@DamageLocationQuestion'; 'windshield-damage-type-required|check-for-repair-and-replace:@DamageLocationQuestion';
// if vehicle has no windshield replacement option // if vehicle has no windshield replacement option
if (!this.isWindshieldReplaceAvailable) { if (!this.isWindshieldReplaceAvailable) {
validationRules = validationRules.concat('|repair-only'); validationRules = validationRules.concat('|repair-only');
@ -197,9 +209,11 @@ export default {
this.windshieldAvailableReplacementOptions = windshieldAvailableReplacementOptions; this.windshieldAvailableReplacementOptions = windshieldAvailableReplacementOptions;
this.$refs.replaceOptionsQuestion.initializeComponent(windshieldAvailableReplacementOptions); this.$refs.replaceOptionsQuestion.initializeComponent(windshieldAvailableReplacementOptions);
}, },
getWindshieldOptions(selectedWindshieldDamageType, getWindshieldOptions(
selectedWindshieldDamageType,
selectedWindshieldChipCount, selectedWindshieldChipCount,
selectedWindshieldReplaceOptions) { selectedWindshieldReplaceOptions
) {
// ONLY UPDATE THE NEW VALUE IF IT IS TRUTHY (NOT NULL) // ONLY UPDATE THE NEW VALUE IF IT IS TRUTHY (NOT NULL)
return { return {
selectedWindshieldDamageType: selectedWindshieldDamageType || this.selectedValues.selectedWindshieldDamageType, selectedWindshieldDamageType: selectedWindshieldDamageType || this.selectedValues.selectedWindshieldDamageType,

View file

@ -1,6 +1,6 @@
/* eslint-env jest */ /* eslint-env jest */
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import queryStrings from '@/constants/query-strings'; import queryStrings from '@/constants/query-strings';
import { GaActions } from '@/constants/analytics'; import { GaActions } from '@/constants/analytics';
import vinLookupMethodSelections from '@/constants/vin-lookup-methods'; import vinLookupMethodSelections from '@/constants/vin-lookup-methods';
@ -11,7 +11,7 @@ import { defineRule } from 'vee-validate';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import VehicleLookup from '@/layouts/vehicle-lookup/vehicle-lookup'; import VehicleLookup from '@/layouts/vehicle-lookup/vehicle-lookup.vue';
const pinia = createTestingPinia(); const pinia = createTestingPinia();
useMainStore(pinia); useMainStore(pinia);

View file

@ -1,7 +1,7 @@
<template> <template>
<Form <Form
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -26,8 +26,8 @@
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="isForwardActionDisabled" :isForwardActionDisabled="isForwardActionDisabled"
class="mt-5" class="mt-5"
@back-clicked="backButtonAction" @backClicked="backButtonAction"
@forward-clicked="forwardButtonAction" /> @forwardClicked="forwardButtonAction" />
</div> </div>
</div> </div>
</div> </div>
@ -40,18 +40,17 @@
<script> <script>
// Import Supporting Files // Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin'; import BaseFormMixin from '@/mixins/base-form-mixin';
import vinLookupMethodSelections from '@/constants/vin-lookup-methods'; import vinLookupMethodSelections from '@/constants/vin-lookup-methods';
import { useMainStore } from '@/store';
// Import Component // Import Component
import SiteFooter from '@/iss-components/site-footer/site-footer'; import SiteFooter from '@/iss-components/site-footer/site-footer.vue';
import SiteHeader from '@/iss-components/site-header/site-header'; import SiteHeader from '@/iss-components/site-header/site-header.vue';
import SiteSubHeader from '@/iss-components/site-sub-header/site-sub-header'; import SiteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import VehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner'; import VehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import VinLookupMethods from '@/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods'; import VinLookupMethods from '@/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods.vue';
export default { export default {
name: 'vehicle-lookup', name: 'vehicle-lookup',
@ -105,17 +104,17 @@ export default {
}, },
forwardButtonAction() { forwardButtonAction() {
switch (this.selectedVinLookupMethod) { switch (this.selectedVinLookupMethod) {
case vinLookupMethodSelections.MANUALVIN: case vinLookupMethodSelections.MANUALVIN:
this.$router.navigate(this.navigationScenarios.SELECTED_MANUAL_VIN, this.$route); this.$router.navigate(this.navigationScenarios.SELECTED_MANUAL_VIN, this.$route);
break; break;
case vinLookupMethodSelections.LICENSEPLATE: case vinLookupMethodSelections.LICENSEPLATE:
this.$router.navigate(this.navigationScenarios.SELECTED_LICENSE_PLATE, this.$route); this.$router.navigate(this.navigationScenarios.SELECTED_LICENSE_PLATE, this.$route);
break; break;
case vinLookupMethodSelections.HOMEADDRESS: case vinLookupMethodSelections.HOMEADDRESS:
this.$router.navigate(this.navigationScenarios.SELECTED_HOME_ADDRESS, this.$route); this.$router.navigate(this.navigationScenarios.SELECTED_HOME_ADDRESS, this.$route);
break; break;
default: default:
break; break;
} }
}, },
resetDependentState() {} resetDependentState() {}

View file

@ -14,11 +14,11 @@
// Import Other Supporting Files // Import Other Supporting Files
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import vinLookupMethodSelections from '@/constants/vin-lookup-methods'; import vinLookupMethodSelections from '@/constants/vin-lookup-methods';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
// Import Component // Import Component
import ButtonQuestion from '@/digital-components/button-question/button-question'; import ButtonQuestion from '@/digital-components/button-question/button-question.vue';
export default { export default {
name: 'vin-lookup-methods', name: 'vin-lookup-methods',

View file

@ -1,6 +1,6 @@
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 glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question'; import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
const featureListData = { const featureListData = {
@ -23,6 +23,34 @@ const featureListData = {
modelValueProp: {} modelValueProp: {}
}; };
/** @ignore */
function setupMocks({ glassNameProp, glassLocationProp, colorAnswersProp, modelValueProp, pageData }) {
const mountOptions = getMountOptions({
route: {
query: {
issPage: 'vehicle-parts'
}
}
});
mountOptions.propsData = {
glassName: glassNameProp,
glassLocation: glassLocationProp,
colorAnswers: colorAnswersProp,
modelValue: modelValueProp
};
const wrapper = shallowMount(glassPartQuestion, mountOptions);
// Mock store
const partsOrQuestions = pageData ?? { partsOrQuestions: [{ glassName: 'Stationary', glassLocation: 'Rear', parts: [] }] };
useMainStore().pageData = jest.fn();
useMainStore().pageData.mockReturnValue(partsOrQuestions);
document.querySelector = jest.fn().mockReturnValue({ clicked: false, click: jest.fn() });
return { wrapper };
}
describe('glass-part-question.vue', () => { describe('glass-part-question.vue', () => {
test('Part data passed in, should map data for ButtonQuestion (radio type)', async () => { test('Part data passed in, should map data for ButtonQuestion (radio type)', async () => {
// Arrange // Arrange
@ -31,7 +59,7 @@ describe('glass-part-question.vue', () => {
// Act // Act
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
console.log(wrapper.vm.featureListData['Green Tint'][0].Text); window.console.log(wrapper.vm.featureListData['Green Tint'][0].Text);
// Assert // Assert
expect(Object.keys(wrapper.vm.featureListData).length).toBe(2); expect(Object.keys(wrapper.vm.featureListData).length).toBe(2);
expect(wrapper.vm.featureListData['Green Tint'][0].Text).toBe('heated glass, solar, 1 hole'); expect(wrapper.vm.featureListData['Green Tint'][0].Text).toBe('heated glass, solar, 1 hole');
@ -157,7 +185,8 @@ describe('glass-part-question.vue', () => {
['Driver', 'Quarter', 'Green Tint', []] ['Driver', 'Quarter', 'Green Tint', []]
]; ];
test.each(partsForSelectedTintTestCases)('partsForSelectedTint returns correct parts', test.each(partsForSelectedTintTestCases)(
'partsForSelectedTint returns correct parts',
async (glassLocation, glassName, selectedTint, expectedResults) => { async (glassLocation, glassName, selectedTint, expectedResults) => {
// Arrange // Arrange
const pageData = { partsOrQuestions: [ const pageData = { partsOrQuestions: [
@ -195,32 +224,6 @@ describe('glass-part-question.vue', () => {
// Assert // Assert
expect(expectedResults).toEqual(wrapper.vm.partsForSelectedTint); expect(expectedResults).toEqual(wrapper.vm.partsForSelectedTint);
});
});
function setupMocks({ glassNameProp, glassLocationProp, colorAnswersProp, modelValueProp, pageData }) {
const mountOptions = getMountOptions({
route: {
query: {
issPage: 'vehicle-parts'
}
} }
}); );
});
mountOptions.propsData = {
glassName: glassNameProp,
glassLocation: glassLocationProp,
colorAnswers: colorAnswersProp,
modelValue: modelValueProp
};
const wrapper = shallowMount(glassPartQuestion, mountOptions);
// Mock store
const partsOrQuestions = pageData ?? { partsOrQuestions: [{ glassName: 'Stationary', glassLocation: 'Rear', parts: [] }] };
useMainStore().pageData = jest.fn();
useMainStore().pageData.mockReturnValue(partsOrQuestions);
document.querySelector = jest.fn().mockReturnValue({ clicked: false, click: jest.fn() });
return { wrapper };
}

View file

@ -43,7 +43,7 @@
<script> <script>
// Components // Components
import buttonQuestion from '@/digital-components/button-question/button-question'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
// Supporting files // Supporting files
import getTintImage from '@/constants/tint-mapper'; import getTintImage from '@/constants/tint-mapper';
@ -91,8 +91,10 @@ export default {
return validationRuleName; return validationRuleName;
}, },
colorQuestionText() { colorQuestionText() {
return getCustomTransformValue(this.glassColorQuestion, return getCustomTransformValue(
`${this.glassLocation} ${this.glassName}`); this.glassColorQuestion,
`${this.glassLocation} ${this.glassName}`
);
}, },
tintSelectionOptions() { tintSelectionOptions() {
@ -102,8 +104,7 @@ export default {
tintOptions.push({ tintOptions.push({
value: tintOption, value: tintOption,
buttonLabel: tintOption, buttonLabel: tintOption,
buttonImage: require(`@/assets/img/tints/${this.getTintSourceImage(this.glassLocation, buttonImage: require(`@/assets/img/tints/${this.getTintSourceImage(this.glassLocation, tintOption)}`)
tintOption)}`)
}); });
}); });

View file

@ -1,22 +1,20 @@
// Components // Components
import vehicleParts from '@/layouts/vehicle-parts/vehicle-parts'; import vehicleParts from '@/layouts/vehicle-parts/vehicle-parts.vue';
import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question'; import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue';
// Supporting Files // Supporting Files
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 { 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 { nextTick } from 'vue'; import { nextTick } from 'vue';
import baseMixin from '@/mixins/base-mixin.js'; import baseMixin from '@/mixins/base-mixin.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';
import applicationConfig from '@/constants/application-config'; import applicationConfig from '@/constants/application-config';
// Mock our module for promises. // Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({ jest.mock('@/helpers/layout-helper.js', () => jest.fn());
settleAllPromises: jest.fn()
}));
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
@ -58,6 +56,50 @@ const basePartResponse = {
] ]
}; };
/** @ignore */
function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) {
// Mock api responses
const apiResponses = {
cmsContent: {
SiteSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
GenericVehicleImage:
`${applicationConfig.ISS_DEV_CMS_DOMAIN}/images/default-source/default-album/blurred-image.jpg`
},
FunnelHeaderWidget: {
LogoImage:
`${applicationConfig.ISS_DEV_CMS_DOMAIN}/images/default-source/default-album/logos/insuranceLogo.jpg`
},
ColorQuestionWidget: 'Please choose your rear window tint color',
FeatureQuestionWidget: 'Ok no choose features',
AlertWidget: {
BodyText: 'Please choose your tint color',
HeadlineText: 'Just a few more steps to go'
}
}
};
const store = useMainStore();
const actionResult = [];
store.getCapabilityQuestions.mockImplementation(() => Promise.resolve({ data: actionResult }));
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(vehicleParts, mountOptions);
const partQuestionRearWrapper = wrapper.findComponent({ name: 'glassPartQuestion' });
partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
return { wrapper, apiPromise };
}
describe('vehicle-parts.vue', () => { describe('vehicle-parts.vue', () => {
test('Set cms content called on load', async () => { test('Set cms content called on load', async () => {
// Arrange // Arrange
@ -82,10 +124,12 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
wrapper.vm.setCmsContent = jest.fn(); wrapper.vm.setCmsContent = jest.fn();
// Assert // Assert
@ -115,10 +159,12 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
await nextTick(); await nextTick();
@ -147,10 +193,12 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
await nextTick(); await nextTick();
@ -183,16 +231,20 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
wrapper.vm.navigateBack(); wrapper.vm.navigateBack();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
wrapper.vm.$route); navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
wrapper.vm.$route
);
}); });
test('User did not have part questions > navigateBack triggers a router.navigate change with correct scenario', async () => { test('User did not have part questions > navigateBack triggers a router.navigate change with correct scenario', async () => {
@ -211,16 +263,20 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
wrapper.vm.navigateBack(); wrapper.vm.navigateBack();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
wrapper.vm.$route); navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
wrapper.vm.$route
);
}); });
test('ForwardButtonAction triggers a router.navigate change if there are child part questions', async () => { test('ForwardButtonAction triggers a router.navigate change if there are child part questions', async () => {
@ -286,16 +342,25 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith('CLICKED_FORWARD_WITH_MOLDING_QUESTIONS', { query: { issPage: 'vehicle-parts' } }, {}, {}, expect.anything()); expect(wrapper.vm.$router.navigate)
.toHaveBeenCalledWith(
'CLICKED_FORWARD_WITH_MOLDING_QUESTIONS',
{ query: { issPage: 'vehicle-parts' } },
{},
{},
expect.anything()
);
}); });
test('ForwardButtonAction triggers a router.navigate change if there are capability questions', async () => { test('ForwardButtonAction triggers a router.navigate change if there are capability questions', async () => {
@ -347,58 +412,23 @@ describe('vehicle-parts.vue', () => {
}); });
// Act // Act
vehicleParts.beforeRouteEnter.call(wrapper.vm, vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } }, { query: { issPage: 'vehicle-parts' } },
undefined, undefined,
(c) => c(wrapper.vm)); (c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith('CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS', { query: { issPage: 'vehicle-parts' } }, {}, {}, expect.anything()); expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
'CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS',
{ query: { issPage: 'vehicle-parts' } },
{},
{},
expect.anything()
);
}); });
}); });
function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) {
// Mock api responses
const apiResponses = {
cmsContent: {
SiteSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
GenericVehicleImage:
`${applicationConfig.ISS_DEV_CMS_DOMAIN}/images/default-source/default-album/blurred-image.jpg`
},
FunnelHeaderWidget: {
LogoImage:
`${applicationConfig.ISS_DEV_CMS_DOMAIN}/images/default-source/default-album/logos/insuranceLogo.jpg`
},
ColorQuestionWidget: 'Please choose your rear window tint color',
FeatureQuestionWidget: 'Ok no choose features',
AlertWidget: {
BodyText: 'Please choose your tint color',
HeadlineText: 'Just a few more steps to go'
}
}
};
const store = useMainStore();
const actionResult = [];
store.getCapabilityQuestions.mockImplementation(() => Promise.resolve({ data: actionResult }));
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(vehicleParts, mountOptions);
const partQuestionRearWrapper = wrapper.findComponent({ name: 'glassPartQuestion' });
partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
return { wrapper, apiPromise };
}

View file

@ -2,7 +2,7 @@
<Form <Form
ref="theForm" ref="theForm"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -72,11 +72,12 @@ import alert from '@/ux-components/alert/alert.vue';
// Supporting Files // Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import issPageValues from '@/router/router-constants/issPage-values'; import issPageValues from '@/router/router-constants/issPage-values';
import { Form } from 'vee-validate'; import { Form } from 'vee-validate';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin'; import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
export default { export default {
name: 'vehicle-parts', name: 'vehicle-parts',
@ -178,16 +179,18 @@ export default {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
// Check if isRepair is populated and if the pageData we need is here (Parts data) // Check if isRepair is populated and if the pageData we need is here (Parts data)
return ( return (
this.mainStore.damage.isRepair != null useMainStore().damage.isRepair != null
&& this.mainStore.pageData(issPageValues.VEHICLE_PARTS) && useMainStore().pageData(issPageValues.VEHICLE_PARTS)
&& Object.keys(this.mainStore.pageData(issPageValues.VEHICLE_PARTS)).length !== 0 && Object.keys(useMainStore().pageData(issPageValues.VEHICLE_PARTS)).length !== 0
); );
}, },
async forwardButtonAction() { async forwardButtonAction() {
const matchedParts = []; const matchedParts = [];
// Match them to the parts from the API. // Match them to the parts from the API.
// eslint-disable-next-line no-restricted-syntax
for (const [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) { for (const [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) {
// eslint-disable-next-line no-restricted-syntax
for (const [partKey, partValue] of Object.entries(value.parts)) { for (const [partKey, partValue] of Object.entries(value.parts)) {
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey]; const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
@ -213,10 +216,9 @@ export default {
LoadInitialPartsData() { LoadInitialPartsData() {
const partsData = this.PartsFromApi; const partsData = this.PartsFromApi;
this.alreadyPopulatedPartsData this.alreadyPopulatedPartsData = this.mainStore.lineItems.glassParts === null
= this.mainStore.lineItems.glassParts === null ? []
? [] : this.mainStore.lineItems.glassParts;
: this.mainStore.lineItems.glassParts;
partsData.partsOrQuestions.map((g) => { partsData.partsOrQuestions.map((g) => {
// If the part is already populated, use the value from the store and populate the v-model. // If the part is already populated, use the value from the store and populate the v-model.

View file

@ -9,7 +9,7 @@
<script> <script>
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question'; import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question.vue';
export default { export default {
name: 'vehicle-question', name: 'vehicle-question',

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles position-relative"> <div class="page-container-grouped-styles position-relative">
<div class="fade-on-route-transition position-relative"> <div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" /> <siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -63,7 +63,7 @@
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" /> @backClicked="backButtonAction" />
</div> </div>
</div> </div>
</div> </div>
@ -76,17 +76,17 @@
<script> <script>
// Components // Components
import siteHeader from '@/iss-components/site-header/site-header'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer'; import siteFooter from '@/iss-components/site-footer/site-footer.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner'; import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
import vehicleQuestion from '@/layouts/vehicle-selection/vehicle-question/vehicle-question'; import vehicleQuestion from '@/layouts/vehicle-selection/vehicle-question/vehicle-question.vue';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
// Supporting files // Supporting files
import baseFormMixin from '@/mixins/base-form-mixin.js'; import baseFormMixin from '@/mixins/base-form-mixin.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import { Form, defineRule } from 'vee-validate'; import { Form, defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules'; import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
@ -190,21 +190,23 @@ export default {
navigateForward() { navigateForward() {
this.mainStore.setVehicle().then(() => { this.mainStore.setVehicle().then(() => {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$router.navigate(
this.$route); this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}); });
}, },
async updateYearValues() { async updateYearValues() {
return await useMainStore().getVehicleYears(); return useMainStore().getVehicleYears();
}, },
async updateMakeValues() { async updateMakeValues() {
return await this.mainStore.getVehicleMakes(); return this.mainStore.getVehicleMakes();
}, },
async updateModelValues() { async updateModelValues() {
return await this.mainStore.getVehicleModels(); return this.mainStore.getVehicleModels();
}, },
async updateStyleValues() { async updateStyleValues() {
return await this.mainStore.getVehicleStyles(); return this.mainStore.getVehicleStyles();
} }
} }
}; };

View file

@ -26,7 +26,7 @@
</div> </div>
</template> </template>
<script> <script>
import textLink from '@/ux-components/text-link/text-link'; import textLink from '@/ux-components/text-link/text-link.vue';
export default { export default {
name: 'vin-location-information', name: 'vin-location-information',

View file

@ -7,7 +7,7 @@
aria-label="perfect-match-alert" /> aria-label="perfect-match-alert" />
</template> </template>
<script> <script>
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
import { getDamageString } from '@/helpers/damage-helper'; import { getDamageString } from '@/helpers/damage-helper';
export default { export default {

View file

@ -9,7 +9,7 @@
<script> <script>
import { getDamageString } from '@/helpers/damage-helper'; import { getDamageString } from '@/helpers/damage-helper';
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
export default { export default {
name: 'two-identical-ymm-vehicle-alert', name: 'two-identical-ymm-vehicle-alert',

View file

@ -6,7 +6,7 @@
aria-label="vehicle-not-found-alert" /> aria-label="vehicle-not-found-alert" />
</template> </template>
<script> <script>
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
export default { export default {
name: 'vehicle-not-found-alert', name: 'vehicle-not-found-alert',

View file

@ -9,7 +9,7 @@
<script> <script>
import { getDamageString } from '@/helpers/damage-helper'; import { getDamageString } from '@/helpers/damage-helper';
import alert from '@/ux-components/alert/alert'; import alert from '@/ux-components/alert/alert.vue';
export default { export default {
name: 'vehicle-not-matched-alert', name: 'vehicle-not-matched-alert',

View file

@ -4,7 +4,7 @@ import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
import { RouterLinkStub } from '@vue/test-utils'; import { RouterLinkStub } from '@vue/test-utils';
import { render } from '@testing-library/vue'; import { render } from '@testing-library/vue';
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import VinLookupAlertsComponent from '@/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts'; import VinLookupAlertsComponent from '@/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.vue';
jest.mock('@/helpers/damage-helper'); jest.mock('@/helpers/damage-helper');

View file

@ -14,11 +14,11 @@
</template> </template>
<script> <script>
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types'; import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
import vehicleNotFoundAlert from '@/layouts/vin-lookup/vin-lookup-alerts/vehicle-not-found-alert/vehicle-not-found-alert'; import vehicleNotFoundAlert from '@/layouts/vin-lookup/vin-lookup-alerts/vehicle-not-found-alert/vehicle-not-found-alert.vue';
import vehicleNotMatchedAlert from '@/layouts/vin-lookup/vin-lookup-alerts/vehicle-not-matched-alert/vehicle-not-matched-alert'; import vehicleNotMatchedAlert from '@/layouts/vin-lookup/vin-lookup-alerts/vehicle-not-matched-alert/vehicle-not-matched-alert.vue';
import twoIdenticalYMMVehicleAlert from import twoIdenticalYMMVehicleAlert from
'@/layouts/vin-lookup/vin-lookup-alerts/two-identical-ymm-vehicle-alert/two-identical-ymm-vehicle-alert'; '@/layouts/vin-lookup/vin-lookup-alerts/two-identical-ymm-vehicle-alert/two-identical-ymm-vehicle-alert.vue';
import perfectMatchAlert from '@/layouts/vin-lookup/vin-lookup-alerts//perfect-match-alert/perfect-match-alert'; import perfectMatchAlert from '@/layouts/vin-lookup/vin-lookup-alerts//perfect-match-alert/perfect-match-alert.vue';
export default { export default {
name: 'vin-lookup-alerts', name: 'vin-lookup-alerts',

View file

@ -8,7 +8,7 @@ import errorMessages from '@/constants/error-messages';
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 { navigationScenarios } from '@/router/router-constants/navigation-scenarios'; import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import VinLookupComponent from '@/layouts/vin-lookup/vin-lookup.vue'; import VinLookupComponent from '@/layouts/vin-lookup/vin-lookup.vue';
@ -278,6 +278,7 @@ describe('vin-lookup.vue', () => {
expect(mockRouter.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, mockRoute); expect(mockRouter.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, mockRoute);
}); });
// eslint-disable-next-line max-len
test('Different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page.', async () => { test('Different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page.', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false; mountOptions.global.stubs.vinQuestion = false;
@ -315,6 +316,7 @@ describe('vin-lookup.vue', () => {
}); });
describe('Succesful navigateForward', () => { describe('Succesful navigateForward', () => {
// eslint-disable-next-line max-len
test('Vehicle with Part Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_PART_QUESTIONS', async () => { test('Vehicle with Part Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_PART_QUESTIONS', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false; mountOptions.global.stubs.vinQuestion = false;
@ -346,6 +348,7 @@ describe('vin-lookup.vue', () => {
}); });
}); });
// eslint-disable-next-line max-len
test('Vehicle with Multiple Parts. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE', async () => { test('Vehicle with Multiple Parts. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false; mountOptions.global.stubs.vinQuestion = false;
@ -377,6 +380,7 @@ describe('vin-lookup.vue', () => {
}); });
}); });
// eslint-disable-next-line max-len
test('Vehicle with Molding Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS', async () => { test('Vehicle with Molding Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false; mountOptions.global.stubs.vinQuestion = false;
@ -408,6 +412,7 @@ describe('vin-lookup.vue', () => {
}); });
}); });
// eslint-disable-next-line max-len
test('Vehicle with Capability Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS', async () => { test('Vehicle with Capability Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
const store = useMainStore(); const store = useMainStore();
@ -442,6 +447,7 @@ describe('vin-lookup.vue', () => {
}); });
}); });
// eslint-disable-next-line max-len
test('Vehicle no additional Parts or Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS', async () => { test('Vehicle no additional Parts or Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false; mountOptions.global.stubs.vinQuestion = false;
@ -470,34 +476,6 @@ describe('vin-lookup.vue', () => {
); );
}); });
}); });
test('Selected vehicle VIN do not match vehicles (CarIDs) in our system then navigate forward to bailout page.', async () => {
//Arrange
const user = userEvent.setup();
lookupVehicleByVin.mockResponse.data.error = true;
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
.mockResolvedValue(lookupVehicleByVinError.mockResponse);
mountOptions.data = () => ({
needToLookupVehicle: true,
bailout: true,
vin: mockValidVin
});
const { container } = render(VinLookupComponent, mountOptions);
const continueButton = container.querySelector(continueButtonQuerySelector);
await user.click(continueButton);
await flushPromises();
await waitFor(() => {
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
expect(mockRouter.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
mockRoute
);
});
});
}); });
}); });
}); });

View file

@ -3,7 +3,7 @@
ref="theForm" ref="theForm"
v-slot="{ meta }" v-slot="{ meta }"
@submit="onSubmit" @submit="onSubmit"
@invalid-submit="onInvalidSubmit"> @invalidSubmit="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" />
@ -48,7 +48,7 @@ import { computed } from 'vue';
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types'; import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { isGlassAvailableForCarId } from '@/helpers/damage-helper'; import { isGlassAvailableForCarId } from '@/helpers/damage-helper';
import { settleAllPromises } from '@/helpers/layout-helper'; import settleAllPromises from '@/helpers/layout-helper';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
@ -112,8 +112,7 @@ export default {
vehicleFromLookup: null, vehicleFromLookup: null,
vin: this.getVinFromStore(), vin: this.getVinFromStore(),
forwardButtonCarStyle: '', forwardButtonCarStyle: '',
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0, vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0
bailout: false
}; };
}, },
computed: { computed: {
@ -130,6 +129,7 @@ export default {
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase()); return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
}, },
vinMask() { vinMask() {
// TODO: Side effects in computed.
if (this.vinPopulatedOnPageLoad) { if (this.vinPopulatedOnPageLoad) {
// TODO: Modify to remove side effects in computed // TODO: Modify to remove side effects in computed
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.PERFECT_MATCH; this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.PERFECT_MATCH;
@ -178,13 +178,8 @@ export default {
// because the form itself actually passes its client-side validation. // because the form itself actually passes its client-side validation.
// SSR-189 Scenario #4. // SSR-189 Scenario #4.
this.$refs.siteFooter.enableForwardAction(); this.$refs.siteFooter.enableForwardAction();
this.bailout = true;
} }
if (this.bailout) {
return this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
this.$route);
}
// Add vin bcs the response from the service doesn't contain vin // Add vin bcs the response from the service doesn't contain vin
this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { vin: this.vin }); this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { vin: this.vin });
} }
@ -217,10 +212,12 @@ export default {
if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) { if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) {
this.mainStore.updateVehicle(this.vehicleFromLookup); this.mainStore.updateVehicle(this.vehicleFromLookup);
this.mainStore.resetDamageState(); this.mainStore.resetDamageState();
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, this.$router.navigate(
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route, this.$route,
{}, {},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }); { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
// navigate() doesn't stop the processing flow // navigate() doesn't stop the processing flow
return null; return null;
@ -241,6 +238,8 @@ export default {
// Comes from vehicleQuestionsMixin.navigateForward() // Comes from vehicleQuestionsMixin.navigateForward()
await this.navigateForward(partsOrQuestionsResponse.data.partsOrQuestions, this); await this.navigateForward(partsOrQuestionsResponse.data.partsOrQuestions, this);
return null;
}, },
async getPartsOrQuestions() { async getPartsOrQuestions() {
try { try {

View file

@ -16,7 +16,7 @@ import { regex, required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages'; import errorMessages from '@/constants/error-messages';
// Import Component(s) // Import Component(s)
import textboxQuestion from '@/digital-components/textbox-question/textbox-question'; import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
defineRule('vin-required', required(errorMessages.VIN_REQUIRED)); defineRule('vin-required', required(errorMessages.VIN_REQUIRED));
defineRule('vin-format', regex(/^[a-hA-Hj-nJ-NpPr-zR-Z0-9]{17}$/, errorMessages.VIN_FORMAT)); defineRule('vin-format', regex(/^[a-hA-Hj-nJ-NpPr-zR-Z0-9]{17}$/, errorMessages.VIN_FORMAT));

Some files were not shown because too many files have changed in this diff Show more