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

View file

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

View file

@ -129,6 +129,10 @@ const endpoints = Object.freeze({
RegisterClaim: {
url: '/coverage/api/v1/coverage/register-claim',
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',
VIN_REQUIRED: 'Please enter your VIN',
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',
OPTION_REQUIRED: 'Please select an option',
VEHICLE_REQUIRED: 'Please select a vehicle',

View file

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

View file

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

View file

@ -79,14 +79,19 @@ export default {
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 {
errorMessage,
handleBlur,
handleChange,
meta,
errors
errors,
setErrors
};
},
computed: {
@ -123,6 +128,11 @@ export default {
}
},
watch: {
isDisabled(newValue, oldValue) {
if (newValue !== oldValue) {
this.setErrors([]);
}
},
selectedOption(newValue) {
this.handleChange(newValue);
}

View file

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

View file

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

View file

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

View file

@ -7,10 +7,54 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
jest.mock('axios');
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', () => {
// Arrange
const endpoint = 'https://mock.safelite.com';
const httpArgs = setupMocksForHttpClient({ endpoint: endpoint });
const httpArgs = setupMocksForHttpClient({ endpoint });
// Act
globalMethods.callHttpClient(httpArgs).then((response) => {
@ -25,7 +69,7 @@ it('Global Methods - Call Http Client - Should Reject Promise', () => {
// Arrange
const endpoint = 'https://mock.safelite.com';
const httpArgs = setupMocksForHttpClient({
endpoint: endpoint,
endpoint,
isError: true
});
analyticsMixIn.methods.pushEventToGA = jest.fn();
@ -38,46 +82,3 @@ it('Global Methods - Call Http Client - Should Reject Promise', () => {
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();
return store.validateClientTag(clientTag)
.then((response) =>
// Success
response,
// Error
() => null);
.then(
(response) => response,
() => null
);
};
export default validateISSClientTag;

View file

@ -55,8 +55,11 @@ export function getCookieDomainValue() {
Used to create a cookie.
`useDefaultISSCookieAttributes` will set the path and domain to our defaults
*/
function createOrUpdateCookie(key, value = '',
{ useDefaultISSCookieAttributes = true, maxAge, isSecure = true }) {
function createOrUpdateCookie(
key,
value = '',
{ useDefaultISSCookieAttributes = true, maxAge, isSecure = true }
) {
let cookieToAdd = `${key}=${value}; `;
if (useDefaultISSCookieAttributes) {
@ -122,7 +125,8 @@ export function updateOrCreateISSCookie() {
ReferralNumber: store.order.referralNumber,
ReferralDate: store.order.referralDate,
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 });
}
export function setCookieProperties(properties,
{ useDefaultISSCookieAttributes = true, maxAge, isSecure }) {
export function setCookieProperties(
properties,
{ useDefaultISSCookieAttributes = true, maxAge, isSecure }
) {
if (typeof properties === 'object') {
Object.keys(properties).forEach((key) => {
createOrUpdateCookie(key, properties[key], {

View file

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

View file

@ -9,10 +9,14 @@ import { required, regex } from '@/helpers/validation-rules';
function defineGlobalNameRules() {
defineRule(globalRules.FIRST_NAME_REQUIRED, required(errorMessages.FIRST_NAME_REQUIRED));
defineRule(globalRules.LAST_NAME_REQUIRED, required(errorMessages.LAST_NAME_REQUIRED));
defineRule(globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
required(errorMessages.POLICYHOLDER_FIRST_NAME_REQUIRED));
defineRule(globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
required(errorMessages.POLICYHOLDER_LAST_NAME_REQUIRED));
defineRule(
globalRules.POLICYHOLDER_FIRST_NAME_REQUIRED,
required(errorMessages.POLICYHOLDER_FIRST_NAME_REQUIRED)
);
defineRule(
globalRules.POLICYHOLDER_LAST_NAME_REQUIRED,
required(errorMessages.POLICYHOLDER_LAST_NAME_REQUIRED)
);
}
/**
@ -20,9 +24,13 @@ function defineGlobalNameRules() {
*/
function defineGlobalEmailRules() {
defineRule(globalRules.EMAIL_ADDRESS_REQUIRED, required(errorMessages.EMAIL_ADDRESS_REQUIRED));
defineRule(globalRules.EMAIL_ADDRESS_FORMAT,
regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT));
defineRule(
globalRules.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() {
defineRule(globalRules.PHONE_NUMBER_REQUIRED, required(errorMessages.PHONE_NUMBER_REQUIRED));
defineRule(globalRules.PHONE_NUMBER_FORMAT,
regex(/^(\([0-9]{3}\)|[0-9]{3}) *[-.]? *[0-9]{3} *[-.]? *[0-9]{4}$/,
errorMessages.PHONE_NUMBER_FORMAT));
defineRule(
globalRules.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'
const promiseNames = Object.entries(promiseResultMap);
@ -22,4 +22,6 @@ export function settleAllPromises(promiseResultMap) {
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', () => {
// 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';
export async function getServiceabilityDetails(serviceZipCode, lineItems) {
const serviceabilityDetails = await useMainStore().getServiceabilityDetails({
serviceZipCode,
lineItems
},
false);
const serviceabilityDetails = await useMainStore().getServiceabilityDetails(
{
serviceZipCode,
lineItems
},
false
);
return Promise.resolve(serviceabilityDetails);
}

View file

@ -1,6 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */
import { RouterLinkStub } from '@vue/test-utils';
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 issPageValues from '@/router/router-constants/issPage-values';
import cookieNames from '@/constants/cookie-names';
@ -59,7 +60,9 @@ export function getMountOptions(mockData) {
// Heritage integration common methods
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',
anotherCookie: '{}',
someOtherCookie: '{}',

View file

@ -311,7 +311,8 @@ describe('address-questions.vue', () => {
describe('alerts', () => {
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) => {
// Arrange
const { wrapper } = setupMocks({});
@ -336,7 +337,8 @@ describe('address-questions.vue', () => {
const noMatchAlert = wrapper.findComponent({ ref: 'alertNoMatchWarning' });
expect(noMatchAlert.exists()).toBe(false);
});
}
);
test('user enters address that yields no autocomplete results => show noMatch alert', async () => {
// Arrange

View file

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

View file

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

View file

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

View file

@ -57,8 +57,10 @@ export default {
return this.getCmsContent(this.cmsWidgetName, this.contentProperty ?? 'SubHeaderText');
},
subText() {
let subTextFromCms = this.getCmsContent(this.cmsWidgetName,
this.subContentProperty ?? 'SecondaryText');
let subTextFromCms = this.getCmsContent(
this.cmsWidgetName,
this.subContentProperty ?? 'SecondaryText'
);
if (this.stripRteStyle) {
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';
// Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
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', () => ({
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
@ -14,9 +14,7 @@ jest.mock('@/helpers/damage-helper', () => ({
}));
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
/** @ignore */
function setupMocks({
@ -47,7 +45,8 @@ function setupMocks({
}
}));
const wrapper = shallowMount(addressLookup,
const wrapper = shallowMount(
addressLookup,
getMountOptions({
route: route || undefined,
router: {
@ -71,7 +70,8 @@ function setupMocks({
}
}
}));
})
);
const apiResponses = {
vinLookupResponse: {
@ -348,11 +348,13 @@ describe('address-lookup.vue', () => {
await wrapper.vm.forwardButtonAction();
// 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,
{},
{},
carsFound);
carsFound
);
});
// eslint-disable-next-line max-len
@ -393,11 +395,14 @@ describe('address-lookup.vue', () => {
await wrapper.vm.navigateForward(carsFound);
// 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,
{},
{ displayVehicleChangeAlert: true });
});
{ displayVehicleChangeAlert: true }
);
}
);
test('single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => {
// Arrange

View file

@ -87,12 +87,12 @@ import { Form } from 'vee-validate';
// Supporting files
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 { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper';
import vinPagesMixin from '@/mixins/vin-pages-mixin';
import { useMainStore } from '@/store';
import { useMainStore } from '@/store/index.js';
export default {
name: 'address-lookup',
@ -142,15 +142,17 @@ export default {
},
computed: {
AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget',
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
return this.getCmsContent(
'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
AlertMatchedDifferentVehicleBody() {
const vinYmmFound =
// eslint-disable-next-line max-len
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
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')
.replaceAll('{custom:damage}', getDamageString())
@ -158,8 +160,10 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
},
AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
return this.getCmsContent(
'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound =
@ -167,7 +171,7 @@ export default {
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
const vinYmmsExpected =
// 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')
.replaceAll('{custom:damage}', getDamageString())
@ -179,7 +183,7 @@ export default {
// eslint-disable-next-line max-len
`${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
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());
}
},
@ -199,7 +203,7 @@ export default {
},
methods: {
arePagePrerequisitesValid() {
return this.mainStore.order.vehicle.carId !== null;
return useMainStore().order.vehicle.carId !== null;
},
backButtonAction() {
@ -208,10 +212,12 @@ export default {
},
attachCustomEvents() {
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.GaLabels.ADDRESS_LOOKUP,
true);
true
);
});
},
@ -277,7 +283,7 @@ export default {
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
} 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
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) {
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {
@ -292,22 +298,24 @@ export default {
}
// Save vehicle, customer, service and registration information
await useMainStore().saveRegistrationAddressLookup({
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo:
Object.keys(vehicleInfoToCommit).length === 0
? null
: vehicleInfoToCommit,
registrationInfo: {
firstName: this.customerQuestions.firstName,
lastName: this.customerQuestions.lastName,
address: this.customerQuestions.addressQuestions.streetAddress,
city: this.customerQuestions.addressQuestions.city,
state: this.customerQuestions.addressQuestions.state,
zipCode: this.customerQuestions.addressQuestions.zipCode
}
},
false);
await useMainStore().saveRegistrationAddressLookup(
{
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo:
Object.keys(vehicleInfoToCommit).length === 0
? null
: vehicleInfoToCommit,
registrationInfo: {
firstName: this.customerQuestions.firstName,
lastName: this.customerQuestions.lastName,
address: this.customerQuestions.addressQuestions.streetAddress,
city: this.customerQuestions.addressQuestions.city,
state: this.customerQuestions.addressQuestions.state,
zipCode: this.customerQuestions.addressQuestions.zipCode
}
},
false
);
return this.navigateForward(carsFound);
},
@ -322,18 +330,22 @@ export default {
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,
{},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else if (matchingCars.length === 1) {
await this.navigateForwardWithSingleCarMatch();
} else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
this.$route,
{},
{},
carsFound);
carsFound
);
}
},
resetWarningsAndErrors() {

View file

@ -58,8 +58,10 @@ export default {
emits: ['update: modelValue'],
computed: {
differentVehicleAlertHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'HeadlineText').replaceAll('{custom:damage}',
getDamageString());
return this.getCmsContent(
'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
differentVehicleAlertBody() {
const vinYmmFound =
@ -73,11 +75,14 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
},
AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
return this.getCmsContent(
'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound =
// eslint-disable-next-line max-len
`${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model} ${this.selectedVehicle?.vehicle.style}`;
const vinYmmsExpected =
`${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 { settleAllPromises } from '@/helpers/layout-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { useMainStore } from '@/store';
@ -21,9 +21,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({
}));
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
function setupMocks({
route = null,
@ -209,7 +207,8 @@ describe('address-vehicles.vue', () => {
// Assert
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 () => {
// Arrange
@ -233,10 +232,12 @@ describe('address-vehicles.vue', () => {
useMainStore().order.vehicle.carId = 'CR00000395';
// Act
addressVehicles.beforeRouteEnter.call(wrapper.vm,
addressVehicles.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'address-vehicles' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();

View file

@ -65,7 +65,7 @@
<script>
// Import Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import issPageValues from '@/router/router-constants/issPage-values';
import errorMessages from '@/constants/error-messages';
@ -148,8 +148,10 @@ export default {
return this.VehiclesForQuestions.length;
},
AlertFoundMultipleVehiclesHeader() {
return this.getCmsContent('FoundMultipleVehicles',
'HeadlineText').replaceAll('{custom:vehicleCount}', this.vehicleCount);
return this.getCmsContent(
'FoundMultipleVehicles',
'HeadlineText'
).replaceAll('{custom:vehicleCount}', this.vehicleCount);
},
isTwoIdenticalYMMVehicleFound() {
const vinYmmFound =
@ -224,7 +226,7 @@ export default {
getRouterLinkRouteFromCopy,
getRouterLinkDisplayTextFromCopy,
arePagePrerequisitesValid() {
if (this.mainStore.order.vehicle.carId) {
if (useMainStore().order.vehicle.carId) {
return true;
}
return false;
@ -242,14 +244,16 @@ export default {
return;
}
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
await useMainStore().saveVin({
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
vin: this.selectedVehicle.vin
}),
isSelectedGlassAvailableForVehicle:
this.isSelectedGlassAvailableForVehicle
},
false);
await useMainStore().saveVin(
{
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
vin: this.selectedVehicle.vin
}),
isSelectedGlassAvailableForVehicle:
this.isSelectedGlassAvailableForVehicle
},
false
);
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
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
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,
{},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else {
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 { Form } from 'vee-validate';
import globalRules from '@/constants/global-rules';
import { settleAllPromises } from '@/helpers/layout-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
export default {
@ -134,11 +134,13 @@ export default {
return this.navigateForward();
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route,
{},
{},
this.bailoutPageModel);
this.bailoutPageModel
);
},
getBailoutPageModelFromStore() {
return {

View file

@ -21,7 +21,7 @@
<script>
// Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper';
import settleAllPromises from '@/helpers/layout-helper';
// Import Component
import baseFormMixin from '@/mixins/base-form-mixin';
@ -101,17 +101,21 @@ export default {
glass.answerKey = `${glass.glassLocation}-${glass.glassName}`;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(glass,
const updatedGlass = this.setupInitialData(
glass,
index,
alreadyAnsweredQuestions);
alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions
this.$watch(`selectedAnswers.${glass.answerKey}`,
this.$watch(
`selectedAnswers.${glass.answerKey}`,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true });
{ deep: true }
);
return updatedGlass;
});
},

View file

@ -16,7 +16,7 @@ import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'
// Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
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';
export default {

View file

@ -6,7 +6,7 @@ import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { getRandomString, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js';
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';
describe('contactDetails.vue', () => {

View file

@ -205,8 +205,10 @@ export default {
notesForTechnician: this.notesForTechnician
};
useMainStore().updateContactInfo(contactInfo);
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
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 { getMountOptions } from '@/helpers/unit-test-helper.js';
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 { settleAllPromises } from '@/helpers/layout-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import routerParams from '@/router/router-constants/router-params';
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
jest.mock('@/helpers/cms-content-helper', () => ({
fetchCmsContentForPage: jest.fn(),
@ -459,7 +458,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {
// Arrange
@ -495,7 +498,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {
// Arrange
@ -532,7 +539,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {
// Arrange
@ -572,7 +583,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {
// Arrange
@ -612,7 +627,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {
// Arrange
@ -638,7 +657,11 @@ describe('coverageStatement.vue', () => {
// Assert
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', () => {

View file

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

View file

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

View file

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

View file

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

View file

@ -78,7 +78,7 @@
<script>
// Import Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import errorMessages from '@/constants/error-messages';
import { required } from '@/helpers/validation-rules';
@ -154,8 +154,10 @@ export default {
},
computed: {
AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent('AlertMatchedDifferentVehicleWidget',
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
return this.getCmsContent(
'AlertMatchedDifferentVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
AlertMatchedDifferentVehicleBody() {
const vinYmmFound =
@ -170,8 +172,10 @@ export default {
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
},
AlertMatchedTwoIdenticalYMMVehicleHeader() {
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
return this.getCmsContent(
'AlertMatchedTwoIdenticalYMMVehicleWidget',
'HeadlineText'
).replaceAll('{custom:damage}', getDamageString());
},
AlertMatchedTwoIdenticalYMMVehicleBody() {
const vinYmmsFound =
@ -214,7 +218,7 @@ export default {
},
methods: {
arePagePrerequisitesValid() {
return this.mainStore.order.vehicle.carId !== null;
return useMainStore().order.vehicle.carId !== null;
},
loadDefaultsFromStore() {
this.customerQuestions = this.mainStore.customerData.addressQuestions.state;
@ -225,10 +229,12 @@ export default {
},
attachCustomEvents() {
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.GaLabels.LICENSE_PLATE_LOOKUP,
true);
true
);
});
},
// 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
await useMainStore().saveRegistrationLicensePlateLookup({
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
registrationInfo: {
licensePlate: this.licensePlate,
state: this.licenseState
}
},
false);
await useMainStore().saveRegistrationLicensePlateLookup(
{
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
registrationInfo: {
licensePlate: this.licensePlate,
state: this.licenseState
}
},
false
);
return this.navigateForward();
},
@ -304,10 +312,12 @@ export default {
// not available for that vehicle then navigate back to "vehicle-damage"
// display vehicle changed alert on that page.
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,
{},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
} else {
await this.navigateForwardWithSingleCarMatch();
}

View file

@ -22,7 +22,7 @@
<script>
// Import Supporting Files
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 vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import { useMainStore } from '@/store';
@ -70,8 +70,10 @@ export default {
},
computed: {
AlertFewMoreQuestionsHeader() {
return this.getCmsContent('AdditionalPartsQuestionsAlert',
'HeadlineText');
return this.getCmsContent(
'AdditionalPartsQuestionsAlert',
'HeadlineText'
);
},
AlertFewMoreQuestionsCopy() {
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
@ -105,18 +107,24 @@ export default {
glass.answerKey = `${glass.glassLocation}-${glass.glassName}`;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(glass,
const updatedGlass = this.setupInitialData(
glass,
index,
alreadyAnsweredQuestions);
alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions
this.$watch(`selectedAnswers.${glass.answerKey}`,
this.$watch(
`selectedAnswers.${glass.answerKey}`,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue,
glass.answerKey);
this.handleAnswerUpdates(
newValue,
glass.answerKey
);
}
},
{ deep: true });
{ deep: true }
);
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';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
@ -63,8 +63,10 @@ export default {
return this.navigateForward();
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}
}
};

View file

@ -91,6 +91,7 @@ const baseStoreGettersPageData = () => ({
{
questionSequence: 1,
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?',
answers: [
{
@ -122,12 +123,14 @@ const baseStoreGettersDamage = () => ({
answeredQuestions: [
{
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?',
selectedAnswerText: 'Yes',
questionNum: 1
},
{
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?',
selectedAnswerText: 'Yes',
questionNum: 2

View file

@ -24,7 +24,7 @@ import questionsPageLayout from '@/iss-components/questions-page-layout/question
// Supporting Files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { settleAllPromises } from '@/helpers/layout-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store';
import issPageValues from '@/router/router-constants/issPage-values';
import { Form } from 'vee-validate';
@ -96,13 +96,15 @@ export default {
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
// Set up watch for each set of glass questions
this.$watch(`selectedAnswers.${glass.answerKey}`,
this.$watch(
`selectedAnswers.${glass.answerKey}`,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true });
{ deep: true }
);
return updatedGlass;
});

View file

@ -27,7 +27,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';

View file

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

View file

@ -59,7 +59,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 globalRules from '@/constants/global-rules';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
@ -131,14 +131,18 @@ export default {
navigateForward() {
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.vehiclesFound);
this.vehiclesFound
);
} else {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
this.$route
);
}
},

View file

@ -1,10 +1,10 @@
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 { getMountOptions } from '@/helpers/unit-test-helper';
import { useMainStore } from '@/store';
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 { getRandomString, getRandomInt } from '@/helpers/data-generation';
import endorsementOptions from '@/constants/endorsement-options';
@ -23,9 +23,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({
}));
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
const mockMixin = {
methods: {
@ -90,7 +88,9 @@ describe('policy-vehicles.vue', () => {
describe('forwardButtonAction', () => {
// 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 () => {
// Arrange
const { wrapper } = setupMocks({});
@ -127,13 +127,17 @@ describe('policy-vehicles.vue', () => {
// Assert
expect(wrapper.vm.bailout).toBeFalsy();
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,
{},
{});
});
{}
);
}
);
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 () => {
// Arrange
const { wrapper } = setupMocks({});
@ -152,11 +156,14 @@ describe('policy-vehicles.vue', () => {
// Assert
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,
{},
{});
});
{}
);
}
);
test('vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.', async () => {
// Arrange
@ -170,10 +177,12 @@ describe('policy-vehicles.vue', () => {
await wrapper.vm.forwardButtonAction();
// 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,
{},
{});
{}
);
});
});

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,13 +1,11 @@
import { shallowMount } from '@vue/test-utils';
import { settleAllPromises } from '@/helpers/layout-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import tpaRecalModal from '@/layouts/provider-preference/tpa-recal-modal/tpa-recal-modal.vue';
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
// Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({
@ -23,8 +21,10 @@ function setupMocks() {
}
});
const wrapper = shallowMount(tpaRecalModal,
mountOptions);
const wrapper = shallowMount(
tpaRecalModal,
mountOptions
);
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';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
@ -68,8 +68,10 @@ export default {
forwardButtonAction() {
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}
}
};

View file

@ -28,7 +28,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';

View file

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

View file

@ -58,7 +58,7 @@
<script>
// Import Supporting Files
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 errorMessages from '@/constants/error-messages';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
@ -118,8 +118,7 @@ export default {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.setData(resultMap.zipCodeData,
resultMap.serviceabilityDetails);
vm.setData(resultMap.zipCodeData, resultMap.serviceabilityDetails);
});
},
setup() {
@ -170,8 +169,11 @@ export default {
}
},
methods: {
arePagePrerequisiteValid() {
return true;
arePagePrerequisitesValid() {
return (
useMainStore().lineItems.supportingItems !== null
&& useMainStore().order.serviceLocation.zipCode !== null
);
},
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)),
getZipCodeData: jest.fn((mockServiceZipCode) => mockGetZipCodeData(mockServiceZipCode))
}));
})
);
const linkWidgetName = 'linkWidgetName';
const modalWidgetName = 'modalWidgetName';

View file

@ -107,7 +107,8 @@ describe('service-package-radio.vue', () => {
const fileredResults = results.filter((result) => result.includes(' -'));
expect(fileredResults.length).toBe(0);
});
it('Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
it(
'Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ',
async () => {
// Arrange
const moddedProps = mockProps;
@ -123,5 +124,6 @@ describe('service-package-radio.vue', () => {
// Assert
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 contentGroupModal from '@/iss-components/content-group-modal/content-group-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 { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { Form } from 'vee-validate';

View file

@ -3,7 +3,7 @@
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" />
@backClicked="backButtonAction" />
</div>
</div>
</div>
@ -22,11 +22,11 @@
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header';
import siteFooter from '@/iss-components/site-footer/site-footer';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
@ -36,6 +36,7 @@ export default {
components: {
siteHeader,
siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form
},
mixins: [BaseFormMixin],
@ -70,8 +71,10 @@ export default {
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}
}
};

View file

@ -3,7 +3,7 @@
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" />
@backClicked="backButtonAction" />
</div>
</div>
</div>
@ -22,11 +22,11 @@
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header';
import siteFooter from '@/iss-components/site-footer/site-footer';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
@ -65,8 +65,10 @@ export default {
return this.navigateForward();
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}
}
};

View file

@ -3,7 +3,7 @@
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -14,7 +14,7 @@
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@back-clicked="backButtonAction" />
@backClicked="backButtonAction" />
</div>
</div>
</div>
@ -22,12 +22,12 @@
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header';
import siteFooter from '@/iss-components/site-footer/site-footer';
import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
// Supporting files
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 BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
@ -37,6 +37,7 @@ export default {
components: {
siteHeader,
siteFooter,
// eslint-disable-next-line vue/no-reserved-component-names
Form
},
mixins: [BaseFormMixin],
@ -76,8 +77,10 @@ export default {
},
navigateForward() {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
this.$route);
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
}
}
};

View file

@ -1,51 +1,8 @@
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';
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'] }
});
});
});
/** @ignore */
function setupMocks({
modelValueProp = ['Windshield', 'SideDoor'],
isMultiSelect = false,
@ -79,3 +36,49 @@ function setupMocks({
const damageOptions = dataFromStoreApi;
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>
<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 { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';

View file

@ -1,86 +1,8 @@
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';
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();
});
});
/** @ignore */
function setupMocks({
modelValueProp = ['Windshield'],
isAvailable = true,
@ -92,7 +14,7 @@ function setupMocks({
dataFromStoreApi = [],
methodsToMock = []
}) {
const mountOptions = getMountOptions({ });
const mountOptions = getMountOptions({});
// Mock props
const mockMixin = {
@ -124,3 +46,88 @@ function setupMocks({
const replaceOptions = dataFromStoreApi;
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>
<script>
import buttonQuestion from '@/digital-components/button-question/button-question';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default {
name: 'replace-options-question',

View file

@ -1,91 +1,9 @@
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 replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question';
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([]);
});
});
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
/** @ignore */
function setupMocks({
modelValueProp = ['DriverSide'],
groupName = 'sideDoorOptions',
@ -133,3 +51,91 @@ function setupMocks({
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>
<script>
import buttonQuestion from '@/digital-components/button-question/button-question';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import replaceOptionsQuestion from '@/layouts/vehicle-damage/replace-options-question/replace-options-question.vue';
import { defineRule } from 'vee-validate';
import { required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';
@ -87,9 +87,11 @@ export default {
return this.selectedValues.selectedDoorSides;
},
set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(newValue,
this.selectedValues = this.getSideDoorReplacementOptions(
newValue,
this.selectedValues.selectedDriverSideReplaceOptions,
this.selectedValues.selectedPassengerSideReplaceOptions);
this.selectedValues.selectedPassengerSideReplaceOptions
);
}
},
selectedDriverSideReplaceOptionsValues: {
@ -97,9 +99,11 @@ export default {
return this.selectedValues.selectedDriverSideReplaceOptions;
},
set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides,
this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
newValue,
this.selectedValues.selectedPassengerSideReplaceOptions);
this.selectedValues.selectedPassengerSideReplaceOptions
);
}
},
selectedPassengerSideReplaceOptionsValues: {
@ -107,9 +111,11 @@ export default {
return this.selectedValues.selectedPassengerSideReplaceOptions;
},
set(newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides,
this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
this.selectedValues.selectedDriverSideReplaceOptions,
newValue);
newValue
);
}
},
answersToDisplay() {
@ -148,9 +154,11 @@ export default {
this.$refs.driverSideOptions.initializeComponent(driverSideOptions);
this.$refs.passengerSideOptions.initializeComponent(passengerSideOptions);
},
getSideDoorReplacementOptions(selectedDoorSides,
getSideDoorReplacementOptions(
selectedDoorSides,
selectedDriverSideReplaceOptions,
selectedPassengerSideReplaceOptions) {
selectedPassengerSideReplaceOptions
) {
return {
selectedDoorSides,
selectedDriverSideReplaceOptions,

View file

@ -1,8 +1,9 @@
/* eslint-env jest */
import { mount, flushPromises } from '@vue/test-utils';
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 { useMainStore } from '@/store';
import vehicleCategories from '@/constants/vehicle-categories';
import VehicleDamageComponent from '@/layouts/vehicle-damage/vehicle-damage.vue';
@ -69,6 +70,21 @@ describe('vehicle-damage.vue', () => {
const wrapper = mount(VehicleDamageComponent, mountOptions);
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');
await flushPromises();

View file

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

View file

@ -1,28 +1,9 @@
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';
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);
});
});
/** @ignore */
function setupMocks({
modelValueProp = ['Two'],
groupName = 'WindshieldChipCountQuestion',
@ -55,3 +36,24 @@ function setupMocks({
const damageOptions = dataFromStoreApi;
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>
<script>
import buttonQuestion from '@/digital-components/button-question/button-question';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default {
name: 'windshield-options',

View file

@ -1,22 +1,9 @@
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';
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' }]);
});
});
/** @ignore */
function setupMocks({
modelValueProp = '',
groupName = 'WindshieldDamageTypeQuestion',
@ -42,10 +29,25 @@ function setupMocks({
// Mock CMS content
const cmsContent = {
groupName: groupName,
groupName,
QuestionText: cmsQuestionText,
Answers: cmsAnswers
};
const damageOptions = dataFromStoreApi;
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>
<script>
import buttonQuestion from '@/digital-components/button-question/button-question';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
export default {
name: 'windshield-damage-type-question',

View file

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

View file

@ -1,6 +1,6 @@
/* eslint-env jest */
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 { GaActions } from '@/constants/analytics';
import vinLookupMethodSelections from '@/constants/vin-lookup-methods';
@ -11,7 +11,7 @@ import { defineRule } from 'vee-validate';
import errorMessages from '@/constants/error-messages';
import globalRules from '@/constants/global-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();
useMainStore(pinia);

View file

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

View file

@ -14,11 +14,11 @@
// Import Other Supporting Files
import { useMainStore } from '@/store';
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 Component
import ButtonQuestion from '@/digital-components/button-question/button-question';
import ButtonQuestion from '@/digital-components/button-question/button-question.vue';
export default {
name: 'vin-lookup-methods',

View file

@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
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';
const featureListData = {
@ -23,6 +23,34 @@ const featureListData = {
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', () => {
test('Part data passed in, should map data for ButtonQuestion (radio type)', async () => {
// Arrange
@ -31,7 +59,7 @@ describe('glass-part-question.vue', () => {
// Act
await wrapper.vm.$nextTick();
console.log(wrapper.vm.featureListData['Green Tint'][0].Text);
window.console.log(wrapper.vm.featureListData['Green Tint'][0].Text);
// Assert
expect(Object.keys(wrapper.vm.featureListData).length).toBe(2);
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', []]
];
test.each(partsForSelectedTintTestCases)('partsForSelectedTint returns correct parts',
test.each(partsForSelectedTintTestCases)(
'partsForSelectedTint returns correct parts',
async (glassLocation, glassName, selectedTint, expectedResults) => {
// Arrange
const pageData = { partsOrQuestions: [
@ -195,32 +224,6 @@ describe('glass-part-question.vue', () => {
// Assert
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>
// Components
import buttonQuestion from '@/digital-components/button-question/button-question';
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
// Supporting files
import getTintImage from '@/constants/tint-mapper';
@ -91,8 +91,10 @@ export default {
return validationRuleName;
},
colorQuestionText() {
return getCustomTransformValue(this.glassColorQuestion,
`${this.glassLocation} ${this.glassName}`);
return getCustomTransformValue(
this.glassColorQuestion,
`${this.glassLocation} ${this.glassName}`
);
},
tintSelectionOptions() {
@ -102,8 +104,7 @@ export default {
tintOptions.push({
value: tintOption,
buttonLabel: tintOption,
buttonImage: require(`@/assets/img/tints/${this.getTintSourceImage(this.glassLocation,
tintOption)}`)
buttonImage: require(`@/assets/img/tints/${this.getTintSourceImage(this.glassLocation, tintOption)}`)
});
});

View file

@ -1,22 +1,20 @@
// Components
import vehicleParts from '@/layouts/vehicle-parts/vehicle-parts';
import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question';
import vehicleParts from '@/layouts/vehicle-parts/vehicle-parts.vue';
import glassPartQuestion from '@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue';
// Supporting Files
import { settleAllPromises } from '@/helpers/layout-helper.js';
import settleAllPromises from '@/helpers/layout-helper.js';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from '@/helpers/unit-test-helper.js';
import { nextTick } from 'vue';
import baseMixin from '@/mixins/base-mixin.js';
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';
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn()
}));
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
// Mock fetchCmsContentForPage
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', () => {
test('Set cms content called on load', async () => {
// Arrange
@ -82,10 +124,12 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
wrapper.vm.setCmsContent = jest.fn();
// Assert
@ -115,10 +159,12 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
await nextTick();
@ -147,10 +193,12 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
await nextTick();
@ -183,16 +231,20 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
wrapper.vm.navigateBack();
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
wrapper.vm.$route);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
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 () => {
@ -211,16 +263,20 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
wrapper.vm.navigateBack();
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
wrapper.vm.$route);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
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 () => {
@ -286,16 +342,25 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
// Assert
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 () => {
@ -347,58 +412,23 @@ describe('vehicle-parts.vue', () => {
});
// Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'vehicle-parts' } },
undefined,
(c) => c(wrapper.vm));
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
// Assert
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
ref="theForm"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -72,11 +72,12 @@ import alert from '@/ux-components/alert/alert.vue';
// Supporting Files
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 { Form } from 'vee-validate';
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store';
export default {
name: 'vehicle-parts',
@ -178,16 +179,18 @@ export default {
arePagePrerequisitesValid() {
// Check if isRepair is populated and if the pageData we need is here (Parts data)
return (
this.mainStore.damage.isRepair != null
&& this.mainStore.pageData(issPageValues.VEHICLE_PARTS)
&& Object.keys(this.mainStore.pageData(issPageValues.VEHICLE_PARTS)).length !== 0
useMainStore().damage.isRepair != null
&& useMainStore().pageData(issPageValues.VEHICLE_PARTS)
&& Object.keys(useMainStore().pageData(issPageValues.VEHICLE_PARTS)).length !== 0
);
},
async forwardButtonAction() {
const matchedParts = [];
// 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)) {
// eslint-disable-next-line no-restricted-syntax
for (const [partKey, partValue] of Object.entries(value.parts)) {
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
@ -213,10 +216,9 @@ export default {
LoadInitialPartsData() {
const partsData = this.PartsFromApi;
this.alreadyPopulatedPartsData
= this.mainStore.lineItems.glassParts === null
? []
: this.mainStore.lineItems.glassParts;
this.alreadyPopulatedPartsData = this.mainStore.lineItems.glassParts === null
? []
: this.mainStore.lineItems.glassParts;
partsData.partsOrQuestions.map((g) => {
// If the part is already populated, use the value from the store and populate the v-model.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,7 +9,7 @@
<script>
import { getDamageString } from '@/helpers/damage-helper';
import alert from '@/ux-components/alert/alert';
import alert from '@/ux-components/alert/alert.vue';
export default {
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 { render } from '@testing-library/vue';
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');

View file

@ -14,11 +14,11 @@
</template>
<script>
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 vehicleNotMatchedAlert from '@/layouts/vin-lookup/vin-lookup-alerts/vehicle-not-matched-alert/vehicle-not-matched-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.vue';
import twoIdenticalYMMVehicleAlert from
'@/layouts/vin-lookup/vin-lookup-alerts/two-identical-ymm-vehicle-alert/two-identical-ymm-vehicle-alert';
import perfectMatchAlert from '@/layouts/vin-lookup/vin-lookup-alerts//perfect-match-alert/perfect-match-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.vue';
export default {
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 queryStrings from '@/constants/query-strings';
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 { useMainStore } from '@/store';
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);
});
// 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 () => {
const user = userEvent.setup();
mountOptions.global.stubs.vinQuestion = false;
@ -315,6 +316,7 @@ describe('vin-lookup.vue', () => {
});
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 () => {
const user = userEvent.setup();
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 () => {
const user = userEvent.setup();
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 () => {
const user = userEvent.setup();
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 () => {
const user = userEvent.setup();
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 () => {
const user = userEvent.setup();
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"
v-slot="{ meta }"
@submit="onSubmit"
@invalid-submit="onInvalidSubmit">
@invalidSubmit="onInvalidSubmit">
<div class="page-container-grouped-styles">
<div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -48,7 +48,7 @@ import { computed } from 'vue';
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
import { fetchCmsContentForPage } from '@/helpers/cms-content-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 { useMainStore } from '@/store';
@ -112,8 +112,7 @@ export default {
vehicleFromLookup: null,
vin: this.getVinFromStore(),
forwardButtonCarStyle: '',
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0,
bailout: false
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0
};
},
computed: {
@ -130,6 +129,7 @@ export default {
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
},
vinMask() {
// TODO: Side effects in computed.
if (this.vinPopulatedOnPageLoad) {
// TODO: Modify to remove side effects in computed
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.PERFECT_MATCH;
@ -178,13 +178,8 @@ export default {
// because the form itself actually passes its client-side validation.
// SSR-189 Scenario #4.
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
this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { vin: this.vin });
}
@ -217,10 +212,12 @@ export default {
if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) {
this.mainStore.updateVehicle(this.vehicleFromLookup);
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,
{},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
);
// navigate() doesn't stop the processing flow
return null;
@ -241,6 +238,8 @@ export default {
// Comes from vehicleQuestionsMixin.navigateForward()
await this.navigateForward(partsOrQuestionsResponse.data.partsOrQuestions, this);
return null;
},
async getPartsOrQuestions() {
try {

View file

@ -16,7 +16,7 @@ import { regex, required } from '@/helpers/validation-rules';
import errorMessages from '@/constants/error-messages';
// 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-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