INSR-7759: Update review sections, move contact details drawer
This commit is contained in:
parent
be4bed44fe
commit
4e996145c3
20 changed files with 219 additions and 1297 deletions
|
|
@ -70,9 +70,7 @@ const errorMessages = Object.freeze({
|
||||||
TPA_SEARCH_SHOP_FORMAT: 'Please enter a valid shop name.',
|
TPA_SEARCH_SHOP_FORMAT: 'Please enter a valid shop name.',
|
||||||
TPA_SEARCH_REQUIRED: 'Please enter a shop name or ZIP code.',
|
TPA_SEARCH_REQUIRED: 'Please enter a shop name or ZIP code.',
|
||||||
SERVICE_ADDRESS_REQUIRED: 'Service street address is required.',
|
SERVICE_ADDRESS_REQUIRED: 'Service street address is required.',
|
||||||
SERVICE_CITY_REQUIRED: 'Service city is required.',
|
SERVICE_CITY_REQUIRED: 'Service city is required.'
|
||||||
|
|
||||||
PAYMENT_METHOD_PAGE_OPTION_REQUIRED: 'Please select an Option',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default errorMessages;
|
export default errorMessages;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Components
|
// Components
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue';
|
import contactDetailsDrawer from '@/iss-components/contact-details-drawer/contact-details-drawer.vue';
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<baseInputButton
|
<baseInputButton
|
||||||
v-bind="$props"
|
v-bind="$props"
|
||||||
v-model="selectedValue"
|
v-model="selectedValue"
|
||||||
buttonWrapperClasses="list-group base-input-button list-button d-flex flex-column w-100 no-hover">
|
buttonWrapperClasses="list-group base-input-button list-button payment-method d-flex flex-column w-100 no-hover">
|
||||||
<div class="button-content list-button-content d-flex flex-row">
|
<div class="button-content list-button-content d-flex flex-row">
|
||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.list-button {
|
.list-button.payment-method.list-group {
|
||||||
outline: none;
|
outline: none;
|
||||||
input[type="radio"],
|
input[type="radio"],
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
|
|
@ -83,7 +83,19 @@ export default {
|
||||||
color: $black;
|
color: $black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&.has-error {
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"] {
|
||||||
|
&:focus + .list-button-content {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-button-content {
|
.list-button-content {
|
||||||
color: $darker-gray;
|
color: $darker-gray;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
@ -96,6 +108,5 @@ export default {
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: .625rem 2rem;
|
padding: .625rem 2rem;
|
||||||
height: 2.875rem;
|
height: 2.875rem;
|
||||||
margin-bottom: .75rem;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,10 @@
|
||||||
cmsWidgetName="SiteSubHeaderWidget" />
|
cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
<div class="main-content-container">
|
<div class="main-content-container">
|
||||||
<hr class="section-divider" />
|
<hr class="section-divider" />
|
||||||
<reviewDropdown ref="reviewDropdown" />
|
<reviewDropdown
|
||||||
<hr class="section-divider" />
|
ref="reviewDropdown"
|
||||||
|
@edit-clicked="handleEditClicked"
|
||||||
|
/>
|
||||||
<div class="cart-header">
|
<div class="cart-header">
|
||||||
<span class="cart-label">{{ cartHeaderText }}</span>
|
<span class="cart-label">{{ cartHeaderText }}</span>
|
||||||
<span v-if="showCartTotal" class="cart-value">{{ cartTotal }}</span>
|
<span v-if="showCartTotal" class="cart-value">{{ cartTotal }}</span>
|
||||||
|
|
@ -104,6 +106,7 @@ import paymentMethodQuestion from '@/layouts/payment-method/payment-method-quest
|
||||||
import alert from '@/ux-components/alert/alert.vue';
|
import alert from '@/ux-components/alert/alert.vue';
|
||||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
import buttonQuestion from '@/digital-components/button-question/button-question.vue';
|
||||||
|
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
||||||
|
|
||||||
// Supporting Items
|
// Supporting Items
|
||||||
import settleAllPromises from '@/helpers/layout-helper';
|
import settleAllPromises from '@/helpers/layout-helper';
|
||||||
|
|
@ -112,7 +115,7 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { paymentMethods } from '@/constants/payment-method-constants';
|
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||||
import queryStrings from '@/constants/query-strings';
|
import queryStrings from '@/constants/query-strings';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
import { defineRule, Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import issPageValues from '@/router/router-constants/issPage-values';
|
import issPageValues from '@/router/router-constants/issPage-values';
|
||||||
import bailoutMessage from '@/constants/bailoutMessage';
|
import bailoutMessage from '@/constants/bailoutMessage';
|
||||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||||
|
|
@ -124,13 +127,8 @@ import { supportsApplePay } from '@/helpers/browser-helper';
|
||||||
import { getCartTotal } from '@/helpers/cart-helper';
|
import { getCartTotal } from '@/helpers/cart-helper';
|
||||||
import { formatAmountInDollars } from '@/helpers/text-helper';
|
import { formatAmountInDollars } from '@/helpers/text-helper';
|
||||||
import widgetFields from '@/constants/cms-widget-fields';
|
import widgetFields from '@/constants/cms-widget-fields';
|
||||||
import errorMessages from '@/constants/error-messages';
|
|
||||||
import { required } from '@/helpers/validation-rules';
|
|
||||||
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
|
||||||
import MaskaFormattedMasks from '@/constants/maska-masks';
|
import MaskaFormattedMasks from '@/constants/maska-masks';
|
||||||
|
|
||||||
defineRule('option-required', required(errorMessages.PAYMENT_METHOD_PAGE_OPTION_REQUIRED));
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'payment-method',
|
name: 'payment-method',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -391,13 +389,43 @@ export default {
|
||||||
const scenario = this.mainStore.isMobileAppointment
|
const scenario = this.mainStore.isMobileAppointment
|
||||||
? this.navigationScenarios.CLICKED_BACK_MOBILE
|
? this.navigationScenarios.CLICKED_BACK_MOBILE
|
||||||
: this.navigationScenarios.CLICKED_BACK_INSHOP;
|
: this.navigationScenarios.CLICKED_BACK_INSHOP;
|
||||||
this.$router.navigate(
|
this.$router.navigateWithSpinner(
|
||||||
scenario,
|
scenario,
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getSMSPhoneFromStore() {
|
getSMSPhoneFromStore() {
|
||||||
return useMainStore().contactInfo.servicePhone;
|
return useMainStore().contactInfo.servicePhone;
|
||||||
|
},
|
||||||
|
handleEditClicked(section) {
|
||||||
|
switch (section) {
|
||||||
|
case 'location':
|
||||||
|
this.$router.navigateWithSpinner(
|
||||||
|
this.navigationScenarios.EDIT_SERVICE_LOCATION,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'schedule':
|
||||||
|
this.$router.navigateWithSpinner(
|
||||||
|
this.navigationScenarios.EDIT_SCHEDULE,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'vehicle':
|
||||||
|
this.$router.navigateWithSpinner(
|
||||||
|
this.navigationScenarios.EDIT_VEHICLE,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'customer':
|
||||||
|
break;
|
||||||
|
case 'wipers':
|
||||||
|
this.$router.navigateWithSpinner(
|
||||||
|
this.navigationScenarios.EDIT_WIPERS,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,55 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="py-3">
|
<div class="block-container">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<textBlock
|
<textBlock
|
||||||
:cmsWidgetName="headerCmsWidgetName"
|
:cmsWidgetName="headerCmsWidgetName"
|
||||||
:customText="customHeaderText"
|
:customText="customHeaderText"
|
||||||
typeStyle="body small dark"
|
typeStyle="body dark"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
:marginTopSizeOverride="0" />
|
:marginTopSizeOverride="0" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="review-block-body-container">
|
||||||
v-for="item in content"
|
<div
|
||||||
:key="item"
|
v-for="item in content"
|
||||||
class="small review-block-content"
|
:key="item"
|
||||||
data-test="contentLine"
|
class="review-block-content"
|
||||||
v-html="item"></div>
|
data-test="contentLine"
|
||||||
|
v-html="item"></div>
|
||||||
|
<div
|
||||||
|
class="link-container"
|
||||||
|
:class="{ 'expanded': linkVisible }">
|
||||||
|
<textLink
|
||||||
|
linkType="text"
|
||||||
|
:text="editLinkText"
|
||||||
|
useLoadingModal
|
||||||
|
href="javascript:void(0)"
|
||||||
|
class="link"
|
||||||
|
@clickEvent="linkClicked">
|
||||||
|
</textLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
|
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'review-block',
|
name: 'review-block',
|
||||||
components: {
|
components: {
|
||||||
textBlock
|
textBlock,
|
||||||
|
textLink
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
headerCmsWidgetName: String,
|
headerCmsWidgetName: String,
|
||||||
customHeaderText: String,
|
customHeaderText: String,
|
||||||
content: Array // Specifically an array of strings.
|
content: Array, // Specifically an array of strings.
|
||||||
|
editLinkText: {
|
||||||
|
type: String,
|
||||||
|
default: 'Edit'
|
||||||
|
},
|
||||||
|
linkVisible: Boolean
|
||||||
},
|
},
|
||||||
emits: ['edit-clicked'],
|
emits: ['edit-clicked'],
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -51,7 +72,17 @@ export default {
|
||||||
:deep(.review-block-content > ul) {
|
:deep(.review-block-content > ul) {
|
||||||
margin-bottom: 0rem;
|
margin-bottom: 0rem;
|
||||||
}
|
}
|
||||||
.review-block-content {
|
.review-block-body-container {
|
||||||
width: 90%;
|
margin-top: .625rem;
|
||||||
|
}
|
||||||
|
.link-container {
|
||||||
|
max-height: 0;
|
||||||
|
transition: $transition-swing;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.expanded {
|
||||||
|
margin-top: .625rem;
|
||||||
|
max-height: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,35 +11,29 @@
|
||||||
<span class="label">Appointment details</span>
|
<span class="label">Appointment details</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="review-table px-4">
|
<div class="review-table">
|
||||||
<vehicleReview
|
|
||||||
cmsWidgetName="VehicleReviewWidget"
|
|
||||||
:vehicle="vehicleInfo" />
|
|
||||||
<hr class="review-divider" />
|
|
||||||
<damageReview
|
|
||||||
cmsWidgetName="DamageReviewWidget"
|
|
||||||
damageLocationsWidgetName="DamageLocationsWidget"
|
|
||||||
:damage="damageInfo" />
|
|
||||||
<hr class="review-divider" />
|
|
||||||
<servicePackageReview
|
|
||||||
ref="servicePackageReview"
|
|
||||||
servicePackageOptionsCmsName="ServicePackageTitle"
|
|
||||||
defaultPackageItemsCmsName="DefaultPackageItemDescriptions"
|
|
||||||
vapsItemsCmsName="VapsItemDescriptions"
|
|
||||||
:damage="damageInfo"
|
|
||||||
:lineItems="lineItems" />
|
|
||||||
<hr class="review-divider" />
|
|
||||||
<serviceLocationReview
|
<serviceLocationReview
|
||||||
cmsWidgetName="ServiceLocationTitleWidget"
|
:linkVisible="isExpanded"
|
||||||
:serviceLocation="serviceLocationInfo" />
|
cmsWidgetName="ServiceLocationWidget"
|
||||||
<hr class="review-divider" />
|
:serviceLocation="serviceLocationInfo"
|
||||||
|
@edit-clicked="editServiceLocation" />
|
||||||
<scheduleReview
|
<scheduleReview
|
||||||
|
:linkVisible="isExpanded"
|
||||||
cmsWidgetName="ScheduleWidget"
|
cmsWidgetName="ScheduleWidget"
|
||||||
:appointmentType="appointmentType" />
|
@edit-clicked="editSchedule" />
|
||||||
<hr class="review-divider" />
|
<hr class="section-divider" />
|
||||||
<customerReview
|
<div class="review-table-expander">
|
||||||
cmsWidgetName="CustomerReviewWidget"
|
<vehicleReview
|
||||||
:customer="customerInfo" />
|
:linkVisible="true"
|
||||||
|
cmsWidgetName="VehicleReviewWidget"
|
||||||
|
@edit-clicked="editVehicle" />
|
||||||
|
<hr class="section-divider" />
|
||||||
|
<customerReview
|
||||||
|
:linkVisible="true"
|
||||||
|
cmsWidgetName="CustomerReviewWidget"
|
||||||
|
@edit-clicked="editCustomer" />
|
||||||
|
<hr class="section-divider" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -47,26 +41,18 @@
|
||||||
<script>
|
<script>
|
||||||
// import textBlock from '@/digital-components/text-block/text-block.vue';
|
// import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
import customerReview from '@/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue';
|
import customerReview from '@/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue';
|
||||||
import damageReview from '@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue';
|
|
||||||
import scheduleReview from '@/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue';
|
import scheduleReview from '@/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue';
|
||||||
import
|
import serviceLocationReview from '@/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue';
|
||||||
serviceLocationReview from '@/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue';
|
|
||||||
import
|
|
||||||
servicePackageReview
|
|
||||||
from '@/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue';
|
|
||||||
import vehicleReview from '@/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue';
|
import vehicleReview from '@/layouts/payment-method/review-dropdown/review-sections/vehicle-review/vehicle-review.vue';
|
||||||
|
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import settleAllPromises from '@/helpers/layout-helper';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'review-dropdown',
|
name: 'review-dropdown',
|
||||||
components: {
|
components: {
|
||||||
customerReview,
|
customerReview,
|
||||||
damageReview,
|
|
||||||
scheduleReview,
|
scheduleReview,
|
||||||
serviceLocationReview,
|
serviceLocationReview,
|
||||||
servicePackageReview,
|
|
||||||
vehicleReview
|
vehicleReview
|
||||||
},
|
},
|
||||||
props: {},
|
props: {},
|
||||||
|
|
@ -79,12 +65,6 @@ export default {
|
||||||
vehicleInfo() {
|
vehicleInfo() {
|
||||||
return useMainStore().vehicle;
|
return useMainStore().vehicle;
|
||||||
},
|
},
|
||||||
damageInfo() {
|
|
||||||
return useMainStore().damage;
|
|
||||||
},
|
|
||||||
lineItems() {
|
|
||||||
return useMainStore().lineItems;
|
|
||||||
},
|
|
||||||
serviceLocationInfo() {
|
serviceLocationInfo() {
|
||||||
return useMainStore().order.serviceLocation;
|
return useMainStore().order.serviceLocation;
|
||||||
},
|
},
|
||||||
|
|
@ -95,9 +75,22 @@ export default {
|
||||||
return useMainStore().contactInfo;
|
return useMainStore().contactInfo;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
emits: ['edit-clicked'],
|
||||||
methods: {
|
methods: {
|
||||||
toggleIsExpanded() {
|
toggleIsExpanded() {
|
||||||
this.isExpanded = !this.isExpanded;
|
this.isExpanded = !this.isExpanded;
|
||||||
|
},
|
||||||
|
editServiceLocation() {
|
||||||
|
this.$emit('edit-clicked', 'location');
|
||||||
|
},
|
||||||
|
editSchedule() {
|
||||||
|
this.$emit('edit-clicked', 'schedule');
|
||||||
|
},
|
||||||
|
editVehicle() {
|
||||||
|
this.$emit('edit-clicked', 'vehicle');
|
||||||
|
},
|
||||||
|
editCustomer() {
|
||||||
|
this.$emit('edit-clicked', 'customer');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -111,14 +104,19 @@ export default {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-table {
|
.review-table-expander {
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
transition: all 350ms ease-in;
|
transition: $transition-swing;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
visibility: hidden;
|
}
|
||||||
|
|
||||||
|
.section-divider {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-toggle {
|
.review-toggle {
|
||||||
|
margin-bottom: .625rem;
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
transition: transform none;
|
transition: transform none;
|
||||||
|
|
@ -129,17 +127,13 @@ export default {
|
||||||
width: 1.25rem;
|
width: 1.25rem;
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
position: relative;
|
|
||||||
right: 0.75rem;
|
|
||||||
margin: 0.5rem 0 0.5rem 1rem;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
&.expanded:after {
|
&.expanded:after {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
&.expanded + .review-table {
|
&.expanded + .review-table .review-table-expander {
|
||||||
max-height: 800px;
|
max-height: 24rem;
|
||||||
transition: all 150ms ease-in;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<reviewBlock
|
<reviewBlock
|
||||||
:customHeaderText="header"
|
:customHeaderText="header"
|
||||||
:content="displayContent" />
|
:content="displayContent"
|
||||||
|
:editLinkText="editLinkText" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -13,30 +14,20 @@ export default {
|
||||||
reviewBlock
|
reviewBlock
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String
|
||||||
customer: Object
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
displayContent() {
|
displayContent() {
|
||||||
return [this.fullName, this.email, this.phoneNumber, this.smsOptIn];
|
return [this.getCmsContent(this.cmsWidgetName, 'BodyText')];
|
||||||
},
|
},
|
||||||
header() {
|
header() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
},
|
},
|
||||||
fullName() {
|
editLinkText() {
|
||||||
return `${this.customer?.firstName} ${this.customer?.lastName}`;
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
},
|
|
||||||
email() {
|
|
||||||
return this.customer?.emailAddress;
|
|
||||||
},
|
|
||||||
phoneNumber() {
|
|
||||||
return this.customer?.servicePhone;
|
|
||||||
},
|
|
||||||
smsOptIn() {
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'SubheaderText');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
// Components
|
|
||||||
import damageReview from '@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue';
|
|
||||||
|
|
||||||
// Supporting Files
|
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
|
||||||
import { getDamageDisplayContent } from '@/helpers/damage-review-content-generator.js';
|
|
||||||
import baseMixin from '@/mixins/base-mixin';
|
|
||||||
|
|
||||||
jest.mock('@/helpers/damage-review-content-generator.js', () => ({
|
|
||||||
getDamageDisplayContent: jest.fn(),
|
|
||||||
getLocationAnswer: jest.fn()
|
|
||||||
}));
|
|
||||||
|
|
||||||
let cmsContent;
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
...baseMixin.methods,
|
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getShallowMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) {
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const testingPinia = createTestingPinia({
|
|
||||||
initialState: {
|
|
||||||
main: mainInitialState
|
|
||||||
}
|
|
||||||
});
|
|
||||||
useMainStore(testingPinia);
|
|
||||||
methodToRun();
|
|
||||||
|
|
||||||
mountOptions.global.plugins = [testingPinia];
|
|
||||||
mountOptions.data = () => (
|
|
||||||
initialData
|
|
||||||
);
|
|
||||||
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
|
|
||||||
const wrapper = shallowMount(damageReview, mountOptions);
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
getDamageDisplayContent.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Damage Review Block', () => {
|
|
||||||
test('computed displayContent calls getDamageDisplayContent with expected', () => {
|
|
||||||
// Arrange
|
|
||||||
const glassToReplace = ['front-window', 'side-window'];
|
|
||||||
const isRepair = false;
|
|
||||||
const initialStore = {
|
|
||||||
order: {
|
|
||||||
damage: {
|
|
||||||
glassToReplace,
|
|
||||||
isRepair
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const expected = ['a', 'v', 'n'];
|
|
||||||
getDamageDisplayContent.mockImplementationOnce(() => expected);
|
|
||||||
const { wrapper } = getShallowMountedComponent(initialStore, {});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = wrapper.vm.displayContent;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(result).toStrictEqual(expected);
|
|
||||||
expect(getDamageDisplayContent).toBeCalledTimes(1);
|
|
||||||
expect(getDamageDisplayContent).toBeCalledWith([], [], [], glassToReplace, isRepair);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
<template>
|
|
||||||
<reviewBlock
|
|
||||||
:headerCmsWidgetName="cmsWidgetName"
|
|
||||||
:content="displayContent" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import damageLocationsSelected from '@/constants/damage-locations-selected.js';
|
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
import { getDamageDisplayContent, getLocationAnswer } from '@/helpers/damage-review-content-generator.js';
|
|
||||||
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'damage-review',
|
|
||||||
components: {
|
|
||||||
reviewBlock
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
cmsWidgetName: String,
|
|
||||||
damageLocationsWidgetName: String,
|
|
||||||
damage: Object
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
displayContent() {
|
|
||||||
const { glassToReplace, isRepair } = useMainStore().order.damage;
|
|
||||||
return getDamageDisplayContent(
|
|
||||||
this.locationAnswers,
|
|
||||||
this.driverSideDamageAnswers,
|
|
||||||
this.passengerSideDamageAnswers,
|
|
||||||
glassToReplace,
|
|
||||||
isRepair
|
|
||||||
);
|
|
||||||
},
|
|
||||||
driverSideDamageAnswers() {
|
|
||||||
const answerContent = getLocationAnswer(damageLocationsSelected.DRIVER, this.locationAnswers);
|
|
||||||
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
|
|
||||||
},
|
|
||||||
passengerSideDamageAnswers() {
|
|
||||||
const answerContent = getLocationAnswer(damageLocationsSelected.PASSENGER, this.locationAnswers);
|
|
||||||
return this.getInputQuestionWidgetAnswersNullSafe(answerContent?.SubWidgetName);
|
|
||||||
},
|
|
||||||
locationAnswers() {
|
|
||||||
return this.getInputQuestionWidgetAnswersNullSafe(this.damageLocationsWidgetName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<reviewBlock
|
<reviewBlock
|
||||||
:customHeaderText="headerText"
|
:customHeaderText="headerText"
|
||||||
:content="displayContent" />
|
:content="displayContent"
|
||||||
|
:editLinkText="editLinkText" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -13,8 +14,7 @@ export default {
|
||||||
reviewBlock
|
reviewBlock
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String
|
||||||
appointmentType: String
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -28,6 +28,9 @@ export default {
|
||||||
},
|
},
|
||||||
headerText() {
|
headerText() {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
|
editLinkText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<reviewBlock
|
<reviewBlock
|
||||||
:headerCmsWidgetName="cmsWidgetName"
|
:customHeaderText="headerText"
|
||||||
:content="displayContent" />
|
:content="displayContent"
|
||||||
|
:editLinkText="editLinkText" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||||
|
import { toTitleCase } from '@/helpers/text-helper';
|
||||||
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -21,11 +23,14 @@ export default {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
headerText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
displayContent() {
|
displayContent() {
|
||||||
return [
|
return [
|
||||||
`${this.addressInfo.address}${this.addressInfo.address2 ? ', ' : ''}${
|
`${this.addressInfo.address}${this.addressInfo.address2 ? ', ' : ''}${
|
||||||
this.addressInfo.address2
|
this.addressInfo.address2
|
||||||
}, ${this.addressInfo.city}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`
|
}, ${toTitleCase(this.addressInfo.city)}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
addressInfo() {
|
addressInfo() {
|
||||||
|
|
@ -46,6 +51,9 @@ export default {
|
||||||
state: this.serviceLocation?.provider?.address?.state,
|
state: this.serviceLocation?.provider?.address?.state,
|
||||||
zipCode: this.serviceLocation?.provider?.address?.zipCode
|
zipCode: this.serviceLocation?.provider?.address?.zipCode
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
editLinkText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,965 +0,0 @@
|
||||||
// Components
|
|
||||||
import
|
|
||||||
servicePackageReview from '@/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue';
|
|
||||||
|
|
||||||
// Supporting Files
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
|
||||||
import packageNames from '@/constants/package-names';
|
|
||||||
import partTypeStrings from '@/constants/part-type-strings';
|
|
||||||
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
|
|
||||||
const testConstants = {
|
|
||||||
cmsPropValues: {
|
|
||||||
servicePackageOptionsCmsName: 'ServicePackageTitle',
|
|
||||||
defaultPackageItemsCmsName: 'DefaultPackageItemDescriptions',
|
|
||||||
vapsItemsCmsName: 'VapsItemDescriptions'
|
|
||||||
},
|
|
||||||
widgetNames: {
|
|
||||||
tierOneTitle: 'EconomyServiceTitle',
|
|
||||||
tierTwoTitle: 'StandardServiceTitle',
|
|
||||||
tierThreeTitle: 'PremiumServiceTitle'
|
|
||||||
},
|
|
||||||
defaultItemCopy: {
|
|
||||||
itemOne: 'Item Description 1',
|
|
||||||
itemTwo: 'Item Description 2',
|
|
||||||
itemThree: 'Item Description 3',
|
|
||||||
itemFour: 'Item Description 4',
|
|
||||||
defaultItemCopyArray: ['Item Description 1', 'Item Description 2', 'Item Description 3']
|
|
||||||
},
|
|
||||||
vapsCopy: {
|
|
||||||
frontWiperCopy: 'Front Wiper copy',
|
|
||||||
rearWiperCopy: 'Rear Wiper copy',
|
|
||||||
rainDefenseCopy: 'Rain repel copy'
|
|
||||||
},
|
|
||||||
parts: {
|
|
||||||
frontWiperPart: {
|
|
||||||
partNumber: 'SBB16',
|
|
||||||
description: 'SAFELITE BEAM BLADE 16',
|
|
||||||
partType: 'FRONT WIPER',
|
|
||||||
price: 32.64
|
|
||||||
},
|
|
||||||
rearWiperPart: {
|
|
||||||
partNumber: 'SBBR12A',
|
|
||||||
description: 'SAFELITE REAR BLADE 12A',
|
|
||||||
partType: 'REAR WIPER',
|
|
||||||
price: 24.48
|
|
||||||
},
|
|
||||||
rainDefensePart: {
|
|
||||||
partNumber: 'RAIN REPEL',
|
|
||||||
description: null,
|
|
||||||
partType: 'RAIN REPEL',
|
|
||||||
price: 35.5
|
|
||||||
},
|
|
||||||
recalPart: {
|
|
||||||
partNumber: 'RECAL STATIC',
|
|
||||||
Description: 'Recalibration',
|
|
||||||
partType: 'recalibration',
|
|
||||||
Quantity: '1',
|
|
||||||
price: 150.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
damages: {
|
|
||||||
frontWindshield: {
|
|
||||||
glassLocation: damageLocationsSelected.WINDSHIELD,
|
|
||||||
glassName: damageLocationsSelected.SINGLE
|
|
||||||
},
|
|
||||||
rearWindshield: {
|
|
||||||
glassLocation: damageLocationsSelected.REAR,
|
|
||||||
glassName: damageLocationsSelected.STATIONARY
|
|
||||||
},
|
|
||||||
sideGlass: {
|
|
||||||
glassLocation: damageLocationsSelected.PASSENGER,
|
|
||||||
glassName: damageLocationsSelected.QUARTER
|
|
||||||
}
|
|
||||||
},
|
|
||||||
imageId: '00000000-0000-0000-0000-000000000000'
|
|
||||||
};
|
|
||||||
|
|
||||||
const figmaScenarios = [
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_Cash',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.frontWindshield]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard+RearWiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_Standard_Repair',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: true,
|
|
||||||
glassToReplace: []
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard+RearWiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_Recal',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.frontWindshield]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: [testConstants.parts.recalPart]
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard+RearWiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// 05_01_CSR_Quote_RearGlass omitted as a duplicate of below.
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_RearGlass+NonWindshield',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.rearWindshield]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Frontwiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard+RainDefense',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_RearGlass+Windshield',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [
|
|
||||||
testConstants.damages.frontWindshield,
|
|
||||||
testConstants.damages.rearWindshield
|
|
||||||
]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Frontwiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Rearwiper',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+RainDefense',
|
|
||||||
vapsCombo: [testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Frontwiper+RainDefense',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.frontWiperPart,
|
|
||||||
testConstants.parts.rainDefensePart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Rearwiper+RainDefense',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rearWiperPart,
|
|
||||||
testConstants.parts.frontWiperPart,
|
|
||||||
testConstants.parts.rainDefensePart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_RearGlassNoFrontFit',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.rearWindshield]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Raindefense',
|
|
||||||
vapsCombo: [testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// 05_01_CSR_Quote_Windshield+SideGlass has identical outcomes to 05_01_CSR_Quote_Cash, but included in case that changes in the future.
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_Windshield+SideGlass',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [
|
|
||||||
testConstants.damages.frontWindshield,
|
|
||||||
testConstants.damages.sideGlass
|
|
||||||
]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Standard+RearWiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// Has no standard package
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_SideGlass',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.sideGlass]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Frontwiper',
|
|
||||||
vapsCombo: [testConstants.parts.frontWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+RainDefense',
|
|
||||||
vapsCombo: [testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Economy+Rearwiper',
|
|
||||||
vapsCombo: [testConstants.parts.rearWiperPart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium+Rearwiper',
|
|
||||||
vapsCombo: [
|
|
||||||
testConstants.parts.rainDefensePart,
|
|
||||||
testConstants.parts.frontWiperPart,
|
|
||||||
testConstants.parts.rearWiperPart
|
|
||||||
],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// Has no standard package
|
|
||||||
{
|
|
||||||
name: '05_01_CSR_Quote_NoWiperFit',
|
|
||||||
params: {
|
|
||||||
wiperResponse: [],
|
|
||||||
rainDefenseResponse: testConstants.parts.rainDefensePart,
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.frontWindshield]
|
|
||||||
},
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: []
|
|
||||||
},
|
|
||||||
iterations: [
|
|
||||||
{
|
|
||||||
name: 'Economy',
|
|
||||||
vapsCombo: [],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
|
||||||
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Premium',
|
|
||||||
vapsCombo: [testConstants.parts.rainDefensePart],
|
|
||||||
expected: {
|
|
||||||
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
|
||||||
displayContent: [
|
|
||||||
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
|
||||||
testConstants.vapsCopy.rainDefenseCopy
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function generateDefaultProps() {
|
|
||||||
return {
|
|
||||||
servicePackageOptionsCmsName: testConstants.cmsPropValues.servicePackageOptionsCmsName,
|
|
||||||
defaultPackageItemsCmsName: testConstants.cmsPropValues.defaultPackageItemsCmsName,
|
|
||||||
vapsItemsCmsName: testConstants.cmsPropValues.vapsItemsCmsName,
|
|
||||||
lineItems: {
|
|
||||||
glassParts: [],
|
|
||||||
supportingItems: [],
|
|
||||||
vaps: [testConstants.parts.frontWiperPart]
|
|
||||||
},
|
|
||||||
damage: {
|
|
||||||
isRepair: false,
|
|
||||||
glassToReplace: [testConstants.damages.frontWindshield]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let cmsContent;
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function initializeWithDefault() {
|
|
||||||
useMainStore().order.availableVaps = [testConstants.parts.frontWiperPart, testConstants.parts.rainDefensePart];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
methodToRun();
|
|
||||||
|
|
||||||
mountOptions.data = () => (
|
|
||||||
initialData
|
|
||||||
);
|
|
||||||
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
|
|
||||||
const wrapper = shallowMount(servicePackageReview, mountOptions);
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cmsContent = {
|
|
||||||
ServicePackageTitle: {
|
|
||||||
Answers: [
|
|
||||||
{
|
|
||||||
Name: packageNames.TIER_ONE,
|
|
||||||
Text: '',
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: testConstants.widgetNames.tierOneTitle
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: packageNames.TIER_TWO,
|
|
||||||
Text: '',
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: testConstants.widgetNames.tierTwoTitle
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: packageNames.TIER_THREE,
|
|
||||||
Text: '',
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: testConstants.widgetNames.tierThreeTitle
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
DefaultPackageItemDescriptions: {
|
|
||||||
Answers: [
|
|
||||||
{
|
|
||||||
Name: 'Item1',
|
|
||||||
Text: testConstants.defaultItemCopy.itemOne,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: 'Item2',
|
|
||||||
Text: testConstants.defaultItemCopy.itemTwo,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: 'Item3',
|
|
||||||
Text: testConstants.defaultItemCopy.itemThree,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
VapsItemDescriptions: {
|
|
||||||
Answers: [
|
|
||||||
{
|
|
||||||
Name: partTypeStrings.FRONT_WIPER,
|
|
||||||
Text: testConstants.vapsCopy.frontWiperCopy,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: partTypeStrings.REAR_WIPER,
|
|
||||||
Text: testConstants.vapsCopy.rearWiperCopy,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: partTypeStrings.RAIN_DEFENSE,
|
|
||||||
Text: testConstants.vapsCopy.rainDefenseCopy,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Service Package Review Block', () => {
|
|
||||||
describe('General functionality', () => {
|
|
||||||
test('Should properly "Round Down" package tier', async () => {
|
|
||||||
// Slightly longer explanation:
|
|
||||||
// Should only return the highest tier where *every* offered VAP is part of the order.
|
|
||||||
// However, there may be vaps not offered in the qualifying tier. Hence rounding *down*.
|
|
||||||
//
|
|
||||||
// I.e. Economy=[], Standard=[front wipers], Premium=[front wipers, rain defense].
|
|
||||||
// Current vaps=[rain defense]. Though rain defense is in Premium, we don't satisfy it or standard.
|
|
||||||
// So our tier should still be Economy.
|
|
||||||
// Should still display extra vaps.
|
|
||||||
|
|
||||||
// Arrange
|
|
||||||
const props = generateDefaultProps();
|
|
||||||
props.lineItems.vaps = [testConstants.parts.rainDefensePart];
|
|
||||||
|
|
||||||
const { wrapper } = getShallowMountedComponent({
|
|
||||||
...props
|
|
||||||
});
|
|
||||||
|
|
||||||
initializeWithDefault();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.packageNameWidget).toEqual(testConstants.widgetNames.tierOneTitle);
|
|
||||||
|
|
||||||
const containsRainDefenseCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.rainDefenseCopy);
|
|
||||||
expect(containsRainDefenseCopy).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Should display all default items from cms', async () => {
|
|
||||||
// Arrange
|
|
||||||
cmsContent.DefaultPackageItemDescriptions.Answers.push({
|
|
||||||
Name: 'Item4',
|
|
||||||
Text: testConstants.defaultItemCopy.itemFour,
|
|
||||||
SubText: '',
|
|
||||||
ImageId: testConstants.imageId,
|
|
||||||
Image: '',
|
|
||||||
SubWidgetName: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const props = generateDefaultProps();
|
|
||||||
props.lineItems.vaps = [];
|
|
||||||
|
|
||||||
const { wrapper } = getShallowMountedComponent({
|
|
||||||
...props
|
|
||||||
});
|
|
||||||
|
|
||||||
initializeWithDefault();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const expectedResult = [
|
|
||||||
testConstants.defaultItemCopy.itemOne,
|
|
||||||
testConstants.defaultItemCopy.itemTwo,
|
|
||||||
testConstants.defaultItemCopy.itemThree,
|
|
||||||
testConstants.defaultItemCopy.itemFour
|
|
||||||
];
|
|
||||||
|
|
||||||
expect(wrapper.vm.displayContent).toEqual(expectedResult);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Should display vaps if and only if they are added', async () => {
|
|
||||||
// Arrange
|
|
||||||
const props = generateDefaultProps();
|
|
||||||
const { wrapper } = getShallowMountedComponent({
|
|
||||||
...props
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
initializeWithDefault();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.frontWiperCopy);
|
|
||||||
const includesRainDefenseCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.rainDefenseCopy);
|
|
||||||
expect(includesFrontWiperCopy).toBe(true);
|
|
||||||
expect(includesRainDefenseCopy).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Should not error if cms content is missing (though may display poorly).', async () => {
|
|
||||||
// Arrange
|
|
||||||
cmsContent = {};
|
|
||||||
const props = generateDefaultProps();
|
|
||||||
const { wrapper } = getShallowMountedComponent({
|
|
||||||
...props
|
|
||||||
});
|
|
||||||
|
|
||||||
initializeWithDefault();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.packageNameWidget).toEqual('');
|
|
||||||
expect(wrapper.vm.displayContent).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Match Figma Scenarios', () => {
|
|
||||||
figmaScenarios.forEach((scenario) => {
|
|
||||||
scenario.iterations.forEach((iteration) => {
|
|
||||||
it(`Should match figma scenario "${scenario.name}", iteration "${iteration.name}"`, async () => {
|
|
||||||
// Arrange
|
|
||||||
const props = generateDefaultProps();
|
|
||||||
props.damage = scenario.params.damage;
|
|
||||||
props.glassParts = scenario.params.glassParts;
|
|
||||||
props.lineItems.supportingItems = scenario.params.supportingItems;
|
|
||||||
props.lineItems.vaps = iteration.vapsCombo;
|
|
||||||
|
|
||||||
const { wrapper } = getShallowMountedComponent({
|
|
||||||
...props
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().order.availableVaps = [scenario.params.rainDefenseResponse, ...scenario.params.wiperResponse];
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.packageNameWidget).toEqual(iteration.expected.packageNameWidget);
|
|
||||||
expect(wrapper.vm.displayContent).toEqual(iteration.expected.displayContent);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
<template>
|
|
||||||
<reviewBlock
|
|
||||||
:headerCmsWidgetName="packageNameWidget"
|
|
||||||
:content="displayContent" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import settleAllPromises from '@/helpers/layout-helper';
|
|
||||||
// import baseMixin from '@/mixins/base-mixin.js';
|
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
|
||||||
import {
|
|
||||||
getHighestFullySatisfiedTier,
|
|
||||||
containsLineItemWithPartType
|
|
||||||
} from '@/helpers/service-package-helper.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'service-package-review',
|
|
||||||
components: {
|
|
||||||
reviewBlock
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
servicePackageOptionsCmsName: String,
|
|
||||||
defaultPackageItemsCmsName: String,
|
|
||||||
vapsItemsCmsName: String,
|
|
||||||
lineItems: Object,
|
|
||||||
damage: Object
|
|
||||||
},
|
|
||||||
emits: ['edit-clicked'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
availableVaps: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
displayContent() {
|
|
||||||
return [...this.defaultPackageText, ...this.vapsItemText];
|
|
||||||
},
|
|
||||||
packageNameWidget() {
|
|
||||||
const servicePackageNames = this.getCmsContent(
|
|
||||||
this.servicePackageOptionsCmsName,
|
|
||||||
'Answers'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!servicePackageNames) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentPackage = servicePackageNames.find((entry) => entry.Name === this.packageLevel);
|
|
||||||
|
|
||||||
return currentPackage.SubWidgetName;
|
|
||||||
},
|
|
||||||
defaultPackageText() {
|
|
||||||
const defaultItems = this.getCmsContent(this.defaultPackageItemsCmsName, 'Answers');
|
|
||||||
|
|
||||||
if (!defaultItems) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultItems.map((answer) => answer.Text);
|
|
||||||
},
|
|
||||||
vapsItemText() {
|
|
||||||
const vapsDescriptions = this.getCmsContent(this.vapsItemsCmsName, 'Answers');
|
|
||||||
|
|
||||||
if (!vapsDescriptions) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const vapsDescriptionsOnOrder = vapsDescriptions.filter((answer) =>
|
|
||||||
containsLineItemWithPartType(answer.Name, this.vaps));
|
|
||||||
|
|
||||||
return vapsDescriptionsOnOrder.map((answer) => answer.Text);
|
|
||||||
},
|
|
||||||
packageLevel() {
|
|
||||||
return getHighestFullySatisfiedTier(
|
|
||||||
this.glassToReplace,
|
|
||||||
this.availableLineItems,
|
|
||||||
this.isRepair,
|
|
||||||
this.vaps
|
|
||||||
);
|
|
||||||
},
|
|
||||||
glassToReplace() {
|
|
||||||
return this.damage.glassToReplace;
|
|
||||||
},
|
|
||||||
isRepair() {
|
|
||||||
return this.damage.isRepair;
|
|
||||||
},
|
|
||||||
vaps() {
|
|
||||||
return this.lineItems?.vaps;
|
|
||||||
},
|
|
||||||
availableLineItems() {
|
|
||||||
return [
|
|
||||||
...(this.lineItems?.glassParts ?? []),
|
|
||||||
...(this.lineItems?.supportingItems ?? []),
|
|
||||||
...(useMainStore().order.availableVaps ?? [])
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<reviewBlock
|
<reviewBlock
|
||||||
:headerCmsWidgetName="cmsWidgetName"
|
:customHeaderText="header"
|
||||||
:content="displayContent" />
|
:content="displayContent"
|
||||||
|
:editLinkText="editLinkText" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { getStringWithCustomValues, processIfStatements } from '@/helpers/cms-content-helper';
|
||||||
|
import { getGlassList } from '@/helpers/damage-helper';
|
||||||
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -13,15 +16,40 @@ export default {
|
||||||
reviewBlock
|
reviewBlock
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String
|
||||||
vehicle: Object
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
header() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
displayContent() {
|
displayContent() {
|
||||||
return [`${this.vehicle.year} ${this.vehicle.make} ${this.vehicle.model}`];
|
return [this.getCmsContentWithCustomValues(this.cmsWidgetName, 'BodyText')];
|
||||||
|
},
|
||||||
|
editLinkText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
|
},
|
||||||
|
customValueMap() {
|
||||||
|
return {
|
||||||
|
glassList: this.glassList,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
glassList() {
|
||||||
|
const glassPieces = this.mainStore.lineItems.glassParts?.map((part) => part.partType.toLowerCase()) ?? [];
|
||||||
|
return getGlassList(glassPieces);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCmsContentWithCustomValues(widgetName, widgetField) {
|
||||||
|
const rawText = this.getCmsContent(widgetName, widgetField);
|
||||||
|
const processedIfStatements = processIfStatements(
|
||||||
|
rawText,
|
||||||
|
'custom',
|
||||||
|
(v) => this.customValueMap[v]
|
||||||
|
);
|
||||||
|
return getStringWithCustomValues(processedIfStatements, this.customValueMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
import reviewBlock from '@/layouts/tpa-submit/review-block/review-block.vue';
|
import reviewBlock from '@/layouts/tpa-submit/review-block/review-block.vue';
|
||||||
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
|
import deductibleBox from '@/layouts/tpa-submit/deductible-box/deductible-box.vue';
|
||||||
import contactDetailsDrawer from '@/layouts/tpa-submit/contact-details-drawer/contact-details-drawer.vue';
|
import contactDetailsDrawer from '@/iss-components/contact-details-drawer/contact-details-drawer.vue';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
import alert from '@/ux-components/alert/alert.vue';
|
import alert from '@/ux-components/alert/alert.vue';
|
||||||
import modal from '@/digital-components/modal/modal.vue';
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ const navigationScenarios = Object.freeze({
|
||||||
PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR',
|
PAY_IN_ADVANCE_ERROR: 'PAY_IN_ADVANCE_ERROR',
|
||||||
PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR',
|
PAY_IN_ADVANCE_CREDIT_CARD_ERROR: 'PAY_IN_ADVANCE_CREDIT_CARD_ERROR',
|
||||||
PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS',
|
PAY_IN_ADVANCE_SUCCESS: 'PAY_IN_ADVANCE_SUCCESS',
|
||||||
|
EDIT_SERVICE_LOCATION: 'EDIT_SERVICE_LOCATION',
|
||||||
|
EDIT_SCHEDULE: 'EDIT_SCHEDULE',
|
||||||
|
EDIT_WIPERS: 'EDIT_WIPERS',
|
||||||
|
|
||||||
// Bailout
|
// Bailout
|
||||||
CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT',
|
CLICKED_FORWARD_WITH_BAILOUT: 'CLICKED_FORWARD_WITH_BAILOUT',
|
||||||
|
|
|
||||||
|
|
@ -696,6 +696,22 @@ const routingTable = () => [
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.SAVE_SESSION_FAILED,
|
scenario: navigationScenarios.SAVE_SESSION_FAILED,
|
||||||
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.EDIT_SERVICE_LOCATION,
|
||||||
|
destinationIssPageValue: issPageValues.SCHEDULE_PAGE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.EDIT_SCHEDULE,
|
||||||
|
destinationIssPageValue: issPageValues.SCHEDULE_PAGE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.EDIT_VEHICLE,
|
||||||
|
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.EDIT_WIPERS,
|
||||||
|
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -235,3 +235,6 @@ $border-input-focus: 2.5px solid $heritage-blue-primary;
|
||||||
|
|
||||||
$svg-calendar-error-fill-color: $alert-red-bg;
|
$svg-calendar-error-fill-color: $alert-red-bg;
|
||||||
$svg-calendar-error-stroke-color: '%23db0020'; // URL encoded #db0020
|
$svg-calendar-error-stroke-color: '%23db0020'; // URL encoded #db0020
|
||||||
|
|
||||||
|
// Swing easing to replicate Heritage's slideVisible
|
||||||
|
$transition-swing: all 400ms cubic-bezier(.02, .01, .47, 1);
|
||||||
Loading…
Reference in a new issue