From 8c6842ca55cecbab8d3fa8a158c223fb0d42ef06 Mon Sep 17 00:00:00 2001 From: DavidAtSafelite Date: Mon, 28 Aug 2023 08:59:37 -0400 Subject: [PATCH 01/13] Final eslint baseline PR linting 9 ! --- .eslintrc.js | 4 +- src/constants/error-messages.js | 1 + .../base-input-button/base-input-button.vue | 6 +- .../button-question/button-question.spec.js | 252 ++++++++---- .../textarea-question/textarea-question.vue | 11 +- .../textbox-question/textbox-question.vue | 5 +- src/global-methods.js | 66 +-- src/global-methods.spec.js | 91 +++-- src/helpers/clientauth-helper.js | 9 +- src/helpers/cookie-helper.js | 13 +- src/helpers/event-bus/event-bus.spec.js | 24 +- src/helpers/global-rule-definer.js | 32 +- src/helpers/layout-helper.js | 6 +- src/helpers/layout-helper.spec.js | 2 +- src/helpers/service-location-helper.js | 12 +- src/helpers/unit-test-helper.js | 5 +- .../address-questions.spec.js | 6 +- .../address-questions/address-questions.vue | 22 +- .../loading-modal/loading-modal.vue | 6 +- .../site-header/site-header.vue | 6 +- .../site-sub-header/site-sub-header.vue | 6 +- .../address-lookup/address-lookup.spec.js | 27 +- src/layouts/address-lookup/address-lookup.vue | 66 +-- .../address-vehicles-question.vue | 13 +- .../address-vehicles/address-vehicles.spec.js | 15 +- .../address-vehicles/address-vehicles.vue | 32 +- .../bailout-confirmation.vue | 2 +- src/layouts/bailout-page/bailout-page.vue | 8 +- .../capability-questions.vue | 14 +- .../contact-details/contact-details.vue | 6 +- .../coverage-statement.spec.js | 6 +- .../coverage-statement/coverage-statement.vue | 44 +- src/layouts/entry-page/entry-page.spec.js | 12 +- src/layouts/entry-page/entry-page.vue | 6 +- .../license-plate-lookup.spec.js | 33 +- .../license-plate-lookup.vue | 46 ++- .../molding-questions/molding-questions.vue | 26 +- .../order-confirmation/order-confirmation.vue | 8 +- .../part-questions/part-questions.spec.js | 3 + src/layouts/part-questions/part-questions.vue | 8 +- src/layouts/payment-page/payment-page.vue | 2 +- .../policy-holder-details.spec.js | 18 +- .../policy-holder-details.vue | 14 +- .../policy-vehicles/policy-vehicles.spec.js | 37 +- .../policy-vehicles/policy-vehicles.vue | 18 +- .../provider-pref-radio.spec.js | 6 +- .../provider-preference.spec.js | 12 +- .../provider-preference.vue | 2 +- .../shop-preference-modal.spec.js | 12 +- .../steering-modal/steering-modal.spec.js | 12 +- .../tpa-recal-modal/tpa-recal-modal.spec.js | 12 +- src/layouts/review-page/review-page.vue | 8 +- src/layouts/schedule-page/schedule-page.vue | 2 +- .../service-location/service-location.spec.js | 12 +- .../service-location/service-location.vue | 8 +- .../service-zip-modal-question.spec.js | 6 +- .../service-package-radio.spec.js | 6 +- .../service-packages/service-packages.vue | 2 +- .../tpa-confirmation/tpa-confirmation.vue | 8 +- src/layouts/tpa-search/tpa-search.vue | 8 +- src/layouts/tpa-submit/tpa-submit.vue | 8 +- .../damage-location-question.spec.js | 6 +- .../replace-options-question.spec.js | 15 +- .../side-door-options.spec.js | 6 +- .../side-door-options/side-door-options.vue | 24 +- src/layouts/vehicle-damage/vehicle-damage.vue | 32 +- .../windshield-options/windshield-options.vue | 42 +- src/layouts/vehicle-lookup/vehicle-lookup.vue | 2 +- .../vin-lookup-methods/vin-lookup-methods.vue | 2 +- .../glass-part-question.spec.js | 6 +- .../glass-part-question.vue | 6 +- .../vehicle-parts/vehicle-parts.spec.js | 72 ++-- src/layouts/vehicle-parts/vehicle-parts.vue | 2 +- .../vehicle-selection/vehicle-selection.vue | 8 +- src/layouts/vin-lookup/vin-lookup.spec.js | 42 +- src/layouts/vin-lookup/vin-lookup.vue | 14 +- src/layouts/welcome-page/welcome-page.spec.js | 24 +- src/layouts/welcome-page/welcome-page.vue | 26 +- src/mixins/analytics-mixin.js | 15 +- src/mixins/analytics-mixin.spec.js | 12 +- src/mixins/vehicle-questions-mixin.js | 37 +- src/mixins/vehicle-questions-mixin.spec.js | 383 ++++++++++-------- src/router/index.js | 30 +- src/store/store.spec.js | 8 +- src/ux-components/alert/alert.spec.js | 30 +- .../button-main/button-main.spec.js | 24 +- .../modal-button-main.spec.js | 48 ++- .../modal-button-main/modal-button-main.vue | 6 +- src/ux-components/text-link/text-link.vue | 6 +- 89 files changed, 1275 insertions(+), 826 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c9deb6a3..3d578a28 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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 }], diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index caad0dfb..b63d9cd0 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -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', diff --git a/src/digital-components/base-input-button/base-input-button.vue b/src/digital-components/base-input-button/base-input-button.vue index fdcf4480..301bb52e 100644 --- a/src/digital-components/base-input-button/base-input-button.vue +++ b/src/digital-components/base-input-button/base-input-button.vue @@ -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, diff --git a/src/digital-components/button-question/button-question.spec.js b/src/digital-components/button-question/button-question.spec.js index 7e5720d3..6424abc4 100644 --- a/src/digital-components/button-question/button-question.spec.js +++ b/src/digital-components/button-question/button-question.spec.js @@ -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; diff --git a/src/digital-components/textarea-question/textarea-question.vue b/src/digital-components/textarea-question/textarea-question.vue index 70d995f9..902cd2ca 100644 --- a/src/digital-components/textarea-question/textarea-question.vue +++ b/src/digital-components/textarea-question/textarea-question.vue @@ -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, diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index a380f51c..b619460e 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -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, diff --git a/src/global-methods.js b/src/global-methods.js index 4d333918..c32a6c9d 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -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); + } ); }); } diff --git a/src/global-methods.spec.js b/src/global-methods.spec.js index f5622ce6..3f0d0493 100644 --- a/src/global-methods.spec.js +++ b/src/global-methods.spec.js @@ -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 - }; -} diff --git a/src/helpers/clientauth-helper.js b/src/helpers/clientauth-helper.js index 3d1a7f58..2bfd53bb 100644 --- a/src/helpers/clientauth-helper.js +++ b/src/helpers/clientauth-helper.js @@ -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; diff --git a/src/helpers/cookie-helper.js b/src/helpers/cookie-helper.js index 2b93484b..5b858cfa 100644 --- a/src/helpers/cookie-helper.js +++ b/src/helpers/cookie-helper.js @@ -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) { @@ -188,8 +191,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], { diff --git a/src/helpers/event-bus/event-bus.spec.js b/src/helpers/event-bus/event-bus.spec.js index 16501c4f..dc1e36bd 100644 --- a/src/helpers/event-bus/event-bus.spec.js +++ b/src/helpers/event-bus/event-bus.spec.js @@ -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(); }); diff --git a/src/helpers/global-rule-definer.js b/src/helpers/global-rule-definer.js index b06fe946..650fb97e 100644 --- a/src/helpers/global-rule-definer.js +++ b/src/helpers/global-rule-definer.js @@ -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 + ) + ); } /** diff --git a/src/helpers/layout-helper.js b/src/helpers/layout-helper.js index d13bbc2b..a4585342 100644 --- a/src/helpers/layout-helper.js +++ b/src/helpers/layout-helper.js @@ -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; diff --git a/src/helpers/layout-helper.spec.js b/src/helpers/layout-helper.spec.js index c8107580..758639c6 100644 --- a/src/helpers/layout-helper.spec.js +++ b/src/helpers/layout-helper.spec.js @@ -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 diff --git a/src/helpers/service-location-helper.js b/src/helpers/service-location-helper.js index 362f3d22..242752d3 100644 --- a/src/helpers/service-location-helper.js +++ b/src/helpers/service-location-helper.js @@ -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); } diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 2bcfc8af..9ccfd29b 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -1,3 +1,4 @@ +/* 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'; @@ -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: '{}', diff --git a/src/iss-components/address-questions/address-questions.spec.js b/src/iss-components/address-questions/address-questions.spec.js index 60f8d692..6d225c65 100644 --- a/src/iss-components/address-questions/address-questions.spec.js +++ b/src/iss-components/address-questions/address-questions.spec.js @@ -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 diff --git a/src/iss-components/address-questions/address-questions.vue b/src/iss-components/address-questions/address-questions.vue index 6e90deac..7ff88886 100644 --- a/src/iss-components/address-questions/address-questions.vue +++ b/src/iss-components/address-questions/address-questions.vue @@ -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; diff --git a/src/iss-components/loading-modal/loading-modal.vue b/src/iss-components/loading-modal/loading-modal.vue index fb7c270a..02deed69 100644 --- a/src/iss-components/loading-modal/loading-modal.vue +++ b/src/iss-components/loading-modal/loading-modal.vue @@ -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; diff --git a/src/iss-components/site-header/site-header.vue b/src/iss-components/site-header/site-header.vue index 5cf77eca..1666582c 100644 --- a/src/iss-components/site-header/site-header.vue +++ b/src/iss-components/site-header/site-header.vue @@ -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; diff --git a/src/iss-components/site-sub-header/site-sub-header.vue b/src/iss-components/site-sub-header/site-sub-header.vue index 7e607804..4cd0af1d 100644 --- a/src/iss-components/site-sub-header/site-sub-header.vue +++ b/src/iss-components/site-sub-header/site-sub-header.vue @@ -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); diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index a891af3e..ddc65015 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -2,7 +2,7 @@ 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'; @@ -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 diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index b7d9d73e..5f913011 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -87,7 +87,7 @@ 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'; @@ -142,8 +142,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 = @@ -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 = @@ -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 + ); }); }, @@ -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() { diff --git a/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue index 17e429cc..ba04cf22 100644 --- a/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue +++ b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue @@ -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}`; diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js index 862e6569..caab2ae3 100644 --- a/src/layouts/address-vehicles/address-vehicles.spec.js +++ b/src/layouts/address-vehicles/address-vehicles.spec.js @@ -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(); diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index a7c12388..63cb3572 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -65,7 +65,7 @@ + + diff --git a/src/router/index.js b/src/router/index.js index bcf2fd46..1b2e8ace 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ import { createWebHistory, createRouter } from 'vue-router'; import lazyLoadComponent from '@/router/dynamic-routing/component-loader'; import issPageValues from '@/router/router-constants/issPage-values'; @@ -6,11 +7,8 @@ import { useMainStore } from '@/store'; import eventBus from '@/helpers/event-bus/event-bus'; import { globalEvents, globalEventTypes } from '@/constants/events'; import baseMixin from '@/mixins/base-mixin'; -import { - getDeviceIdValue, - updateOrCreateISSCookie, - updateSessionIdCookie -} from '@/helpers/cookie-helper'; +import { isSavedSessionStillActive } from '@/helpers/session-helper'; +import { getDeviceIdValue, getISSCookie, updateOrCreateISSCookie, updateSessionIdCookie } from '@/helpers/cookie-helper'; import { experimentTriggers } from '@/constants/experiments'; import applicationConfig from '@/constants/application-config'; @@ -23,29 +21,52 @@ const routes = [ name: 'root', async beforeEnter(to, from, next) { try { - to.query.issPage = !to.query.issPage - ? issPageValues.WELCOME_PAGE - : to.query.issPage; + const issPageToUse = !to.query.issPage ? issPageValues.WELCOME_PAGE : to.query.issPage; + + if ((issPageToUse === issPageValues.ACCESS_DENIED + || (issPageToUse !== issPageValues.ENTRY_PAGE && !useMainStore().issConfig.accountNumber)) + && process.env.VUE_APP_CURRENT_ENVIRONMENT !== 'Localhost' + ) { + return await GoToAccessIsDenied(next); + } // Do not run these for the main entry page - as it is not part of the user flow. - if (to.query.issPage !== issPageValues.ENTRY_PAGE) { + if (issPageToUse !== issPageValues.ENTRY_PAGE) { if (analyticsMixin.methods.noSession()) { await analyticsMixin.methods.initSession(); } else { updateSessionIdCookie(); } - await runExperiments(to.query.issPage); + await runExperiments(issPageToUse); // fmg has this further down + } + + // If the saved session has timed out, clear the session, execute 404 logic. + if (getISSCookie() !== null && !isSavedSessionStillActive()) { + // await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); + await GoToStartOn404(next); } // Process ISS cookie. updateOrCreateISSCookie(); - if (router.hasRoute(to.query.issPage)) { - return next({ name: to.query.issPage, query: to.query, params: to.params }); + if (router.hasRoute(issPageToUse)) { + // Since our route is already in scope, we can grab the component and call the arePagePrerequisitesValid function. + let component = router.getRoutes().filter((x) => x.name === issPageToUse)[0].components; + + // If the component hasn't been loaded fully, load it before we check prerequisites. + if (component.default.methods === undefined) { + component = await component.default(); + } + + if (!arePagePrerequisitesValid(component)) { + await GoToStartOn404(next); + } + + return next({ name: issPageToUse, query: to.query, params: to.params }); } - const routeData = await GetRouteInfoFromPageName(to.query.issPage); + const routeData = await GetRouteInfoFromPageName(issPageToUse); if (routeData[0].name.toLowerCase() === 'error') { throw new Error('Page not found!'); @@ -58,6 +79,19 @@ const routes = [ component: routeData[0].component }); + // Call the next components arePagePrerequisitesValid method before load. + // If it returns false, use the 404 logic. + const nextComponent = await router + .getRoutes() + .filter((x) => x.name === routeData[0].name)[0] + .components.default(); + + if (!arePagePrerequisitesValid(nextComponent)) { + const tempMsgCopy = 'Pre Requisites failed, need to handle. Default is Welcome Page.'; + const tempMsgHeadline = `${issPageToUse}: pre-req failed...`; + await GoToStartOn404(next, tempMsgCopy, tempMsgHeadline); + } + // Assign current query string parameters, as well as our issPage one. next({ name: routeData[0].name, @@ -66,7 +100,7 @@ const routes = [ }); } catch (error) { window.console.warn(error); - GoToStartOn404(next); + await GoToStartOn404(next); } return null; } @@ -76,15 +110,13 @@ const routes = [ const router = createRouter({ history: createWebHistory('/'), routes, - scrollBehavior(to, from, savedPosition) { + scrollBehavior() { // always scroll to top return { top: 0 }; } }); -router.afterEach((to, from) => { - /*eslint-disable-line*/ - +router.afterEach((to) => { const store = useMainStore(); // Update lastPageVisited in the store store.updateLastPageVisited(to.name); @@ -119,36 +151,33 @@ async function GetRouteInfoFromPageName(pageName) { } // Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example. -router.overrideNavigation = (scenario, +router.overrideNavigation = ( + scenario, currentRoute, next, isSavingNavigation, optionalQuery = {}, optionalParams = {}, - optionalPageData) => { - navigate(scenario, - currentRoute, - isSavingNavigation, - optionalQuery, - optionalParams, - optionalPageData); + optionalPageData = {} +) => { + navigate( + scenario, currentRoute, isSavingNavigation, optionalQuery, optionalParams, optionalPageData + ); next(); }; -router.navigate = (scenario, - currentRoute, - optionalQuery = {}, - optionalParams = {}, - optionalPageData = {}) => { - navigate(scenario, currentRoute, optionalQuery, optionalParams, optionalPageData); +router.navigate = ( + scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {} +) => { + navigate( + scenario, currentRoute, optionalQuery, optionalParams, optionalPageData + ); }; // Navigate to the next route, depending on the scenario. -function navigate(scenario, - currentRoute, - optionalQuery = {}, - optionalParams = {}, - optionalPageData = {}) { +function navigate( + scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {} +) { /*eslint-disable-line*/ if (!scenario) { window.console.error('No scenario provided. Please review the routing table.'); @@ -172,9 +201,7 @@ function navigate(scenario, // Update page data to the store for next page if provided. Otherwise, keep existing page data or set to empty object const existingPageDataForPage = useMainStore().pageData(matchingScenarioMap.destinationIssPageValue); baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationIssPageValue, - Object.keys(optionalPageData).length > 0 - ? optionalPageData - : existingPageDataForPage ?? {}); + Object.keys(optionalPageData).length > 0 ? optionalPageData : existingPageDataForPage ?? {}); // We're always pushing the same path, just changing query strings. // Make sure our optional query strings get combined with our issPage one. @@ -194,7 +221,7 @@ function navigate(scenario, function navigateToUrl(url, optionalQuery = {}) { // possibly show some loading screen in the future here. const externalUrl = new URL(url); - // eslint-disable-next-line no-restricted-syntax + // eslint-disable-next-line no-restricted-syntax, guard-for-in for (const queryKey in optionalQuery) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } @@ -207,9 +234,7 @@ function getNavigationMap(scenario, currentRoute) { const issPageValue = currentRoute.query.issPage; try { const matchedQueryValue = routingTable(useMainStore()) - .filter((item) => - item.issPageValue === issPageValue - && item.maps.filter((map) => map.scenario === scenario).length > 0); + .filter((item) => item.issPageValue === issPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0); const maps = matchedQueryValue ? matchedQueryValue.map((m) => m.maps.filter((map) => map.scenario === scenario))[0] : undefined; @@ -220,7 +245,21 @@ function getNavigationMap(scenario, currentRoute) { } } -function GoToStartOn404(next) { +async function GoToAccessIsDenied(next) { + const errorPageName = issPageValues.ACCESS_DENIED; + router.addRoute({ + path: '/', + name: errorPageName, + component: lazyLoadComponent(errorPageName) + }); + + next({ + name: errorPageName, + query: { issPage: errorPageName } + }); +} + +async function GoToStartOn404(next, msgCopy = null, msgHeadline = null) { const errorPageName = issPageValues.WELCOME_PAGE; router.addRoute({ path: '/', @@ -229,14 +268,12 @@ function GoToStartOn404(next) { }); // Put item on the bus - eventBus.addEventToBus(globalEvents.Categories.GLOBAL_ALERT, - globalEvents.SubCategories.PAGE_NOT_FOUND, - { - isDismissible: true, - messageCopy: 'You can get a quote by starting on this page.', - messageHeadline: "We're sorry, something went wrong.", - type: globalEventTypes.Danger - }); + eventBus.addEventToBus(globalEvents.Categories.GLOBAL_ALERT, globalEvents.SubCategories.PAGE_NOT_FOUND, { + isDismissible: true, + messageCopy: msgCopy ?? 'You can get a quote by starting on this page.', + messageHeadline: msgHeadline ?? "We're sorry, something went wrong.", + type: globalEventTypes.Danger + }); next({ name: errorPageName, @@ -244,6 +281,11 @@ function GoToStartOn404(next) { }); } +// Checks arePagePrerequisitesValid on the component passed in. +function arePagePrerequisitesValid(component) { + return component.default.methods.arePagePrerequisitesValid === undefined || component.default.methods.arePagePrerequisitesValid(); +} + // Run SiteEntry and PageEntry triggers for experiments async function runExperiments(nextPage) { const store = useMainStore(); diff --git a/src/router/router-constants/issPage-values.js b/src/router/router-constants/issPage-values.js index 9ddfab8c..68ad4a08 100644 --- a/src/router/router-constants/issPage-values.js +++ b/src/router/router-constants/issPage-values.js @@ -1,4 +1,5 @@ const issPageValues = Object.freeze({ + ACCESS_DENIED: 'access-denied', ENTRY_PAGE: 'entry-page', WELCOME_PAGE: 'welcome-page', diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 4af22d4f..7830bac3 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -319,6 +319,15 @@ const routingTable = () => [ } ] }, + { + issPageValue: issPageValues.ACCESS_DENIED, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationIssPageValue: issPageValues.ACCESS_DENIED + } + ] + }, { issPageValue: issPageValues.ENTRY_PAGE, maps: [ diff --git a/vue.config.js b/vue.config.js index 5018024e..a13ba34c 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,14 +1,14 @@ +/* eslint-disable max-len */ process.env.VUE_APP_CONSUMER_CF_DISTRO = 'https://digitalapi.dev.safelite.io'; process.env.VUE_APP_CURRENT_ENVIRONMENT = 'Localhost'; -process.env.VUE_APP_GOOGLE_PLACES_API_KEY - = 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0'; +process.env.VUE_APP_GOOGLE_PLACES_API_KEY = 'AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0'; // GA & GTM // NOTE: Using the old ISS site GTM Cotnainer ID for now, will create a new one soon. -process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY - = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');"; -process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC - = 'https://www.googletagmanager.com/ns.html?id=GTM-KKNWZ3>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x'; +process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = + "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');"; +process.env.VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC = + 'https://www.googletagmanager.com/ns.html?id=GTM-KKNWZ3>m_auth=amlAYNhxUxuskQo7jmjadg>m_preview=env-38>m_cookies_win=x'; module.exports = { publicPath: '/', From 406476d6a6ce43d2d50e05d7f70a148642f9c7c3 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Mon, 28 Aug 2023 12:32:42 -0400 Subject: [PATCH 03/13] linting update --- .eslintrc.js | 5 +++-- src/router/index.js | 22 ++++++++-------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c9deb6a3..440245f9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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', diff --git a/src/router/index.js b/src/router/index.js index 1b2e8ace..2fa73c97 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -160,24 +160,16 @@ router.overrideNavigation = ( optionalParams = {}, optionalPageData = {} ) => { - navigate( - scenario, currentRoute, isSavingNavigation, optionalQuery, optionalParams, optionalPageData - ); + navigate(scenario, currentRoute, isSavingNavigation, optionalQuery, optionalParams, optionalPageData); next(); }; -router.navigate = ( - scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {} -) => { - navigate( - scenario, currentRoute, optionalQuery, optionalParams, optionalPageData - ); +router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { + navigate(scenario, currentRoute, optionalQuery, optionalParams, optionalPageData); }; // Navigate to the next route, depending on the scenario. -function navigate( - scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {} -) { +function navigate(scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) { /*eslint-disable-line*/ if (!scenario) { window.console.error('No scenario provided. Please review the routing table.'); @@ -200,8 +192,10 @@ function navigate( } else if (matchingScenarioMap.destinationIssPageValue) { // Update page data to the store for next page if provided. Otherwise, keep existing page data or set to empty object const existingPageDataForPage = useMainStore().pageData(matchingScenarioMap.destinationIssPageValue); - baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationIssPageValue, - Object.keys(optionalPageData).length > 0 ? optionalPageData : existingPageDataForPage ?? {}); + baseMixin.methods.savePageDataToStore( + matchingScenarioMap.destinationIssPageValue, + Object.keys(optionalPageData).length > 0 ? optionalPageData : existingPageDataForPage ?? {} + ); // We're always pushing the same path, just changing query strings. // Make sure our optional query strings get combined with our issPage one. From 70ef75bbc85a36ce88c1e14253b13c9c230ee754 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Mon, 28 Aug 2023 13:43:59 -0400 Subject: [PATCH 04/13] this.mainStore not available in preReq, some linting --- src/layouts/vehicle-damage/vehicle-damage.vue | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index fc8401eb..63e1a02d 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -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; @@ -362,23 +364,22 @@ export default { }, async forwardButtonAction() { - await this.mainStore.saveVehicleDamage(this.isWindshieldRepair, + await this.mainStore.saveVehicleDamage( + this.isWindshieldRepair, this.selectedGlassToReplace(), - this.selectedWindshieldOptions.selectedWindshieldChipCount); + this.selectedWindshieldOptions.selectedWindshieldChipCount + ); 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); } }, From 2b4587c1f9b983f19989e540135db3df227f8c5e Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 29 Aug 2023 13:46:12 -0400 Subject: [PATCH 05/13] save supporting items on windshield repair --- src/layouts/vehicle-damage/vehicle-damage.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 595aef6f..cb8338a8 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -364,11 +364,17 @@ export default { }, async forwardButtonAction() { - await this.mainStore.saveVehicleDamage( + this.mainStore.saveVehicleDamage( this.isWindshieldRepair, this.selectedGlassToReplace(), this.selectedWindshieldOptions.selectedWindshieldChipCount ); + + if (this.isWindshieldRepair) { + const supportingItems = await useMainStore().getSupportingItems(); + useMainStore().saveSupportingItems(supportingItems.data); + } + return this.navigateForward(); }, From 6f63484dffcd4e279a6735948214cf0358859308 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 29 Aug 2023 15:57:23 -0400 Subject: [PATCH 06/13] updates to vehicle damage page. --- src/digital-components/base-input-button/base-input-button.vue | 3 ++- src/layouts/vehicle-damage/vehicle-damage.vue | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/digital-components/base-input-button/base-input-button.vue b/src/digital-components/base-input-button/base-input-button.vue index 301bb52e..f619a16e 100644 --- a/src/digital-components/base-input-button/base-input-button.vue +++ b/src/digital-components/base-input-button/base-input-button.vue @@ -74,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; }, diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index cb8338a8..4a53e854 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -372,7 +372,7 @@ export default { if (this.isWindshieldRepair) { const supportingItems = await useMainStore().getSupportingItems(); - useMainStore().saveSupportingItems(supportingItems.data); + this.mainStore.saveSupportingItems(supportingItems.data); } return this.navigateForward(); From 8e5dddd7ccd6aa0d239631501b7d350e89984c17 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 11:29:25 -0400 Subject: [PATCH 07/13] fix test --- .../vehicle-damage/vehicle-damage.spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index 56a6c4dd..f2f911f7 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -3,6 +3,7 @@ import { mount, flushPromises } from '@vue/test-utils'; import { createTestingPinia } from '@pinia/testing'; 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(); From d7cc2a3ed99fbe21b8011e76b7e814656b2e1c7c Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 13:16:14 -0400 Subject: [PATCH 08/13] bailout-confirmation renamed to contact-confirmation --- .../contact-confirmation.vue} | 0 src/router/router-constants/issPage-values.js | 2 +- src/router/router-constants/routing-table.js | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/layouts/{bailout-confirmation/bailout-confirmation.vue => contact-confirmation/contact-confirmation.vue} (100%) diff --git a/src/layouts/bailout-confirmation/bailout-confirmation.vue b/src/layouts/contact-confirmation/contact-confirmation.vue similarity index 100% rename from src/layouts/bailout-confirmation/bailout-confirmation.vue rename to src/layouts/contact-confirmation/contact-confirmation.vue diff --git a/src/router/router-constants/issPage-values.js b/src/router/router-constants/issPage-values.js index 68ad4a08..d79f748f 100644 --- a/src/router/router-constants/issPage-values.js +++ b/src/router/router-constants/issPage-values.js @@ -5,9 +5,9 @@ const issPageValues = Object.freeze({ ADDRESS_LOOKUP: 'address-lookup', ADDRESS_VEHICLES: 'address-vehicles', - BAILOUT_CONFIRMATION: 'bailout-confirmation', BAILOUT_PAGE: 'bailout-page', CAPABILITY_QUESTIONS: 'capability-questions', + CONTACT_CONFIRMATION: 'contact-confirmation', CONTACT_DETAILS: 'contact-details', ESTIMATE: 'estimate', COVERAGE_STATEMENT: 'coverage-statement', diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 7830bac3..c3fbe633 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -609,7 +609,7 @@ const routingTable = () => [ }, { scenario: navigationScenarios.CLICKED_FORWARD, - destinationIssPageValue: issPageValues.BAILOUT_CONFIRMATION + destinationIssPageValue: issPageValues.CONTACT_CONFIRMATION } ] } From b8a53d94d9b93bb7830782b7428be6e046b0e4bc Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 29 Aug 2023 13:44:09 -0400 Subject: [PATCH 09/13] preReqs --- .../service-location/service-location.vue | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 939f5aa6..31a0a9fc 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -118,10 +118,7 @@ export default { next((vm) => { vm.setCmsContent(resultMap.cmsContent); - vm.setData( - resultMap.zipCodeData, - resultMap.serviceabilityDetails - ); + vm.setData(resultMap.zipCodeData, resultMap.serviceabilityDetails); }); }, setup() { @@ -172,8 +169,15 @@ export default { } }, methods: { - arePagePrerequisiteValid() { - return true; + arePagePrerequisitesValid() { + console.log('hi'); + console.log(useMainStore().lineItems.supportingItems); + console.log(useMainStore().order.serviceLocation.zipCode); + + return ( + useMainStore().lineItems.supportingItems !== null + && useMainStore().order.serviceLocation.zipCode !== null + ); }, backButtonAction() { /** From 9fc06b097c631a1e4dfff820fdc436febba3521c Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 13:57:32 -0400 Subject: [PATCH 10/13] update servicelocation zipcode in store to match customer zipcode --- src/layouts/welcome-page/welcome-page.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 0607f008..e9943ba6 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -325,14 +325,16 @@ export default { const policy = policyInfo.policies?.[0]; if (policy) { // populate policy holder details from policy lookup - this.mainStore.order.customer.address.streetAddress = - policy.insureds?.[0]?.address; + this.mainStore.order.customer.address.streetAddress = policy.insureds?.[0]?.address; this.mainStore.order.customer.address.city = policy.insureds?.[0]?.city; this.mainStore.order.customer.address.state = policy.insureds?.[0]?.state; this.mainStore.order.customer.address.zipCode = policy.insureds?.[0]?.zipCode; this.mainStore.order.customer.firstName = policy.insureds?.[0]?.firstName; this.mainStore.order.customer.lastName = policy.insureds?.[0]?.lastName; + // populate additional fields + this.mainStore.order.serviceLocation.zipCode = policy.insureds?.[0]?.zipCode; + // populate vehicles this.vehiclesFound = policy.vehicles; } From d3882a8d96caecb5f679f270d9d79dce560fda53 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 13:59:09 -0400 Subject: [PATCH 11/13] remove console logs --- src/layouts/service-location/service-location.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 31a0a9fc..252741c1 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -170,10 +170,6 @@ export default { }, methods: { arePagePrerequisitesValid() { - console.log('hi'); - console.log(useMainStore().lineItems.supportingItems); - console.log(useMainStore().order.serviceLocation.zipCode); - return ( useMainStore().lineItems.supportingItems !== null && useMainStore().order.serviceLocation.zipCode !== null From 8a93a379499b13f2bdc65f0337d1a13b6f6b3743 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Wed, 30 Aug 2023 15:57:46 -0400 Subject: [PATCH 12/13] add servicelocation zipcode to --- src/store/index.js | 146 ++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 76 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 24014a3c..01d36851 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,3 +1,4 @@ +/* eslint-disable no-use-before-define */ /* eslint-disable max-len */ import { defineStore } from 'pinia'; import { endpoints } from '@/constants/endpoints'; @@ -203,26 +204,33 @@ export const useMainStore = defineStore({ issIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified, issHasRecalibrationPart: getHasRecalibrationPart(state), issSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1, - issSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, - 'glassLocation').includes(damageLocationsSelected.WINDSHIELD), - issSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, - 'glassLocation').includes(damageLocationsSelected.REAR), - issSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, - 'glassLocation').includes(damageLocationsSelected.DRIVER), - issSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, - 'glassLocation').includes(damageLocationsSelected.PASSENGER), + issSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation') + .includes(damageLocationsSelected.WINDSHIELD), + issSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation') + .includes(damageLocationsSelected.REAR), + issSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation') + .includes(damageLocationsSelected.DRIVER), + issSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, 'glassLocation') + .includes(damageLocationsSelected.PASSENGER), issOrderPartNumbers: [ - ...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, - 'partNumber'), - ...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, - 'partNumber') + ...getNonFalseValuesOfPropertyInArrayOfObjects( + state.order.lineItems.glassParts, + 'partNumber' + ), + ...getNonFalseValuesOfPropertyInArrayOfObjects( + state.order.lineItems.otherParts, + 'partNumber' + ) ], - issOrderPartTypes: [ - ...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, - 'recalibrationType'), - ...getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, - 'recalibrationType') + ...getNonFalseValuesOfPropertyInArrayOfObjects( + state.order.lineItems.glassParts, + 'recalibrationType' + ), + ...getNonFalseValuesOfPropertyInArrayOfObjects( + state.order.lineItems.otherParts, + 'recalibrationType' + ) ] }), experimentSettings: (state) => state.applicationUser.experiments @@ -599,8 +607,7 @@ export const useMainStore = defineStore({ async getPriceOrderItems(availableLineItems) { let zipCodeToUse = this.order.serviceLocation.zipCode; let ctuToUse = this.order.serviceLocation.zipCodeCtu; - const availableLineItemsFormattedForRequest - = getLineItemQueryStringForPricing(availableLineItems); + const availableLineItemsFormattedForRequest = getLineItemQueryStringForPricing(availableLineItems); const { vehicle } = this.order; // WARNING @@ -608,8 +615,8 @@ export const useMainStore = defineStore({ // and ctu is available. Also, EON may need to be implemented. zipCodeToUse = '44902'; ctuToUse = '01820'; - const queryString - = `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` + const queryString = + `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` + `&CTU=${ctuToUse}` + `&CarId=${vehicle.carId}` + `&Make=${vehicle.make}` @@ -637,16 +644,14 @@ export const useMainStore = defineStore({ const lineItemsWithOnlyPartNumbers = this.order.lineItems.glassParts.map((glassPart) => ({ partNumber: glassPart.partNumber })); - const lineItems = buildQueryStringParameterFromArrayOfComplexObjects(lineItemsWithOnlyPartNumbers, - 'lineItems'); + const lineItems = buildQueryStringParameterFromArrayOfComplexObjects(lineItemsWithOnlyPartNumbers, 'lineItems'); const { vehicle } = this.order; const { carId } = vehicle; const { damage } = this.order; const glassArray = convertGlassPieceNamingForApi(damage.glassToReplace); - const glassPieces = buildQueryStringParameterFromArrayOfComplexObjects(glassArray, - 'glassPieces'); + const glassPieces = buildQueryStringParameterFromArrayOfComplexObjects(glassArray, 'glassPieces'); return globalMethods.callHttpClient({ method: endpoints.GetServiceabilityDetails.method, @@ -679,23 +684,16 @@ export const useMainStore = defineStore({ saveVehicleDamage(isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount) { const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort(); - const isGlassToReplaceTheSame - = this.order.damage.glassToReplace?.length === selectedGlassToReplace.length - && this.order.damage.glassToReplace - .slice() - .sort() - .every((obj, index) => obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation + const isGlassToReplaceTheSame = this.order.damage.glassToReplace?.length === selectedGlassToReplace.length + && this.order.damage.glassToReplace + .slice() + .sort() + .every((obj, index) => obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation && obj.glassName === selectedGlassPassedInSorted[index].glassName); - const isWindshieldRepairTheSame - = isWindshieldRepair === this.order.damage.isRepair; - - const isChipCountTheSame - = selectedWindshieldChipCount === this.order.damage.numberOfChips; - - const isDamageChanging - = !isGlassToReplaceTheSame - || !isWindshieldRepairTheSame - || (isWindshieldRepair && !isChipCountTheSame); + const isWindshieldRepairTheSame = isWindshieldRepair === this.order.damage.isRepair; + const isChipCountTheSame = selectedWindshieldChipCount === this.order.damage.numberOfChips; + const isDamageChanging = !isGlassToReplaceTheSame || !isWindshieldRepairTheSame + || (isWindshieldRepair && !isChipCountTheSame); if (isDamageChanging) { // Reset dependent state when changing @@ -927,16 +925,14 @@ export const useMainStore = defineStore({ this.order.customer.address.zipCode = customerQuestions.addressQuestions.zipCode; this.order.customer.firstName = customerQuestions.firstName; this.order.customer.lastName = customerQuestions.lastName; + this.order.serviceLocation.zipCode = customerQuestions.addressQuestions.zipCode; }, savePartQuestionAnswers(partQuestionAnswersArray) { // if part question answers have changed, reset subsequent question answers - const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.partQuestionAnswers, - 'result'); - const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(partQuestionAnswersArray, - 'result'); - const havePartQuestionAnswersChanged - = sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length - || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedPartQuestionAnswersArray[i].result); + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.partQuestionAnswers, 'result'); + const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(partQuestionAnswersArray, 'result'); + const havePartQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length + || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedPartQuestionAnswersArray[i].result); if (havePartQuestionAnswersChanged) { this.updateGlassParts(null); @@ -954,13 +950,10 @@ export const useMainStore = defineStore({ this.updatePartQuestionAnswers(partQuestionAnswersArray); }, saveMoldingQuestionAnswers(moldingQuestionAnswersArray) { - const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.moldingQuestionAnswers, - 'result'); - const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(moldingQuestionAnswersArray, - 'result'); - const haveMoldingQuestionAnswersChanged - = sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length - || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedMoldingQuestionAnswersArray[i].result); + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.moldingQuestionAnswers, 'result'); + const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(moldingQuestionAnswersArray, 'result'); + const haveMoldingQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length + || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedMoldingQuestionAnswersArray[i].result); if (haveMoldingQuestionAnswersChanged) { this.updateGlassParts(null); @@ -974,13 +967,10 @@ export const useMainStore = defineStore({ }, saveCapabilityQuestionAnswers(capabilityQuestionAnswersArray) { - const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.capabilityQuestionAnswers, - 'result'); - const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(capabilityQuestionAnswersArray, - 'result'); - const haveCapabilityQuestionAnswersChanged - = sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length - || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result); + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.capabilityQuestionAnswers, 'result'); + const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue(capabilityQuestionAnswersArray, 'result'); + const haveCapabilityQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length + || !sortedPreviousResultsArray?.every((x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result); if (haveCapabilityQuestionAnswersChanged) { this.updateGlassParts(null); @@ -1064,10 +1054,12 @@ export const useMainStore = defineStore({ endpoint: endpoints.LogPageView.url, payload, logApiCall: false - }).then((response) => response, + }).then( + (response) => response, (error) => { console.log(`Analytics Service Error: ${error.data}`); - }); + } + ); }, logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) { if (pageName == null || pageName.length === 0) { pageName = 'none'; } @@ -1091,10 +1083,12 @@ export const useMainStore = defineStore({ endpoint: endpoints.LogCustomEvent.url, payload, logApiCall: false - }).then((response) => response, + }).then( + (response) => response, (error) => { console.log(`Analytics Service Error: ${error.data}`); - }); + } + ); }, initializeSession({ userId, sessionId, userAgent, referrer }) { const payload = { @@ -1113,10 +1107,12 @@ export const useMainStore = defineStore({ endpoint: endpoints.InitializeSession.url, payload, logApiCall: false - }).then((response) => response, + }).then( + (response) => response, (error) => { console.log(`Analytics Service Error: ${error.data}`); - }); + } + ); }, updateLastPageVisited(lastPageVisited) { @@ -1290,19 +1286,17 @@ export const useMainStore = defineStore({ // Private Functions function getHasRecalibrationPart(state) { - const hasRequiresRecalibration - = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, - 'requiresRecalibration')?.length > 0; - const hasRecalibrationType - = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, - 'recalibrationType')?.length > 0; + const hasRequiresRecalibration = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, 'requiresRecalibration')?.length > 0; + const hasRecalibrationType = getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, 'recalibrationType')?.length > 0; if (hasRequiresRecalibration) { if (hasRecalibrationType) { // Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType' return ( - getNonFalseValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, - 'recalibrationType')[0].toLowerCase() !== 'unknown' + getNonFalseValuesOfPropertyInArrayOfObjects( + state.order.lineItems.glassParts, + 'recalibrationType' + )[0].toLowerCase() !== 'unknown' ); } // Has 'requiresRecalibration' but no 'recalibrationType' at all From cc893b6eacc8d217e295b83ca0e4d4da3fafcb73 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 31 Aug 2023 13:16:44 -0400 Subject: [PATCH 13/13] clear error list on enable/disable --- .../dropdown-question/dropdown-question.vue | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/digital-components/dropdown-question/dropdown-question.vue b/src/digital-components/dropdown-question/dropdown-question.vue index 25a850d2..05f8b9a4 100644 --- a/src/digital-components/dropdown-question/dropdown-question.vue +++ b/src/digital-components/dropdown-question/dropdown-question.vue @@ -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); }