Merge pull request #463 from Safelite/feature/richardson/SSR-673
schedule sub header and change loc link
This commit is contained in:
commit
3e4190ec8a
3 changed files with 246 additions and 16 deletions
|
|
@ -19,7 +19,7 @@
|
||||||
:class="justifySubheader">
|
:class="justifySubheader">
|
||||||
<p
|
<p
|
||||||
class="fw-normal mb-0"
|
class="fw-normal mb-0"
|
||||||
:class="alternateFormatting">
|
:class="[alternateFormatting, subTextClasses]">
|
||||||
<span v-html="subText"> </span>
|
<span v-html="subText"> </span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -49,7 +49,8 @@ export default {
|
||||||
issContainingPage: String,
|
issContainingPage: String,
|
||||||
justification: String,
|
justification: String,
|
||||||
stripRteStyle: Boolean,
|
stripRteStyle: Boolean,
|
||||||
subContentProperty: String
|
subContentProperty: String,
|
||||||
|
subTextClasses: String
|
||||||
},
|
},
|
||||||
emits: ['click-event'],
|
emits: ['click-event'],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
||||||
184
src/layouts/schedule-page/schedule-page.spec.js
Normal file
184
src/layouts/schedule-page/schedule-page.spec.js
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
// Components
|
||||||
|
import schedule from '@/layouts/schedule-page/schedule-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';
|
||||||
|
|
||||||
|
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,
|
||||||
|
siteHeader: true,
|
||||||
|
recalModal: true,
|
||||||
|
contentGroupModal: true,
|
||||||
|
alert: true,
|
||||||
|
loadingModal: loadingModalStub
|
||||||
|
};
|
||||||
|
|
||||||
|
methodToRun();
|
||||||
|
|
||||||
|
mountOptions.mixins = [mockMixin];
|
||||||
|
mountOptions.data = () => (
|
||||||
|
initialData
|
||||||
|
);
|
||||||
|
|
||||||
|
const wrapper = shallowMount(schedule, mountOptions);
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const testingPinia = createTestingPinia({
|
||||||
|
initialState: {
|
||||||
|
main: {
|
||||||
|
order: {
|
||||||
|
schedule: {
|
||||||
|
date: '2019-01-01',
|
||||||
|
startTime: '09:00',
|
||||||
|
endTime: '10:00',
|
||||||
|
routeCode: '000'
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [
|
||||||
|
{
|
||||||
|
partNumber: 'ABC123'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
supportingItems: []
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
appointmentType: 'Inshop',
|
||||||
|
zipCode: '12345',
|
||||||
|
zipCodeCtu: '01234',
|
||||||
|
provider: {
|
||||||
|
providerNumber: '123'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: false
|
||||||
|
},
|
||||||
|
referralNumber: '1234567'
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: true
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
useMainStore(testingPinia);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('schedule-page.vue', () => {
|
||||||
|
describe('Initial Load', () => {
|
||||||
|
test('Should pass arePagePrerequisitesValid with a mobile order and no providerNumber', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
wrapper.vm.mainStore.order.serviceLocation.appointmentType = 'Mobile';
|
||||||
|
wrapper.vm.mainStore.order.serviceLocation.provider = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
test('Should pass arePagePrerequisitesValid with an inshop order and providerNumber', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
test('Should fail arePagePrerequisitesValid with an inshop order and no providerNumber', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
wrapper.vm.mainStore.order.serviceLocation.provider.providerNumber = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBeFalsy();
|
||||||
|
});
|
||||||
|
test('Should fail arePagePrerequisitesValid without isInsurance', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
wrapper.vm.mainStore.payment.isInsurance = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(false);
|
||||||
|
});
|
||||||
|
test('Should fail arePagePrerequisitesValid if supportingItems is null', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
wrapper.vm.mainStore.order.lineItems.supportingItems = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(false);
|
||||||
|
});
|
||||||
|
test('Should fail arePagePrerequisitesValid with an replace with no glass parts', async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
wrapper.vm.mainStore.order.lineItems.glassParts = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Rendering', () => {
|
||||||
|
test('Schedule page loads', () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = getShallowMountedComponent();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -5,18 +5,26 @@
|
||||||
@submit="onSubmit"
|
@submit="onSubmit"
|
||||||
@invalidSubmit="onInvalidSubmit">
|
@invalidSubmit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteSubHeader
|
||||||
<div class="container-fluid pb-2">
|
cmsWidgetName="ScheduleSubHeaderWidget"
|
||||||
<p>Placeholder for schedule page</p>
|
subTextClasses="text-center small sub-text"
|
||||||
<siteFooter
|
class="mt-5" />
|
||||||
ref="siteFooter"
|
<template v-if="ChangeShopLink.length">
|
||||||
class="mt-5"
|
<textBlock
|
||||||
cmsWidgetName="SiteFooterWidget"
|
cmsWidgetName="ChangeShopLink"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
justifyText="center"
|
||||||
@ForwardClicked="forwardButtonAction"
|
class="mb-3 text-link-small"
|
||||||
@backClicked="backButtonAction" />
|
marginTopSizeOverride="1" />
|
||||||
</div>
|
</template>
|
||||||
|
<div class="main-content-container">
|
||||||
|
<siteFooter
|
||||||
|
ref="siteFooter"
|
||||||
|
class="mt-5"
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
|
:isForwardActionDisabled="!meta.valid"
|
||||||
|
@backClicked="backButtonAction"
|
||||||
|
@forwardClicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
@ -24,11 +32,13 @@
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||||
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
|
import textBlock from '@/digital-components/text-block/text-block.vue';
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants.js';
|
import { AppointmentTypeStrings } from '@/constants/schedule-constants.js';
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage, splitCopyOnCMSPlaceHolder } from '@/helpers/cms-content-helper';
|
||||||
import settleAllPromises from '@/helpers/layout-helper';
|
import settleAllPromises from '@/helpers/layout-helper';
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
|
@ -38,7 +48,9 @@ export default {
|
||||||
name: 'schedule-page',
|
name: 'schedule-page',
|
||||||
components: {
|
components: {
|
||||||
siteHeader,
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
siteFooter,
|
siteFooter,
|
||||||
|
textBlock,
|
||||||
// eslint-disable-next-line vue/no-reserved-component-names
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
Form
|
Form
|
||||||
},
|
},
|
||||||
|
|
@ -56,7 +68,6 @@ export default {
|
||||||
|
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
|
|
@ -67,8 +78,18 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
ChangeShopLinkText() {
|
||||||
|
return this.getCmsContent('ChangeShopLink', 'Text');
|
||||||
|
},
|
||||||
|
ChangeShopLink() {
|
||||||
|
// Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
|
||||||
|
return this.splitCopyOnCMSPlaceHolder(this.ChangeShopLinkText);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
splitCopyOnCMSPlaceHolder,
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const { serviceLocation } = useMainStore().order;
|
const { serviceLocation } = useMainStore().order;
|
||||||
const serviceLocationPreReqs = serviceLocation.zipCode
|
const serviceLocationPreReqs = serviceLocation.zipCode
|
||||||
|
|
@ -98,3 +119,27 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$page-side-padding: 1.5rem;
|
||||||
|
|
||||||
|
.page-container-grouped-styles {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.main-content-container {
|
||||||
|
padding: 0 1.5rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.text-link-small) {
|
||||||
|
a, .btn-link {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.subheader-primary) {
|
||||||
|
h5.dark-header {
|
||||||
|
margin-bottom: 0.25rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue