diff --git a/src/helpers/damage-review-content-generator.js b/src/helpers/damage-review-content-generator.js
new file mode 100644
index 00000000..a6d8f7b5
--- /dev/null
+++ b/src/helpers/damage-review-content-generator.js
@@ -0,0 +1,71 @@
+import damageLocationsSelected from '@/constants/damage-locations-selected.js';
+
+function getLocationAnswer(damageLocation, locationAnswers) {
+ return locationAnswers?.find((answer) => answer.Name === damageLocation);
+}
+
+function getGlassPieces(damageLocation, glassToReplace) {
+ return glassToReplace?.filter((item) => item.glassLocation === damageLocation);
+}
+
+function getWindshieldCopy(answerContent, glassToReplace, isRepair) {
+ const windshieldPieces = getGlassPieces(damageLocationsSelected.WINDSHIELD, glassToReplace);
+ return isRepair || !!windshieldPieces?.length ? [answerContent?.Text] : [];
+}
+
+function getRearCopy(answerContent, glassToReplace) {
+ const rearPieces = getGlassPieces(damageLocationsSelected.REAR, glassToReplace);
+ return rearPieces?.length ? [answerContent?.Text] : [];
+}
+
+function generateBulletedListFromAnswers(answers) {
+ const items = answers.map((answer) => `
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
+ textBlock
},
props: {
headerCmsWidgetName: String,
customHeaderText: String,
- // Specifically an array of strings.
- content: Array,
- editScreenReaderTextCmsWidgetName: String
+ content: Array // Specifically an array of strings.
},
emits: ['edit-clicked'],
data() {
diff --git a/src/layouts/payment-method/review-dropdown/review-dropdown.vue b/src/layouts/payment-method/review-dropdown/review-dropdown.vue
new file mode 100644
index 00000000..39c53005
--- /dev/null
+++ b/src/layouts/payment-method/review-dropdown/review-dropdown.vue
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/review-page/review-sections/customer-review/customer-review.spec.js b/src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.spec.js
similarity index 96%
rename from src/layouts/review-page/review-sections/customer-review/customer-review.spec.js
rename to src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.spec.js
index 1e0f612d..7d523f9d 100644
--- a/src/layouts/review-page/review-sections/customer-review/customer-review.spec.js
+++ b/src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.spec.js
@@ -1,5 +1,5 @@
// Components
-import customerReview from '@/layouts/review-page/review-sections/customer-review/customer-review.vue';
+import customerReview from '@/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue';
// Supporting Files
import { shallowMount } from '@vue/test-utils';
diff --git a/src/layouts/review-page/review-sections/customer-review/customer-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue
similarity index 72%
rename from src/layouts/review-page/review-sections/customer-review/customer-review.vue
rename to src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue
index 5f442531..3d92e63c 100644
--- a/src/layouts/review-page/review-sections/customer-review/customer-review.vue
+++ b/src/layouts/payment-method/review-dropdown/review-sections/customer-review/customer-review.vue
@@ -1,13 +1,11 @@
+ :content="displayContent" />
diff --git a/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.spec.js b/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.spec.js
new file mode 100644
index 00000000..5e369a72
--- /dev/null
+++ b/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.spec.js
@@ -0,0 +1,78 @@
+// Components
+import damageReview from '@/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue';
+
+// Supporting Files
+import { createTestingPinia } from '@pinia/testing';
+import { useMainStore } from '@/store';
+import { shallowMount } from '@vue/test-utils';
+import { getMountOptions } from '@/helpers/unit-test-helper.js';
+import { getDamageDisplayContent } from '@/helpers/damage-review-content-generator.js';
+
+jest.mock('@/helpers/damage-review-content-generator.js', () => ({
+ getDamageDisplayContent: jest.fn(),
+ getLocationAnswer: jest.fn()
+}));
+
+let cmsContent;
+const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn((widgetName, cmsFieldName) => cmsContent?.[widgetName]?.[cmsFieldName] ?? '')
+ }
+};
+
+function getShallowMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) {
+ const mountOptions = getMountOptions({
+ router: {
+ navigate: jest.fn()
+ }
+ });
+
+ const testingPinia = createTestingPinia({
+ initialState: {
+ main: mainInitialState
+ }
+ });
+ useMainStore(testingPinia);
+ methodToRun();
+
+ mountOptions.global.plugins = [testingPinia];
+ mountOptions.data = () => (
+ initialData
+ );
+
+ mountOptions.mixins = [mockMixin];
+
+ const wrapper = shallowMount(damageReview, mountOptions);
+ return { wrapper };
+}
+
+beforeEach(() => {
+ getDamageDisplayContent.mockClear();
+});
+
+describe('Damage Review Block', () => {
+ test('computed displayContent calls getDamageDisplayContent with expected', () => {
+ // Arrange
+ const glassToReplace = ['front-window', 'side-window'];
+ const isRepair = false;
+ const initialStore = {
+ order: {
+ damage: {
+ glassToReplace,
+ isRepair
+ }
+ }
+ };
+ const expected = ['a', 'v', 'n'];
+ getDamageDisplayContent.mockImplementationOnce(() => expected);
+ const { wrapper } = getShallowMountedComponent(initialStore, {});
+
+ // Act
+ const result = wrapper.vm.displayContent;
+
+ // Assert
+ expect(result).toStrictEqual(expected);
+ expect(getDamageDisplayContent).toBeCalledTimes(1);
+ expect(getDamageDisplayContent).toBeCalledWith([], [], [], glassToReplace, isRepair);
+ });
+});
diff --git a/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue
new file mode 100644
index 00000000..ac93b4bf
--- /dev/null
+++ b/src/layouts/payment-method/review-dropdown/review-sections/damage-review/damage-review.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
diff --git a/src/layouts/review-page/review-sections/schedule-review/schedule-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue
similarity index 65%
rename from src/layouts/review-page/review-sections/schedule-review/schedule-review.vue
rename to src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue
index d34e33a5..e0c615df 100644
--- a/src/layouts/review-page/review-sections/schedule-review/schedule-review.vue
+++ b/src/layouts/payment-method/review-dropdown/review-sections/schedule-review/schedule-review.vue
@@ -1,13 +1,11 @@
+ :content="displayContent" />
diff --git a/src/layouts/review-page/review-sections/service-location-review/service-location-review.spec.js b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.spec.js
similarity index 96%
rename from src/layouts/review-page/review-sections/service-location-review/service-location-review.spec.js
rename to src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.spec.js
index 834714aa..2f4be3b1 100644
--- a/src/layouts/review-page/review-sections/service-location-review/service-location-review.spec.js
+++ b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.spec.js
@@ -1,5 +1,6 @@
// Components
-import serviceLocationReview from '@/layouts/review-page/review-sections/service-location-review/service-location-review.vue';
+import
+serviceLocationReview from '@/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue';
// Supporting Files
import { shallowMount } from '@vue/test-utils';
diff --git a/src/layouts/review-page/review-sections/service-location-review/service-location-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
similarity index 82%
rename from src/layouts/review-page/review-sections/service-location-review/service-location-review.vue
rename to src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
index 59241b15..17cc66cc 100644
--- a/src/layouts/review-page/review-sections/service-location-review/service-location-review.vue
+++ b/src/layouts/payment-method/review-dropdown/review-sections/service-location-review/service-location-review.vue
@@ -1,14 +1,12 @@
+ :content="displayContent" />
diff --git a/src/layouts/review-page/review-sections/service-package-review/service-package-review.spec.js b/src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.spec.js
similarity index 99%
rename from src/layouts/review-page/review-sections/service-package-review/service-package-review.spec.js
rename to src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.spec.js
index 6dfd6f4e..500c9bac 100644
--- a/src/layouts/review-page/review-sections/service-package-review/service-package-review.spec.js
+++ b/src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.spec.js
@@ -1,5 +1,6 @@
// Components
-import servicePackageReview from '@/layouts/review-page/review-sections/service-package-review/service-package-review.vue';
+import
+servicePackageReview from '@/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue';
// Supporting Files
import { shallowMount } from '@vue/test-utils';
diff --git a/src/layouts/review-page/review-sections/service-package-review/service-package-review.vue b/src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue
similarity index 75%
rename from src/layouts/review-page/review-sections/service-package-review/service-package-review.vue
rename to src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue
index 56655945..de231e1f 100644
--- a/src/layouts/review-page/review-sections/service-package-review/service-package-review.vue
+++ b/src/layouts/payment-method/review-dropdown/review-sections/service-package-review/service-package-review.vue
@@ -1,21 +1,18 @@
+ :content="displayContent" />
diff --git a/src/layouts/review-page/review-block/review-block.spec.js b/src/layouts/review-page/review-block/review-block.spec.js
deleted file mode 100644
index 738a7df2..00000000
--- a/src/layouts/review-page/review-block/review-block.spec.js
+++ /dev/null
@@ -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);
- });
-});
diff --git a/src/layouts/review-page/review-page.spec.js b/src/layouts/review-page/review-page.spec.js
deleted file mode 100644
index a9739cef..00000000
--- a/src/layouts/review-page/review-page.spec.js
+++ /dev/null
@@ -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);
- });
- });
- });
-});
diff --git a/src/layouts/review-page/review-page.vue b/src/layouts/review-page/review-page.vue
deleted file mode 100644
index 36fcb749..00000000
--- a/src/layouts/review-page/review-page.vue
+++ /dev/null
@@ -1,320 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/layouts/review-page/review-sections/damage-review/damage-review.spec.js b/src/layouts/review-page/review-sections/damage-review/damage-review.spec.js
deleted file mode 100644
index b7a36442..00000000
--- a/src/layouts/review-page/review-sections/damage-review/damage-review.spec.js
+++ /dev/null
@@ -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 = '
';
- items.forEach((item) => {
- list += `- ${item}
`;
- });
- list += '
';
-
- 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
- ]);
- });
- });
-});
diff --git a/src/layouts/review-page/review-sections/damage-review/damage-review.vue b/src/layouts/review-page/review-sections/damage-review/damage-review.vue
deleted file mode 100644
index 4e0b0878..00000000
--- a/src/layouts/review-page/review-sections/damage-review/damage-review.vue
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue
index acabea46..5a3fb0d4 100644
--- a/src/layouts/schedule-page/schedule-page.vue
+++ b/src/layouts/schedule-page/schedule-page.vue
@@ -9,7 +9,7 @@
+ class="mt-4" />
0 && addressLine2.length > 0 ? ', ' : '';
return [addressLine1, addressLine2].join(joinString);
},
@@ -376,6 +376,9 @@ export default {
this.mapZipCode = this.zipCode;
},
forwardButtonAction() {
+ if (this.selectedProviderIsSafeliteShop) {
+ useMainStore().updateIsSafeliteProvider(true);
+ }
const scenario = this.selectedProviderIsSafeliteShop
? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP
: this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP;
@@ -390,7 +393,7 @@ export default {
}
},
getShopButtonDataFromProvider(provider) {
- const cellNumber = this.toDisplayPhoneNumber(provider?.phoneNumber);
+ const cellNumber = toDisplayPhoneNumber(provider?.phoneNumber);
const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles))
? +provider.distanceInMiles.toFixed(1)
: null;
@@ -403,9 +406,7 @@ export default {
buttonBodyCopy: `${this.getProviderAddress(provider)}
${cellNumber ?? ''}`,
value: provider?.providerNumber ?? ''
};
- },
- toDisplayPhoneNumber,
- toTitleCase
+ }
}
};
diff --git a/src/layouts/tpa-submit/__snapshots__/tpa-submit.spec.js.snap b/src/layouts/tpa-submit/__snapshots__/tpa-submit.spec.js.snap
index 10ea690d..48eedef7 100644
--- a/src/layouts/tpa-submit/__snapshots__/tpa-submit.spec.js.snap
+++ b/src/layouts/tpa-submit/__snapshots__/tpa-submit.spec.js.snap
@@ -8,6 +8,7 @@ Object {
},
"sections": Array [],
"widget": Object {
+ "damageLocations": "DamageLocationsWidget",
"footer": "SiteFooterWidget",
"orderDetails": "OrderDetailsContent",
"serviceSummary": "ServiceSummaryContent",
diff --git a/src/layouts/tpa-submit/review-block/review-block.vue b/src/layouts/tpa-submit/review-block/review-block.vue
index 5d13e48f..4f5af710 100644
--- a/src/layouts/tpa-submit/review-block/review-block.vue
+++ b/src/layouts/tpa-submit/review-block/review-block.vue
@@ -21,8 +21,8 @@
- {{ line }}
+ class="small review-block__body--line"
+ v-html="line">
diff --git a/src/layouts/tpa-submit/tpa-submit.spec.js b/src/layouts/tpa-submit/tpa-submit.spec.js
index 7b326679..50b01bc9 100644
--- a/src/layouts/tpa-submit/tpa-submit.spec.js
+++ b/src/layouts/tpa-submit/tpa-submit.spec.js
@@ -9,6 +9,8 @@ import { useMainStore } from '@/store';
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper.js';
import widgetFields from '@/constants/cms-widget-fields.js';
+import { toTitleCase, formatAddress, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
+import { getDamageDisplayContent } from '@/helpers/damage-review-content-generator.js';
// Mock fetchCmsContentForPage
jest.mock('@/helpers/cms-content-helper', () => ({
@@ -25,6 +27,11 @@ jest.mock('@/helpers/text-helper.js', () => ({
toTitleCase: jest.fn()
}));
+jest.mock('@/helpers/damage-review-content-generator.js', () => ({
+ getDamageDisplayContent: jest.fn(),
+ getLocationAnswer: jest.fn()
+}));
+
// Mock our module for promises.
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
@@ -57,6 +64,12 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRu
return { wrapper };
}
+beforeEach(() => {
+ formatAddress.mockClear();
+ toDisplayPhoneNumber.mockClear();
+ getDamageDisplayContent.mockClear();
+});
+
describe('tpa-submit', () => {
test('returns the initial data', () => {
// Arrange
@@ -337,37 +350,25 @@ describe('tpa-submit', () => {
expect(vehicleSection.lines).toStrictEqual(expectedLines);
}
);
- test.each([
- ['Apple sauce', 'Apple sauce'],
- ['', ''],
- ['', undefined],
- ['', null]
- ])(
- 'damage line is %p when store damage is %p',
- async (damageLine, storeDamage) => {
- // Arrange
- const initialStore = {
- order: {
- policy: { damageCause: storeDamage }
- }
- };
- const { wrapper } = getMountedComponent(initialStore);
- const damageSectionIndex = 1;
- const expectedLines = [damageLine];
+ test('damage section lines equal result from getDamageDisplayContent', async () => {
+ // Arrange
+ const { wrapper } = getMountedComponent();
+ const damageSectionIndex = 1;
+ const expectedLines = ['hi', 'potato', 'vehicle 3'];
+ getDamageDisplayContent.mockImplementationOnce(() => expectedLines);
- // Act
- await tpaSubmit.beforeRouteEnter.call(
- wrapper.vm,
- { query: { issPage: 'tpa-submit' } },
- undefined,
- (c) => c(wrapper.vm)
- );
+ // Act
+ await tpaSubmit.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { issPage: 'tpa-submit' } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
- // Assert
- const damageSection = wrapper.vm.sections[damageSectionIndex];
- expect(damageSection.lines).toStrictEqual(expectedLines);
- }
- );
+ // Assert
+ const damageSection = wrapper.vm.sections[damageSectionIndex];
+ expect(damageSection.lines).toEqual(expectedLines);
+ });
describe('preferred shop section', () => {
test('has three lines', async () => {
// Arrange
@@ -386,15 +387,12 @@ describe('tpa-submit', () => {
const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex];
expect(preferredShopSection.lines.length).toBe(3);
});
- test.each([
- ['some value', 'some value'],
- ['', ''],
- ['', null],
- ['', undefined]
- ])('first line is %p when company name is %p', async (line, companyName) => {
+ test('first line is value returned from toTitleCase method', async () => {
// Arrange
- const initialData = { companyName };
+ const initialData = { companyName: 'some value' };
const { wrapper } = getMountedComponent({}, initialData);
+ const expectedName = 'some expected name';
+ toTitleCase.mockImplementationOnce(() => expectedName);
const preferredShopSectionIndex = 2;
// Act
@@ -407,7 +405,7 @@ describe('tpa-submit', () => {
// Assert
const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex];
- expect(preferredShopSection.lines[0]).toBe(line);
+ expect(preferredShopSection.lines[0]).toBe(expectedName);
});
test('second line is expected and formatAddress called', async () => {
// Arrange
@@ -426,7 +424,7 @@ describe('tpa-submit', () => {
};
const { wrapper } = getMountedComponent(initialStore);
const line = 'some returned line';
- wrapper.vm.formatAddress = jest.fn().mockImplementationOnce(() => line);
+ formatAddress.mockImplementationOnce(() => line);
const preferredShopSectionIndex = 2;
// Act
@@ -440,8 +438,8 @@ describe('tpa-submit', () => {
// Assert
const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex];
expect(preferredShopSection.lines[1]).toBe(line);
- expect(wrapper.vm.formatAddress).toHaveBeenCalledTimes(1);
- expect(wrapper.vm.formatAddress).toHaveBeenCalledWith(
+ expect(formatAddress).toHaveBeenCalledTimes(1);
+ expect(formatAddress).toHaveBeenCalledWith(
address.streetAddress,
null,
address.city,
@@ -461,7 +459,7 @@ describe('tpa-submit', () => {
};
const { wrapper } = getMountedComponent(initialStore);
const expectedLine = 'returned from to display phone num';
- wrapper.vm.toDisplayPhoneNumber = jest.fn().mockImplementationOnce(() => expectedLine);
+ toDisplayPhoneNumber.mockImplementationOnce(() => expectedLine);
const preferredShopSectionIndex = 2;
// Act
@@ -475,7 +473,7 @@ describe('tpa-submit', () => {
// Assert
const preferredShopSection = wrapper.vm.sections[preferredShopSectionIndex];
expect(preferredShopSection.lines[2]).toBe(expectedLine);
- expect(wrapper.vm.toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber);
+ expect(toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber);
});
});
test('contact info section has expected content', async () => {
@@ -498,7 +496,7 @@ describe('tpa-submit', () => {
const expectedLine1 = 'Jones Eddison';
const expectedLine2 = emailAddress;
const expectedLine3 = 'some value returned';
- wrapper.vm.toDisplayPhoneNumber = jest.fn().mockImplementation((number) => (number === phoneNumber ? expectedLine3 : ''));
+ toDisplayPhoneNumber.mockImplementation((number) => (number === phoneNumber ? expectedLine3 : ''));
const contactInfoSectionIndex = 3;
// Act
@@ -514,7 +512,7 @@ describe('tpa-submit', () => {
expect(contactInfoSection.lines[0]).toBe(expectedLine1);
expect(contactInfoSection.lines[1]).toBe(expectedLine2);
expect(contactInfoSection.lines[2]).toBe(expectedLine3);
- expect(wrapper.vm.toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber);
+ expect(toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber);
});
});
describe('computed', () => {
@@ -762,5 +760,22 @@ describe('tpa-submit', () => {
expect(result).toBe(null);
});
});
+ test.each([
+ [[1, 5, 6], [1, 5, 6]],
+ [[], []],
+ [undefined, []],
+ [null, []]
+ ])('getAnswersNullSafe', (rawAnswers, expected) => {
+ // Arrange
+ const widgetName = 'WidgetName';
+ const { wrapper } = getMountedComponent();
+ wrapper.vm.getCmsContent = jest.fn().mockImplementationOnce(() => rawAnswers);
+
+ // Act
+ const result = wrapper.vm.getAnswersNullSafe(widgetName);
+
+ // Assert
+ expect(result).toEqual(expected);
+ });
});
});
diff --git a/src/layouts/tpa-submit/tpa-submit.vue b/src/layouts/tpa-submit/tpa-submit.vue
index 1ba7f98a..9886298f 100644
--- a/src/layouts/tpa-submit/tpa-submit.vue
+++ b/src/layouts/tpa-submit/tpa-submit.vue
@@ -78,7 +78,9 @@
:customText="orderDetailsBody"
:marginTopSizeOverride="4"
class="mb-4 px-4 small text-color--darker-gray" />
-