From 6a8409cd345863d01037856714a6e72d1d52952b Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:03:40 -0400 Subject: [PATCH 1/3] CSR-702 Add basic routing for part-questions --- .../button-question/button-question.vue | 2 +- src/layouts/part-questions/part-questions.vue | 2 +- .../side-door-options/side-door-options.vue | 2 +- .../glass-part-question.vue | 3 ++- src/layouts/vehicle-parts/vehicle-parts.vue | 19 +++++++++---------- src/mixins/vehicle-questions-mixin.js | 10 ++++++++++ src/mixins/vehicle-questions-mixin.spec.js | 0 src/mixins/vin-pages-mixin.js | 8 +++++--- src/router/index.js | 7 +++++-- .../router-constants/navigation-scenarios.js | 4 +++- src/router/router-constants/routing-table.js | 12 ++++++++---- src/store/index.js | 7 ++++++- .../list-button-horizontal.vue | 8 ++++---- src/ux-components/list-button/list-button.vue | 8 ++++---- src/ux-components/list-card/list-card.vue | 6 +----- 15 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 src/mixins/vehicle-questions-mixin.js create mode 100644 src/mixins/vehicle-questions-mixin.spec.js diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index ee9ecdbad..6848285b8 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -89,7 +89,7 @@ export default { modelValue: [Array, String], validationRules: String, suppressError: Boolean, - useTextForValue: Boolean + useTextForValue: Boolean, }, computed: { formattedGroupName() { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index f5ec4841d..ee1d81c09 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions.filter((p) => { + partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue index b4df1121e..284c3eee6 100644 --- a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue @@ -112,7 +112,7 @@ export default ({ this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides, this.selectedValues.selectedDriverSideReplaceOptions, newValue); } }, - answersToDisplay(){ + answersToDisplay(){ const filteredAnswers = Array.isArray(this.answersFromCms) ? this.answersFromCms.filter(ans => { diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index 608cf55cb..b46a2f9bc 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,6 +48,7 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import store from "@/store"; export default { name: "glass-part-question", @@ -152,7 +153,7 @@ export default { }, PartDataFromApi() { - return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index ce5727ce3..c35699c4e 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -63,9 +63,11 @@ import store from "@/store"; import { Form } from "vee-validate"; import { storeActions } from "@/constants/store-actions"; + import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { name: "vehicle-parts", + mixins: [vehicleQuestionsMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); @@ -173,19 +175,16 @@ methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) - if ( - store.getters.damage.isRepair != null && - Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) - .length !== 0 - ) { - return true; - } - - return false; + return store.getters.damage.isRepair != null && + Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { + console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) + const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); + const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; + this.$router.navigate( - this.navigationScenarios.CLICKED_BACK, + backNavigationScenario, this.$route ); }, diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js new file mode 100644 index 000000000..7a8f3832f --- /dev/null +++ b/src/mixins/vehicle-questions-mixin.js @@ -0,0 +1,10 @@ +export default { + methods: { + hasPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + }, + hasGlassLocationWithMultipleParts(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.parts?.length > 1); + } + } +} \ No newline at end of file diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index fce96c980..31fa44cf7 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -2,15 +2,17 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { + mixins: [vehicleQuestionsMixin], methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); const partsOrQuestions = result.data.partsOrQuestions; - const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); - const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); + const hasPartsQuestions = this.hasPartQuestions(partsOrQuestions); + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); if (hasPartsQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data); @@ -23,6 +25,6 @@ export default { this.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); } - } + }, } } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d2a5ee154..d086cc89a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -173,8 +173,11 @@ async function navigate(scenario, currentRoute, optionalQuery = {}, optionalPara if (destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. - // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. - baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + // Update page data to the store for next page if provided. Otherwise, use existing page data or override with empty object + const existingPageData = store.getters.pageData(destinationFmgPageValue) ?? {}; + if (Object.keys(optionalPageData).length > 0 && Object.keys(existingPageData).length === 0) { + baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + } // if cookie and referralNumber/Date exists OR an emailAddress has been saved if ((getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) || store.getters.order.customer?.emailAddress) { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5768c55de..61de8147f 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -19,7 +19,9 @@ const navigationScenarios = { SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", - SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" + SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY", + CLICKED_BACK_WITH_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITH_PART_QUESTION_ANSWERS", + CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS" }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 25463bd8b..0c729607f 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -82,10 +82,6 @@ const routingTable = function(store) { { fmgPageValue: fmgPageValues.VEHICLE_PARTS, maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, { scenario: navigationScenarios.SELECTED_PARTS, destinationFmgPageValue: fmgPageValues.QUOTE, @@ -94,6 +90,14 @@ const routingTable = function(store) { scenario: navigationScenarios.CLICKED_FORWARD, destinationFmgPageValue: fmgPageValues.REVEAL, }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, ], }, { diff --git a/src/store/index.js b/src/store/index.js index 90932c8bb..200389734 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,7 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/se import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "../constants/store-actions"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Export State const getDefaultState = () => { @@ -264,7 +265,10 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { + console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; + state.order.damage.partQuestionAnswers = null; + state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; }, resetState(state) { Object.assign(state, getDefaultState()); @@ -701,7 +705,7 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { - context.commit(storeMutations.RESET_STATE); + // context.commit(storeMutations.RESET_STATE); context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); return response; }); @@ -854,6 +858,7 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values + // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index 2fef5119f..5bcfcc706 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index 34b6f92e0..cef450bb6 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index a4ef7eac8..002fb14ac 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -110,10 +110,6 @@ export default { this.checkValue = this.selectedValues == this.value || this.modelValue == this.value; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, computed: { getLabelClasses() { if (this.isWide) { @@ -185,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - checkedValue: props.value, // EX: "Single" or "Passenger" + // checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 7e5fb4c906903f2c657553327b50e091e10add72 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:31:20 -0400 Subject: [PATCH 2/3] CSR-702 Cleanup --- src/layouts/part-questions/part-questions.vue | 2 +- src/layouts/vehicle-parts/vehicle-parts.vue | 3 --- src/store/index.js | 2 -- .../list-button-horizontal/list-button-horizontal.vue | 4 ---- src/ux-components/list-button/list-button.vue | 4 ---- src/ux-components/list-card/list-card.vue | 2 +- 6 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 3f779ace8..ff5f494c1 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -142,7 +142,7 @@ export default { if (!partsLookup) { return } - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; + const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; // test response data for multiple parts const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 75ba3df7f..80cdf8a97 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -157,7 +157,6 @@ export default { Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { - console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; @@ -167,8 +166,6 @@ export default { ); }, async forwardButtonAction() { - const selectedGlassPartNumbers = []; - const matchedParts = []; let isMoldingQuestions = false; // Match them to the parts from the API. diff --git a/src/store/index.js b/src/store/index.js index d6c09b22c..f3e3cf96a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -265,7 +265,6 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { - console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; state.order.damage.partQuestionAnswers = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; @@ -866,7 +865,6 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values - // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index 5bcfcc706..4c9670097 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index cef450bb6..aabb06ae5 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index 002fb14ac..a1c95157f 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -181,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - // checkedValue: props.value, // EX: "Single" or "Passenger" + checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 18524de9a6fe74b3f2bc4a142861a2db1173c4d4 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 16:02:53 -0400 Subject: [PATCH 3/3] CSR-702 Add vehicle-questions-mixin tests --- src/layouts/part-questions/part-questions.vue | 2 +- .../glass-part-question.vue | 3 +- src/mixins/vehicle-questions-mixin.spec.js | 161 ++++++++++++++++++ 3 files changed, 163 insertions(+), 3 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index ff5f494c1..6f18408b7 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { + partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index b46a2f9bc..608cf55cb 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,7 +48,6 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; -import store from "@/store"; export default { name: "glass-part-question", @@ -153,7 +152,7 @@ export default { }, PartDataFromApi() { - return store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index e69de29bb..01d41b9c8 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -0,0 +1,161 @@ +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import { shallowMount } from "@vue/test-utils"; +import { setupMocksForJsFiles, getMountOptions } from "@/helpers/unit-test-helper.js"; + +describe("vehicle-questions-mixin", () => { + describe("hasPartQuestions", () => { + test("has no part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has undefined part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has part questions => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [{ + testProperty: "some value" + }] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(true); + }); + }); + + describe("hasGlassLocationWithMultipleParts", () => { + test("has one part for one glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has one part for every glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [{ + partNumber: "1234569" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has multiple parts for one glass location => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [ + { + partNumber: "1234569" + }, + { + partNumber: "1234560" + } + ] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(true); + }); + }); +}); + +function setupMocks({}) { + const baseMixin = setupMocksForJsFiles({}); + + const mocks = getMountOptions({ + router: { + navigate: jest.fn() + }, + }); + + const mockVehicleQuestionComponent = { + template: '
', + mixins: [vehicleQuestionsMixin, baseMixin.baseMixin] + }; + + const wrapper = shallowMount(mockVehicleQuestionComponent, mocks); + + return { wrapper }; +} \ No newline at end of file