remove old review-page

This commit is contained in:
Bill Richardson 2024-01-18 14:31:29 -05:00
parent 36ef5d63bb
commit a37d55a306
19 changed files with 7 additions and 3032 deletions

View file

@ -29,7 +29,7 @@
:isForwardActionDisabled="!meta.valid"
:isBackButtonHidden="shouldHideBackButton"
buttonSize
@backClicked="backButtonAction"
@backClicked="navigateBack"
@ForwardClicked="forwardButtonAction" />
</div>
</div>

View file

@ -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);
});
});

View file

@ -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>

View file

@ -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);
});
});
});
});

View file

@ -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>

View file

@ -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
]);
});
});

View file

@ -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>

View file

@ -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
]);
});
});
});

View file

@ -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>

View file

@ -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>

View file

@ -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']);
});
});

View file

@ -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>

View file

@ -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);
});
});
});
});
});

View file

@ -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>

View file

@ -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']);
});
});

View file

@ -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>

View file

@ -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();

View file

@ -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',

View file

@ -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
}
]
},