remove old review-page
This commit is contained in:
parent
36ef5d63bb
commit
a37d55a306
19 changed files with 7 additions and 3032 deletions
|
|
@ -29,7 +29,7 @@
|
|||
:isForwardActionDisabled="!meta.valid"
|
||||
:isBackButtonHidden="shouldHideBackButton"
|
||||
buttonSize
|
||||
@backClicked="backButtonAction"
|
||||
@backClicked="navigateBack"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
// Components
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: jest.fn()
|
||||
}));
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
const wrapper = shallowMount(reviewBlock, mountOptions);
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('Review Content Block', () => {
|
||||
test('Displays one new line of content for each element in the content prop.', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
headerCmsWidgetName: 'TestWidget',
|
||||
content: ['a', 'b', 'c', 'd']
|
||||
});
|
||||
|
||||
// Act
|
||||
const contentLines = wrapper.findAll("[data-test='contentLine']");
|
||||
|
||||
// Assert
|
||||
expect(contentLines.length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
<template>
|
||||
<div class="py-3">
|
||||
<div class="d-flex">
|
||||
<textBlock
|
||||
:cmsWidgetName="headerCmsWidgetName"
|
||||
:customText="customHeaderText"
|
||||
typeStyle="body small bold dark"
|
||||
:marginTopSizeOverride="0" />
|
||||
<textLink
|
||||
linkType="textSmall"
|
||||
text="Edit"
|
||||
class="ml-auto"
|
||||
useLoadingModal
|
||||
href="javascript:void(0)"
|
||||
@click-event="linkClicked">
|
||||
<template
|
||||
v-if="editScreenReaderTextCmsWidgetName"
|
||||
#after-text>
|
||||
<span class="sr-only"> {{ screenReaderOnlyText }} </span>
|
||||
</template>
|
||||
</textLink>
|
||||
</div>
|
||||
<div
|
||||
v-for="item in content"
|
||||
:key="item"
|
||||
class="small review-block-content"
|
||||
data-test="contentLine"
|
||||
v-html="item"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||
import textLink from '@/ux-components/text-link/text-link.vue';
|
||||
|
||||
export default {
|
||||
name: 'review-block',
|
||||
components: {
|
||||
textBlock,
|
||||
textLink
|
||||
},
|
||||
props: {
|
||||
headerCmsWidgetName: String,
|
||||
customHeaderText: String,
|
||||
// Specifically an array of strings.
|
||||
content: Array,
|
||||
editScreenReaderTextCmsWidgetName: String
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
screenReaderOnlyText() {
|
||||
return this.getCmsContent(this.editScreenReaderTextCmsWidgetName, 'Text');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
linkClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.review-block-content > ul) {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
.review-block-content {
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,386 +0,0 @@
|
|||
// Components
|
||||
import review from '@/layouts/review-page/review-page.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import { useMainStore } from '@/store/index.js';
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: jest.fn()
|
||||
}));
|
||||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn().mockImplementation(() => ''),
|
||||
setCmsContent: jest.fn()
|
||||
}
|
||||
};
|
||||
|
||||
const footerStub = {
|
||||
render: () => {},
|
||||
methods: {
|
||||
updateButtonText: jest.fn()
|
||||
}
|
||||
};
|
||||
|
||||
const loadingModalStub = {
|
||||
render: () => {},
|
||||
methods: {
|
||||
showModal: jest.fn(),
|
||||
hideModal: jest.fn()
|
||||
}
|
||||
};
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
// mountOptions.global.mocks["$store"] = store;
|
||||
|
||||
mountOptions.global.stubs = {
|
||||
siteFooter: footerStub,
|
||||
loadingModal: loadingModalStub
|
||||
};
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.mixins = [mockMixin];
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
const wrapper = shallowMount(review, mountOptions);
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
const testingPinia = createTestingPinia({
|
||||
initialState: {
|
||||
main: {
|
||||
order: {
|
||||
vehicle: {
|
||||
year: '2020',
|
||||
make: 'Acura',
|
||||
model: 'MDX',
|
||||
style: '4 door sedan'
|
||||
},
|
||||
damage: {
|
||||
isRepair: false,
|
||||
numberOfChips: 2,
|
||||
glassToReplace: ['dummy location value']
|
||||
},
|
||||
lineItems: {
|
||||
glassParts: ['dummy part value'],
|
||||
supportingItems: ['dummy supporting item'],
|
||||
vaps: ['dummy vap']
|
||||
},
|
||||
serviceLocation: {
|
||||
address: 'address 1',
|
||||
address2: 'address 2',
|
||||
city: 'city',
|
||||
state: 'state',
|
||||
zipCode: 'zip code',
|
||||
appointmentType: 'Mobile',
|
||||
provider: {
|
||||
providerNumber: 1,
|
||||
address: {
|
||||
streetAddress: 'provider address 1',
|
||||
city: 'provider city',
|
||||
state: 'provider state',
|
||||
zipCode: 'provider zip code'
|
||||
}
|
||||
}
|
||||
},
|
||||
schedule: {
|
||||
date: 'date',
|
||||
startTime: 'start',
|
||||
endTime: 'end',
|
||||
jobMinMinutes: '30',
|
||||
jobMaxMinutes: '45'
|
||||
},
|
||||
customer: {
|
||||
firstName: 'first name',
|
||||
lastName: 'last name',
|
||||
emailAddress: 'builddigitaltest@safelite.com',
|
||||
phoneNumber: '555-555-5555',
|
||||
isSmsOptIn: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
useMainStore(testingPinia);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Review Page', () => {
|
||||
describe('arePagePrerequisitesValid', () => {
|
||||
test('Returns true for baseline valid state', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Returns false for empty state', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order = {
|
||||
vehicle: {
|
||||
year: null,
|
||||
make: null,
|
||||
model: null,
|
||||
style: null,
|
||||
carId: null,
|
||||
category: null,
|
||||
vin: null,
|
||||
imageUrl: null,
|
||||
imageVifNumber: null,
|
||||
imageColor: null,
|
||||
registration: {
|
||||
licensePlate: null
|
||||
}
|
||||
},
|
||||
serviceLocation: {
|
||||
address: null,
|
||||
address2: null,
|
||||
city: null,
|
||||
state: null,
|
||||
zipCode: null,
|
||||
zipCodeCtu: null,
|
||||
appointmentType: null,
|
||||
isVehicleProtected: null,
|
||||
provider: {
|
||||
providerNumber: null,
|
||||
address: {
|
||||
streetAddress: null,
|
||||
city: null,
|
||||
state: null,
|
||||
zipCode: null,
|
||||
zipCodeCtu: null
|
||||
}
|
||||
},
|
||||
techNotes: null
|
||||
},
|
||||
customer: {
|
||||
firstName: null,
|
||||
lastName: null,
|
||||
emailAddress: null,
|
||||
phoneNumber: null,
|
||||
isSmsOptIn: null
|
||||
},
|
||||
damage: {
|
||||
isRepair: null,
|
||||
numberOfChips: null,
|
||||
glassToReplace: null,
|
||||
partQuestionAnswers: null,
|
||||
moldingQuestionAnswers: null,
|
||||
capabilityQuestionAnswers: null
|
||||
},
|
||||
lineItems: {
|
||||
glassParts: null,
|
||||
supportingItems: null,
|
||||
vaps: null,
|
||||
serverData: null
|
||||
},
|
||||
payment: {
|
||||
isInsurance: null,
|
||||
insuranceCoverage: {
|
||||
isVerified: null,
|
||||
coverageStatus: null
|
||||
},
|
||||
parentAccountNumber: 0
|
||||
},
|
||||
schedule: {
|
||||
date: null,
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
routeCode: null,
|
||||
jobMaxMinutes: null,
|
||||
jobMinMinutes: null
|
||||
},
|
||||
referralNumber: null,
|
||||
referralSequenceNumber: null,
|
||||
referralDate: null,
|
||||
referralCorrelationId: null,
|
||||
eon: null
|
||||
};
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
describe('Damage requirements', () => {
|
||||
test('Accepts null glassToReplace when is repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = true;
|
||||
wrapper.vm.mainStore.order.damage.glassToReplace = null;
|
||||
wrapper.vm.mainStore.order.damage.numberOfChips = 1;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Rejects 0 chips when repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = true;
|
||||
wrapper.vm.mainStore.order.damage.numberOfChips = 0;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
test('Rejects null chips when repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = true;
|
||||
wrapper.vm.mainStore.order.damage.numberOfChips = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
test('Accepts null chips when not repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = false;
|
||||
wrapper.vm.mainStore.order.damage.numberOfChips = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Rejects empty glassToReplace when not repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = false;
|
||||
wrapper.vm.mainStore.order.damage.glassToReplace = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
test('Rejects null glassToReplace when not repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = false;
|
||||
wrapper.vm.mainStore.order.damage.glassToReplace = [];
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('Package requirements', () => {
|
||||
test('Accepts null glassParts when is repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = true;
|
||||
wrapper.vm.mainStore.order.lineItems.glassParts = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Rejects null glassParts when not repair', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.damage.isRepair = false;
|
||||
wrapper.vm.mainStore.order.lineItems.glassParts = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('Service Location requirements', () => {
|
||||
test('Accepts null provider address when mobile appointment', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Mobile';
|
||||
wrapper.vm.mainStore.order.serviceLocation.provider.address = {};
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Reject null provider address when non-mobile appointment', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Inshop';
|
||||
wrapper.vm.mainStore.order.serviceLocation.provider.address = {};
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
test('Accepts null service location address when non-mobile appointment', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Inshop';
|
||||
wrapper.vm.mainStore.order.serviceLocation.address = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.address2 = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.zipCode = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.city = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.state = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(true);
|
||||
});
|
||||
test('Rejects null service location address when mobile appointment', () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent();
|
||||
wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Mobile';
|
||||
wrapper.vm.mainStore.order.serviceLocation.address = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.address2 = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.zipCode = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.city = null;
|
||||
wrapper.vm.mainStore.order.serviceLocation.state = null;
|
||||
|
||||
// Act
|
||||
const isValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(isValid).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,320 +0,0 @@
|
|||
<template>
|
||||
<Form
|
||||
ref="theForm"
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit">
|
||||
<!-- When customer-details is added: v-slot="{ meta }" -->
|
||||
<div class="page-container-grouped-styles">
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<div class="main-content-container">
|
||||
<vehicleBanner
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
class="mb-4"
|
||||
:displayGenericVehicleImage="false" />
|
||||
<textBlock
|
||||
:customText="subHeaderTitle"
|
||||
typeStyle="h5"
|
||||
justifyText="center"
|
||||
margin="mt-1"
|
||||
class="dark-header" />
|
||||
<textBlock
|
||||
:customText="subHeaderBody"
|
||||
typeStyle="body"
|
||||
justifyText="left"
|
||||
class="mb-4"
|
||||
margin="mt-0 mb-2" />
|
||||
<buttonMain
|
||||
ref="buttonMain"
|
||||
:buttonText="forwardButtonText"
|
||||
isPrimary
|
||||
loaderColor="white"
|
||||
class="mb-2 w-100"
|
||||
@clickEvent="forwardButtonAction" />
|
||||
<div>
|
||||
<hr />
|
||||
</div>
|
||||
<textBlock
|
||||
customText="Appointment Details"
|
||||
typeStyle="label bold"
|
||||
justifyText="justify-text-left"
|
||||
margin="mt-0"
|
||||
class="dark-header" />
|
||||
<div class="px-4">
|
||||
<vehicleReview
|
||||
cmsWidgetName="VehicleReviewWidget"
|
||||
:vehicle="vehicleInfo"
|
||||
@editClicked="editVehicle" />
|
||||
<hr class="my-0" />
|
||||
<damageReview
|
||||
cmsWidgetName="DamageReviewWidget"
|
||||
damageLocationsWidgetName="DamageLocationsWidget"
|
||||
:damage="damageInfo"
|
||||
@editClicked="editDamage" />
|
||||
<hr class="my-0" />
|
||||
<servicePackageReview
|
||||
ref="servicePackageReview"
|
||||
servicePackageOptionsCmsName="ServicePackageTitle"
|
||||
defaultPackageItemsCmsName="DefaultPackageItemDescriptions"
|
||||
vapsItemsCmsName="VapsItemDescriptions"
|
||||
:damage="damageInfo"
|
||||
:lineItems="lineItems"
|
||||
@editClicked="editServicePackage" />
|
||||
<hr class="my-0" />
|
||||
<serviceLocationReview
|
||||
cmsWidgetName="ServiceLocationTitleWidget"
|
||||
:serviceLocation="serviceLocationInfo"
|
||||
@editClicked="editServiceLocation" />
|
||||
<hr class="my-0" />
|
||||
<scheduleReview
|
||||
cmsWidgetName="ScheduleWidget"
|
||||
:appointmentType="appointmentType"
|
||||
@editClicked="editSchedule" />
|
||||
<hr class="my-0" />
|
||||
<customerReview
|
||||
cmsWidgetName="CustomerReviewWidget"
|
||||
:customer="customerInfo"
|
||||
@editClicked="editCustomerDetails" />
|
||||
</div>
|
||||
<div>
|
||||
<hr class="my-0" />
|
||||
</div>
|
||||
<siteFooter
|
||||
ref="siteFooter"
|
||||
class="mt-5"
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
@backClicked="navigateBack" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components
|
||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
||||
import buttonMain from '@/ux-components/button-main/button-main.vue';
|
||||
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||
|
||||
import customerReview from '@/layouts/review-page/review-sections/customer-review/customer-review.vue';
|
||||
import damageReview from '@/layouts/review-page/review-sections/damage-review/damage-review.vue';
|
||||
import scheduleReview from '@/layouts/review-page/review-sections/schedule-review/schedule-review.vue';
|
||||
import serviceLocationReview from '@/layouts/review-page/review-sections/service-location-review/service-location-review.vue';
|
||||
import servicePackageReview from '@/layouts/review-page/review-sections/service-package-review/service-package-review.vue';
|
||||
import vehicleReview from '@/layouts/review-page/review-sections/vehicle-review/vehicle-review.vue';
|
||||
|
||||
// Supporting files
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
|
||||
import settleAllPromises from '@/helpers/layout-helper';
|
||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||
import { useMainStore } from '@/store';
|
||||
|
||||
// Validation
|
||||
import { Form } from 'vee-validate';
|
||||
|
||||
export default {
|
||||
name: 'review-page',
|
||||
components: {
|
||||
buttonMain,
|
||||
customerReview,
|
||||
damageReview,
|
||||
scheduleReview,
|
||||
servicePackageReview,
|
||||
serviceLocationReview,
|
||||
siteHeader,
|
||||
siteFooter,
|
||||
textBlock,
|
||||
vehicleBanner,
|
||||
vehicleReview,
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Form
|
||||
},
|
||||
mixins: [BaseFormMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
}];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
return { mainStore };
|
||||
},
|
||||
data() {
|
||||
},
|
||||
computed: {
|
||||
subHeaderTitle() {
|
||||
return this.getCmsContent('SiteSubHeaderWidget', 'HeaderText');
|
||||
},
|
||||
subHeaderBody() {
|
||||
return this.getCmsContent('SiteSubHeaderWidget', 'BodyText');
|
||||
},
|
||||
forwardButtonText() {
|
||||
return this.getCmsContent('SiteFooterWidget', 'ForwardButtonText');
|
||||
},
|
||||
vehicleInfo() {
|
||||
return useMainStore().vehicle;
|
||||
},
|
||||
damageInfo() {
|
||||
return useMainStore().damage;
|
||||
},
|
||||
lineItems() {
|
||||
return useMainStore().lineItems;
|
||||
},
|
||||
serviceLocationInfo() {
|
||||
return useMainStore().order.serviceLocation;
|
||||
},
|
||||
appointmentType() {
|
||||
return useMainStore().order.serviceLocation.appointmentType;
|
||||
},
|
||||
customerInfo() {
|
||||
return useMainStore().order.customer;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
// Vehicle
|
||||
const { vehicle } = useMainStore().order;
|
||||
const vehicleReqs = !!(vehicle.year && vehicle.make && vehicle.model && vehicle.style);
|
||||
|
||||
// Damage
|
||||
const { damage } = useMainStore().order;
|
||||
const damageReqs = !!(
|
||||
(damage.isRepair && damage.numberOfChips)
|
||||
|| (!damage.isRepair && damage.glassToReplace?.length)
|
||||
);
|
||||
|
||||
// Service Package
|
||||
const { lineItems } = useMainStore().order;
|
||||
// damageReqs handles checking for damage, even though it is also required for this section.
|
||||
const packageReqs = !!(
|
||||
(damage.isRepair || lineItems.glassParts)
|
||||
&& lineItems.supportingItems
|
||||
);
|
||||
|
||||
// Service Location
|
||||
const { serviceLocation } = useMainStore().order;
|
||||
const mobileReqs = !!(
|
||||
serviceLocation.address
|
||||
&& serviceLocation.city
|
||||
&& serviceLocation.state
|
||||
&& serviceLocation.zipCode
|
||||
);
|
||||
|
||||
const providerLocation = serviceLocation.provider.address;
|
||||
const dropOffInshopReqs = !!(
|
||||
providerLocation.streetAddress
|
||||
&& providerLocation.city
|
||||
&& providerLocation.state
|
||||
&& providerLocation.zipCode
|
||||
);
|
||||
|
||||
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||
const serviceLocationReqs =
|
||||
(isMobile && mobileReqs) || (!isMobile && dropOffInshopReqs);
|
||||
|
||||
// Schedule
|
||||
const { schedule } = useMainStore().order;
|
||||
const scheduleReqs = !!(
|
||||
schedule.date
|
||||
&& schedule.startTime
|
||||
&& schedule.endTime
|
||||
&& schedule.jobMaxMinutes
|
||||
&& schedule.jobMinMinutes
|
||||
);
|
||||
|
||||
// Customer
|
||||
const { customer } = useMainStore().order;
|
||||
const customerReqs = !!(
|
||||
customer.firstName
|
||||
&& customer.lastName
|
||||
&& customer.phoneNumber
|
||||
&& customer.emailAddress
|
||||
);
|
||||
|
||||
return (
|
||||
vehicleReqs
|
||||
&& damageReqs
|
||||
&& packageReqs
|
||||
&& serviceLocationReqs
|
||||
&& scheduleReqs
|
||||
&& customerReqs
|
||||
);
|
||||
},
|
||||
editVehicle() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_VEHICLE_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
editDamage() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_DAMAGE_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
editServicePackage() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_SERVICE_PACKAGE_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
editServiceLocation() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_SERVICE_LOCATION_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
editSchedule() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_SCHEDULE_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
editCustomerDetails() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_CUSTOMER_EDIT,
|
||||
this.$route
|
||||
);
|
||||
},
|
||||
forwardButtonAction() {
|
||||
this.navigateForward();
|
||||
},
|
||||
navigateForward() {
|
||||
this.$router.navigateWithoutSaving(
|
||||
navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$page-side-padding: 1.5rem;
|
||||
|
||||
.page-container-grouped-styles {
|
||||
overflow: auto;
|
||||
|
||||
.main-content-container {
|
||||
padding: 0 1.5rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dark-header {
|
||||
color: $black;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
// Components
|
||||
import customerReview from '@/layouts/review-page/review-sections/customer-review/customer-review.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
|
||||
const testConstants = {
|
||||
cms: {
|
||||
header: {
|
||||
text: 'Header'
|
||||
},
|
||||
sms: {
|
||||
text: 'Sms'
|
||||
}
|
||||
},
|
||||
customer: {
|
||||
firstName: 'First',
|
||||
lastName: 'Last',
|
||||
phoneNumber: '111-111-1111',
|
||||
emailAddress: 'builddigitaltest@safelite.com',
|
||||
isSmsOptIn: false
|
||||
},
|
||||
displayContent: {
|
||||
fullName: 'First Last',
|
||||
phoneNumber: '111-111-1111',
|
||||
emailAddress: 'builddigitaltest@safelite.com',
|
||||
smsOptIn: 'Sms'
|
||||
}
|
||||
};
|
||||
|
||||
function generateDefaultProps() {
|
||||
return {
|
||||
cmsWidgetName: 'CustomerWidget',
|
||||
customer: {
|
||||
firstName: testConstants.customer.firstName,
|
||||
lastName: testConstants.customer.lastName,
|
||||
phoneNumber: testConstants.customer.phoneNumber,
|
||||
emailAddress: testConstants.customer.emailAddress,
|
||||
isSmsOptIn: testConstants.customer.isSmsOptIn
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let cmsContent;
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
||||
}
|
||||
};
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
mountOptions.mixins = [mockMixin];
|
||||
|
||||
const wrapper = shallowMount(customerReview, mountOptions);
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cmsContent = {
|
||||
CustomerWidget: {
|
||||
HeaderText: testConstants.cms.header.text,
|
||||
SubheaderText: testConstants.cms.sms.text
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
describe('Customer Review Block', () => {
|
||||
test('Should display header text from cms', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.header).toEqual(testConstants.cms.header.text);
|
||||
});
|
||||
|
||||
test('Should display sms text from cms', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.smsOptIn).toEqual(testConstants.cms.sms.text);
|
||||
});
|
||||
|
||||
test('Should render correct display content', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toEqual([
|
||||
testConstants.displayContent.fullName,
|
||||
testConstants.displayContent.emailAddress,
|
||||
testConstants.displayContent.phoneNumber,
|
||||
testConstants.displayContent.smsOptIn
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditContactDetailsScreenReader"
|
||||
:customHeaderText="header"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
export default {
|
||||
name: 'customer-review',
|
||||
components: {
|
||||
reviewBlock
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: String,
|
||||
customer: Object
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
displayContent() {
|
||||
return [this.fullName, this.email, this.phoneNumber, this.smsOptIn];
|
||||
},
|
||||
header() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||
},
|
||||
fullName() {
|
||||
return `${this.customer?.firstName} ${this.customer?.lastName}`;
|
||||
},
|
||||
email() {
|
||||
return this.customer?.emailAddress;
|
||||
},
|
||||
phoneNumber() {
|
||||
return this.customer?.phoneNumber;
|
||||
},
|
||||
smsOptIn() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'SubheaderText');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,436 +0,0 @@
|
|||
// Components
|
||||
import damageReview from '@/layouts/review-page/review-sections/damage-review/damage-review.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
||||
|
||||
const testConstants = {
|
||||
cmsConstants: {
|
||||
widgetNames: {
|
||||
header: 'DamageReviewWidget',
|
||||
locations: 'DamageLocationsWidget',
|
||||
driverDamages: 'DriverDamagesWidget',
|
||||
passengerDamages: 'PassengerDamagesWidget'
|
||||
},
|
||||
header: {
|
||||
text: 'Damage'
|
||||
},
|
||||
damageLocations: {
|
||||
windshield: damageLocationsSelected.WINDSHIELD,
|
||||
driver: damageLocationsSelected.DRIVER,
|
||||
passenger: damageLocationsSelected.PASSENGER,
|
||||
rear: damageLocationsSelected.REAR
|
||||
},
|
||||
damageNames: {
|
||||
vent: damageLocationsSelected.VENT,
|
||||
front: damageLocationsSelected.FRONT,
|
||||
back: damageLocationsSelected.BACK,
|
||||
quarter: damageLocationsSelected.QUARTER,
|
||||
side: damageLocationsSelected.SIDEDOOR
|
||||
},
|
||||
locationCopy: {
|
||||
windshield: 'Windshield copy',
|
||||
driver: 'Driver copy',
|
||||
passenger: 'Passenger copy',
|
||||
rear: 'Rear copy'
|
||||
},
|
||||
damageCopy: {
|
||||
vent: 'Vent copy',
|
||||
front: 'Front copy',
|
||||
back: 'Back copy',
|
||||
quarter: 'Quarter copy',
|
||||
side: 'Side copy'
|
||||
},
|
||||
imageId: '00000000-0000-0000-0000-000000000000'
|
||||
},
|
||||
makeBulletedList: (items) => {
|
||||
let list = '<ul>';
|
||||
items.forEach((item) => {
|
||||
list += `<li>${item}</li>`;
|
||||
});
|
||||
list += '</ul>';
|
||||
|
||||
return list;
|
||||
},
|
||||
glassItems: {
|
||||
windshield: {
|
||||
glassLocation: damageLocationsSelected.WINDSHIELD,
|
||||
glassName: damageLocationsSelected.SINGLE
|
||||
},
|
||||
rear: {
|
||||
glassLocation: damageLocationsSelected.REAR,
|
||||
glassName: damageLocationsSelected.STATIONARY
|
||||
},
|
||||
passengerItems: {
|
||||
vent: {
|
||||
glassLocation: damageLocationsSelected.PASSENGER,
|
||||
glassName: damageLocationsSelected.VENT
|
||||
},
|
||||
front: {
|
||||
glassLocation: damageLocationsSelected.PASSENGER,
|
||||
glassName: damageLocationsSelected.FRONT
|
||||
},
|
||||
back: {
|
||||
glassLocation: damageLocationsSelected.PASSENGER,
|
||||
glassName: damageLocationsSelected.BACK
|
||||
},
|
||||
quarter: {
|
||||
glassLocation: damageLocationsSelected.PASSENGER,
|
||||
glassName: damageLocationsSelected.QUARTER
|
||||
},
|
||||
side: {
|
||||
glassLocation: damageLocationsSelected.PASSENGER,
|
||||
glassName: damageLocationsSelected.SIDEDOOR
|
||||
}
|
||||
},
|
||||
driverItems: {
|
||||
vent: {
|
||||
glassLocation: damageLocationsSelected.DRIVER,
|
||||
glassName: damageLocationsSelected.VENT
|
||||
},
|
||||
front: {
|
||||
glassLocation: damageLocationsSelected.DRIVER,
|
||||
glassName: damageLocationsSelected.FRONT
|
||||
},
|
||||
back: {
|
||||
glassLocation: damageLocationsSelected.DRIVER,
|
||||
glassName: damageLocationsSelected.BACK
|
||||
},
|
||||
quarter: {
|
||||
glassLocation: damageLocationsSelected.DRIVER,
|
||||
glassName: damageLocationsSelected.QUARTER
|
||||
},
|
||||
side: {
|
||||
glassLocation: damageLocationsSelected.DRIVER,
|
||||
glassName: damageLocationsSelected.SIDEDOOR
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let cmsContent;
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
||||
}
|
||||
};
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
mountOptions.mixins = [mockMixin];
|
||||
|
||||
const wrapper = shallowMount(damageReview, mountOptions);
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cmsContent = {
|
||||
DamageReviewWidget: {
|
||||
Text: testConstants.cmsConstants.header.text
|
||||
},
|
||||
DamageLocationsWidget: {
|
||||
Answers: [
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageLocations.windshield,
|
||||
Text: testConstants.cmsConstants.locationCopy.windshield,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageLocations.driver,
|
||||
Text: testConstants.cmsConstants.locationCopy.driver,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: testConstants.cmsConstants.widgetNames.driverDamages
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageLocations.passenger,
|
||||
Text: testConstants.cmsConstants.locationCopy.passenger,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: testConstants.cmsConstants.widgetNames.passengerDamages
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageLocations.rear,
|
||||
Text: testConstants.cmsConstants.locationCopy.rear,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
DriverDamagesWidget: {
|
||||
Answers: [
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.vent,
|
||||
Text: testConstants.cmsConstants.damageCopy.vent,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.front,
|
||||
Text: testConstants.cmsConstants.damageCopy.front,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.back,
|
||||
Text: testConstants.cmsConstants.damageCopy.back,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.quarter,
|
||||
Text: testConstants.cmsConstants.damageCopy.quarter,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.side,
|
||||
Text: testConstants.cmsConstants.damageCopy.side,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
}
|
||||
]
|
||||
},
|
||||
PassengerDamagesWidget: {
|
||||
Answers: [
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.vent,
|
||||
Text: testConstants.cmsConstants.damageCopy.vent,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.front,
|
||||
Text: testConstants.cmsConstants.damageCopy.front,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.back,
|
||||
Text: testConstants.cmsConstants.damageCopy.back,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.quarter,
|
||||
Text: testConstants.cmsConstants.damageCopy.quarter,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
},
|
||||
{
|
||||
Name: testConstants.cmsConstants.damageNames.side,
|
||||
Text: testConstants.cmsConstants.damageCopy.side,
|
||||
SubText: '',
|
||||
ImageId: testConstants.cmsConstants.imageId,
|
||||
Image: '',
|
||||
SubWidgetName: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
describe('Damage Review Block', () => {
|
||||
describe('Correctly assembles damage info into a display string', () => {
|
||||
test('Shows windshield copy when windshield damage is included', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: false,
|
||||
glassToReplace: [testConstants.glassItems.windshield]
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.windshield
|
||||
]);
|
||||
});
|
||||
|
||||
test('Windshield copy is shown when order is a repair', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: true,
|
||||
numberOfChips: 2,
|
||||
glassToReplace: []
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.windshield
|
||||
]);
|
||||
});
|
||||
|
||||
test('Rear windshield copy shows when rear damage is present', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: false,
|
||||
numberOfChips: null,
|
||||
glassToReplace: [testConstants.glassItems.rear]
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.rear
|
||||
]);
|
||||
});
|
||||
|
||||
test('Driver side copy and items are shown when driver side damage is present', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: false,
|
||||
numberOfChips: null,
|
||||
glassToReplace: [
|
||||
testConstants.glassItems.driverItems.back,
|
||||
testConstants.glassItems.driverItems.front
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.driver,
|
||||
testConstants.makeBulletedList([
|
||||
testConstants.cmsConstants.damageCopy.front,
|
||||
testConstants.cmsConstants.damageCopy.back
|
||||
])
|
||||
]);
|
||||
});
|
||||
|
||||
test('Passenger side copy and items are shown when passenger side damage is present', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: false,
|
||||
numberOfChips: null,
|
||||
glassToReplace: [
|
||||
testConstants.glassItems.passengerItems.quarter,
|
||||
testConstants.glassItems.passengerItems.vent,
|
||||
testConstants.glassItems.passengerItems.side
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.passenger,
|
||||
testConstants.makeBulletedList([
|
||||
testConstants.cmsConstants.damageCopy.vent,
|
||||
testConstants.cmsConstants.damageCopy.quarter,
|
||||
testConstants.cmsConstants.damageCopy.side
|
||||
])
|
||||
]);
|
||||
});
|
||||
|
||||
test('All relevant sections are shown in order in multiglass scenario', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
cmsWidgetName: testConstants.cmsConstants.widgetNames.header,
|
||||
damageLocationsWidgetName: testConstants.cmsConstants.widgetNames.locations,
|
||||
damage: {
|
||||
isRepair: false,
|
||||
numberOfChips: null,
|
||||
glassToReplace: [
|
||||
testConstants.glassItems.windshield,
|
||||
testConstants.glassItems.rear,
|
||||
testConstants.glassItems.driverItems.vent,
|
||||
testConstants.glassItems.driverItems.front,
|
||||
testConstants.glassItems.driverItems.back,
|
||||
testConstants.glassItems.passengerItems.quarter,
|
||||
testConstants.glassItems.passengerItems.back,
|
||||
testConstants.glassItems.passengerItems.side
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual([
|
||||
testConstants.cmsConstants.locationCopy.windshield,
|
||||
testConstants.cmsConstants.locationCopy.driver,
|
||||
testConstants.makeBulletedList([
|
||||
testConstants.cmsConstants.damageCopy.vent,
|
||||
testConstants.cmsConstants.damageCopy.front,
|
||||
testConstants.cmsConstants.damageCopy.back
|
||||
]),
|
||||
testConstants.cmsConstants.locationCopy.passenger,
|
||||
testConstants.makeBulletedList([
|
||||
testConstants.cmsConstants.damageCopy.back,
|
||||
testConstants.cmsConstants.damageCopy.quarter,
|
||||
testConstants.cmsConstants.damageCopy.side
|
||||
]),
|
||||
testConstants.cmsConstants.locationCopy.rear
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditDamageScreenReader"
|
||||
:headerCmsWidgetName="cmsWidgetName"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import damageLocationsSelected from '@/constants/damage-locations-selected.js';
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
export default {
|
||||
name: 'damage-review',
|
||||
components: {
|
||||
reviewBlock
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: String,
|
||||
damageLocationsWidgetName: String,
|
||||
damage: Object
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
displayContent() {
|
||||
return [
|
||||
...this.windshieldCopy,
|
||||
...this.driverSideCopy,
|
||||
...this.passengerSideCopy,
|
||||
...this.rearCopy
|
||||
];
|
||||
},
|
||||
hasWindshieldDamage() {
|
||||
const windshieldPieces = this.getGlassPieces(damageLocationsSelected.WINDSHIELD);
|
||||
|
||||
return this.damage.isRepair || !!windshieldPieces?.length;
|
||||
},
|
||||
hasDriverSideDamage() {
|
||||
const driverPieces = this.getGlassPieces(damageLocationsSelected.DRIVER);
|
||||
|
||||
return !!driverPieces?.length;
|
||||
},
|
||||
hasPassengerSideDamage() {
|
||||
const passengerPieces = this.getGlassPieces(damageLocationsSelected.PASSENGER);
|
||||
|
||||
return !!passengerPieces?.length;
|
||||
},
|
||||
hasRearDamage() {
|
||||
const rearPieces = this.getGlassPieces(damageLocationsSelected.REAR);
|
||||
|
||||
return !!rearPieces?.length;
|
||||
},
|
||||
windshieldCopy() {
|
||||
const answerContent = this.getLocationAnswer(damageLocationsSelected.WINDSHIELD);
|
||||
|
||||
if (this.hasWindshieldDamage) {
|
||||
return [answerContent?.Text];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
driverSideCopy() {
|
||||
const answerContent = this.getLocationAnswer(damageLocationsSelected.DRIVER);
|
||||
const damageAnswers = this.getAnswersNullSafe(answerContent?.SubWidgetName);
|
||||
const driverSideItems = this.getGlassPieces(damageLocationsSelected.DRIVER);
|
||||
const damageAnswersOnOrder = damageAnswers?.filter((answer) =>
|
||||
driverSideItems?.some((glassPiece) => answer.Name === glassPiece.glassName));
|
||||
|
||||
if (this.hasDriverSideDamage) {
|
||||
return [
|
||||
answerContent?.Text,
|
||||
this.generateBulletedListFromAnswers(damageAnswersOnOrder)
|
||||
];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
passengerSideCopy() {
|
||||
const answerContent = this.getLocationAnswer(damageLocationsSelected.PASSENGER);
|
||||
const damageAnswers = this.getAnswersNullSafe(answerContent?.SubWidgetName);
|
||||
const passengerSideItems = this.getGlassPieces(damageLocationsSelected.PASSENGER);
|
||||
const damageAnswersOnOrder = damageAnswers?.filter((answer) =>
|
||||
passengerSideItems?.some((glassPiece) => answer.Name === glassPiece.glassName));
|
||||
|
||||
if (this.hasPassengerSideDamage) {
|
||||
return [
|
||||
answerContent?.Text,
|
||||
this.generateBulletedListFromAnswers(damageAnswersOnOrder)
|
||||
];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
rearCopy() {
|
||||
const answerContent = this.getLocationAnswer(damageLocationsSelected.REAR);
|
||||
|
||||
if (this.hasRearDamage) {
|
||||
return [answerContent?.Text];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
locationAnswers() {
|
||||
return this.getAnswersNullSafe(this.damageLocationsWidgetName);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
},
|
||||
getAnswersNullSafe(widgetName) {
|
||||
const rawAnswers = this.getCmsContent(widgetName, 'Answers');
|
||||
|
||||
return rawAnswers || [];
|
||||
},
|
||||
getLocationAnswer(damageLocation) {
|
||||
return this.locationAnswers?.find((answer) => answer.Name === damageLocation);
|
||||
},
|
||||
getGlassPieces(damageLocation) {
|
||||
return this.damage?.glassToReplace?.filter((item) => item.glassLocation === damageLocation);
|
||||
},
|
||||
generateBulletedListFromAnswers(answers) {
|
||||
let list = '<ul>';
|
||||
|
||||
answers.forEach((answer) => {
|
||||
list += `<li>${answer.Text}</li>`;
|
||||
});
|
||||
|
||||
list += '</ul>';
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditAppointmentScreenReader"
|
||||
:customHeaderText="headerText"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
export default {
|
||||
name: 'schedule-review',
|
||||
components: {
|
||||
reviewBlock
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: String,
|
||||
appointmentType: String
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
displayContent() {
|
||||
return [
|
||||
this.getCmsContent(this.cmsWidgetName, 'BodyText'),
|
||||
this.getCmsContent(this.cmsWidgetName, 'BodyText2')
|
||||
];
|
||||
},
|
||||
headerText() {
|
||||
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
// Components
|
||||
import serviceLocationReview from '@/layouts/review-page/review-sections/service-location-review/service-location-review.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
|
||||
const cmsContent = {
|
||||
ServiceLocationTitleWidget: {
|
||||
Text: 'Title Text'
|
||||
}
|
||||
};
|
||||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
|
||||
}
|
||||
};
|
||||
|
||||
function generateDefaultProps() {
|
||||
return {
|
||||
cmsWidgetName: 'ServiceLocationTitleWidget',
|
||||
serviceLocation: {
|
||||
address: 'Mobile Address 1',
|
||||
address2: 'Mobile Address 2',
|
||||
city: 'Mobile City',
|
||||
state: 'MO',
|
||||
zipCode: '11111',
|
||||
zipCodeCtu: '',
|
||||
appointmentType: AppointmentTypeStrings.MOBILE,
|
||||
isVehicleProtected: false,
|
||||
provider: {
|
||||
providerNumber: '',
|
||||
address: {
|
||||
streetAddress: 'Service Location Address',
|
||||
city: 'Service Location City',
|
||||
state: 'SL',
|
||||
zipCode: '22222',
|
||||
zipCodeCtu: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
mountOptions.mixins = [mockMixin];
|
||||
|
||||
const wrapper = shallowMount(serviceLocationReview, mountOptions);
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('Service Location Review Block', () => {
|
||||
test('Should render mobile address if mobile appointment', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toEqual([
|
||||
'Mobile Address 1, Mobile Address 2, Mobile City, MO 11111'
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should render service location address if inshop appointment.', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
props.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;
|
||||
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toEqual([
|
||||
'Service Location Address, Service Location City, SL 22222'
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should render service location address if drop-off appointment', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
props.serviceLocation.appointmentType = AppointmentTypeStrings.DROP_OFF;
|
||||
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toEqual([
|
||||
'Service Location Address, Service Location City, SL 22222'
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should not add comma or any text if address2 is null', async () => {
|
||||
// Arrange
|
||||
const props = generateDefaultProps();
|
||||
props.serviceLocation.address2 = null;
|
||||
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
...props
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toEqual(['Mobile Address 1, Mobile City, MO 11111']);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditLocationScreenReader"
|
||||
:headerCmsWidgetName="cmsWidgetName"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
export default {
|
||||
name: 'service-location-review',
|
||||
components: {
|
||||
reviewBlock
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: String,
|
||||
serviceLocation: Object
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
displayContent() {
|
||||
return [
|
||||
`${this.addressInfo.address}${this.addressInfo.address2 ? ', ' : ''}${
|
||||
this.addressInfo.address2
|
||||
}, ${this.addressInfo.city}, ${this.addressInfo.state} ${this.addressInfo.zipCode}`
|
||||
];
|
||||
},
|
||||
addressInfo() {
|
||||
if (this.serviceLocation?.appointmentType === AppointmentTypeStrings.MOBILE) {
|
||||
return {
|
||||
address: this.serviceLocation?.address,
|
||||
address2: this.serviceLocation?.address2 ?? '',
|
||||
city: this.serviceLocation?.city,
|
||||
state: this.serviceLocation?.state,
|
||||
zipCode: this.serviceLocation?.zipCode
|
||||
};
|
||||
}
|
||||
return {
|
||||
address: this.serviceLocation?.provider?.address?.streetAddress,
|
||||
address2: '',
|
||||
city: this.serviceLocation?.provider?.address?.city,
|
||||
state: this.serviceLocation?.provider?.address?.state,
|
||||
zipCode: this.serviceLocation?.provider?.address?.zipCode
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,969 +0,0 @@
|
|||
// Components
|
||||
import servicePackageReview from '@/layouts/review-page/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';
|
||||
|
||||
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 defense 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 DEFENSE',
|
||||
description: null,
|
||||
partType: 'RAIN DEFENSE',
|
||||
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(wrapper) {
|
||||
wrapper.vm.initializeComponent({
|
||||
wipers: [testConstants.parts.frontWiperPart],
|
||||
rainDefense: 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(wrapper);
|
||||
|
||||
// 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(wrapper);
|
||||
|
||||
// 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(wrapper);
|
||||
|
||||
// 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(wrapper);
|
||||
|
||||
// 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
|
||||
});
|
||||
|
||||
wrapper.vm.initializeComponent({
|
||||
wipers: scenario.params.wiperResponse,
|
||||
rainDefense: scenario.params.rainDefenseResponse
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.packageNameWidget).toEqual(iteration.expected.packageNameWidget);
|
||||
expect(wrapper.vm.displayContent).toEqual(iteration.expected.displayContent);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditServiceTypeScreenReader"
|
||||
:headerCmsWidgetName="packageNameWidget"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import settleAllPromises from '@/helpers/layout-helper';
|
||||
// import baseMixin from '@/mixins/base-mixin.js';
|
||||
// import store from '@/store';
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
import {
|
||||
getHighestFullySatisfiedTier,
|
||||
containsLineItemWithPartType
|
||||
} from '@/helpers/service-package-helper.js';
|
||||
// import { storeActions } from '@/constants/store-actions.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 ?? []),
|
||||
...this.availableVaps
|
||||
];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadInitialData() {
|
||||
/* const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.GET_WIPERS,
|
||||
{
|
||||
serviceZipCode: store.getters.order.serviceLocation.zipCode,
|
||||
carId: store.getters.vehicle.carId
|
||||
},
|
||||
'review'
|
||||
);
|
||||
const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.GET_RAIN_DEFENSE,
|
||||
null,
|
||||
'review'
|
||||
);
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'wipers',
|
||||
promise: wipersPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'rainDefense',
|
||||
promise: rainDefensePromise
|
||||
}
|
||||
];
|
||||
|
||||
return settleAllPromises(promiseResultMap); */
|
||||
},
|
||||
initializeComponent(apiResponses) {
|
||||
const vapsFromApi = [...apiResponses.wipers, apiResponses.rainDefense];
|
||||
|
||||
this.availableVaps = vapsFromApi;
|
||||
},
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Components
|
||||
import vehicleReview from '@/layouts/review-page/review-sections/vehicle-review/vehicle-review.vue';
|
||||
|
||||
// Supporting Files
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||
|
||||
jest.mock('@/helpers/cms-content-helper', () => ({
|
||||
fetchCmsContentForPage: () => Promise.resolve('content')
|
||||
}));
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
const mountOptions = getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
});
|
||||
|
||||
methodToRun();
|
||||
|
||||
mountOptions.data = () => (
|
||||
initialData
|
||||
);
|
||||
|
||||
const wrapper = shallowMount(vehicleReview, mountOptions);
|
||||
wrapper.vm.setCmsContent = jest.fn();
|
||||
return { wrapper };
|
||||
}
|
||||
|
||||
describe('Vehicle Review Block', () => {
|
||||
test('Correctly assembles vehicle info into a display string', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = getShallowMountedComponent({
|
||||
vehicle: {
|
||||
year: '2019',
|
||||
make: 'Honda',
|
||||
model: 'Odyssey'
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.displayContent).toStrictEqual(['2019 Honda Odyssey']);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
<template>
|
||||
<reviewBlock
|
||||
editScreenReaderTextCmsWidgetName="EditVehicleScreenReader"
|
||||
:headerCmsWidgetName="cmsWidgetName"
|
||||
:content="displayContent"
|
||||
@editClicked="editClicked" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import reviewBlock from '@/layouts/review-page/review-block/review-block.vue';
|
||||
|
||||
export default {
|
||||
name: 'vehicle-review',
|
||||
components: {
|
||||
reviewBlock
|
||||
},
|
||||
props: {
|
||||
cmsWidgetName: String,
|
||||
vehicle: Object
|
||||
},
|
||||
emits: ['edit-clicked'],
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
displayContent() {
|
||||
return [`${this.vehicle.year} ${this.vehicle.make} ${this.vehicle.model}`];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editClicked() {
|
||||
this.$emit('edit-clicked');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -66,8 +66,8 @@ import allGlassPartsAndItemsHavePrices from '@/layouts/service-packages/service-
|
|||
import globalRules from '@/constants/global-rules';
|
||||
import servicePackageQuestion from '@/layouts/service-packages/service-package-question/service-package-question.vue';
|
||||
import issPageValues from '@/router/router-constants/issPage-values';
|
||||
import bailoutCode from "@/constants/bailoutCode";
|
||||
import bailoutMessage from "@/constants/bailoutMessage";
|
||||
import bailoutCode from '@/constants/bailoutCode';
|
||||
import bailoutMessage from '@/constants/bailoutMessage';
|
||||
|
||||
const store = useMainStore();
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ const issPageValues = Object.freeze({
|
|||
LICENSE_PLATE_LOOKUP: 'license-plate-lookup',
|
||||
MOLDING_QUESTIONS: 'molding-questions',
|
||||
ORDER_CONFIRMATION: 'order-confirmation',
|
||||
PAYMENT_METHOD: 'payment-method',
|
||||
PAYMENT_PAGE: 'payment-page',
|
||||
PART_QUESTIONS: 'part-questions',
|
||||
POLICY_HOLDER_DETAILS: 'policy-holder-details',
|
||||
PROVIDER_PREFERENCE: 'provider-preference',
|
||||
REVIEW_PAGE: 'review-page',
|
||||
REVEAL: 'reveal',
|
||||
SERVICE_LOCATION: 'service-location',
|
||||
TPA_CONFIRMATION: 'tpa-confirmation',
|
||||
|
|
|
|||
|
|
@ -599,12 +599,12 @@ const routingTable = () => [
|
|||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationIssPageValue: issPageValues.REVIEW_PAGE
|
||||
destinationIssPageValue: issPageValues.PAYMENT_METHOD
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.REVIEW_PAGE,
|
||||
issPageValue: issPageValues.PAYMENT_METHOD,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
|
|
@ -612,31 +612,7 @@ const routingTable = () => [
|
|||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationIssPageValue: issPageValues.PAYMENT_PAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_CUSTOMER_EDIT,
|
||||
destinationIssPageValue: issPageValues.CONTACT_DETAILS
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_DAMAGE_EDIT,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_SCHEDULE_EDIT,
|
||||
destinationIssPageValue: issPageValues.SCHEDULE_PAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_SERVICE_LOCATION_EDIT,
|
||||
destinationIssPageValue: issPageValues.SERVICE_LOCATION
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_SERVICE_PACKAGE_EDIT,
|
||||
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_VEHICLE_EDIT,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_SELECTION
|
||||
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue