Fixing merge conflict

This commit is contained in:
Michaela Brydon 2023-12-04 21:22:48 -05:00
commit e25fc2dff4
7 changed files with 394 additions and 386 deletions

View file

@ -17,9 +17,30 @@ export function stripRteStyle(stringWithStyleTag) {
* @returns {string} * @returns {string}
*/ */
export function toTitleCase(text) { export function toTitleCase(text) {
const temp = text.toLowerCase().split(' '); const temp = text?.toLowerCase()?.split(' ') ?? [];
for (let i = 0; i < temp.length; i++) { for (let i = 0; i < temp.length; i++) {
temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1); temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1);
} }
return temp.join(' '); return temp.join(' ');
} }
/**
* @function toDisplayPhoneNumber
* @summary If 10 or 11 digits are in phoneNumber, then the expected number including dashes will be returned
* in either d-ddd-ddd-dddd or ddd-ddd-dddd format. Otherwise, an empty string will be returned.
* @param {string} phoneNumber
* @returns {string}
*/
export function toDisplayPhoneNumber(phoneNumber) {
let result = '';
if (!phoneNumber) { return result; }
let remainingDigits = phoneNumber.match(/\d+/g).join('');
if (remainingDigits.length === 11) {
result += `${remainingDigits[0]}-`;
remainingDigits = remainingDigits.substring(1);
}
if (remainingDigits.length === 10) {
result += remainingDigits.replace(/^(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
}
return result;
}

View file

@ -0,0 +1,42 @@
import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
describe('text-helper', () => {
test.each([
[undefined, ''],
[null, ''],
['', ''],
['hello world', 'Hello World'],
['hello world', 'Hello World'],
['HEllO worLD', 'Hello World'],
['a991,,:A froG FAMILY', 'A991,,:a Frog Family']
])(
'toTitleCase given "%p" returns "%p"',
(input, expected) => {
// Act
const result = toTitleCase(input);
// Assert
expect(result).toEqual(expected);
}
);
test.each([
[undefined, ''],
[null, ''],
['', ''],
['119', ''],
['1111999900', '111-199-9900'],
['111199-9900', '111-199-9900'],
['111-199-9900', '111-199-9900'],
['01111999900', '0-111-199-9900'],
['0-111-199-9900', '0-111-199-9900']
])(
'getDisplayPhoneNumber',
(input, expected) => {
// Act
const result = toDisplayPhoneNumber(input);
// Assert
expect(result).toEqual(expected);
}
);
});

View file

@ -180,7 +180,7 @@ export default {
if (vehicleLookupResponse.status === 404) { if (vehicleLookupResponse.status === 404) {
this.mainStore.resetVehicleState(); this.mainStore.resetVehicleState();
useMainStore().updateVehicle({ useMainStore().updateVehicle({
policyVehicleId: vehicle.id, policyVehicleId: vehicle.fleetUnitNumber,
carId: '0', carId: '0',
category: '', category: '',
year: vehicle.vehicleYear || '', year: vehicle.vehicleYear || '',
@ -202,7 +202,7 @@ export default {
} }
this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, {
policyVehicleId: vehicle.id, policyVehicleId: vehicle.fleetUnitNumber,
vin: this.selectedVehicleVin, vin: this.selectedVehicleVin,
noCoverage: this.noCoverageForSelectedVehicle, noCoverage: this.noCoverageForSelectedVehicle,
deductible: this.deductibleForSelectedVehicle, deductible: this.deductibleForSelectedVehicle,

View file

@ -5,25 +5,11 @@ Object {
"additionalButtonData": Object { "additionalButtonData": Object {
"displayAvailabilityIndicators": false, "displayAvailabilityIndicators": false,
}, },
"dataLoaded": false,
"filter": "", "filter": "",
"initialLoading": false,
"mapZipCode": "12663", "mapZipCode": "12663",
"providers": Array [], "providers": Array [],
"radiusFilterPairs": Array [ "reloadingProviders": false,
Object {
"filter": "25 miles",
"radius": 25,
},
Object {
"filter": "50 miles",
"radius": 50,
},
Object {
"filter": "100 miles",
"radius": 100,
},
],
"reloadProviders": false,
"rules": Object { "rules": Object {
"filter": "option-required", "filter": "option-required",
"provider": "option-required", "provider": "option-required",

View file

@ -132,7 +132,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(searchQuestionField.exists()).toBeTruthy(); expect(searchQuestionField.exists()).toBeTruthy();
expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionField'); expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionFieldInput');
expect(searchQuestionField.props().isRequired).toBeTruthy(); expect(searchQuestionField.props().isRequired).toBeTruthy();
expect(searchQuestionField.props().cmsWidgetName).toBe(expectedWidgetName); expect(searchQuestionField.props().cmsWidgetName).toBe(expectedWidgetName);
expect(searchQuestionField.props().includeSearchIcon).toBeTruthy(); expect(searchQuestionField.props().includeSearchIcon).toBeTruthy();
@ -150,18 +150,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(providerSelectionForm.exists()).toBeTruthy(); expect(providerSelectionForm.exists()).toBeTruthy();
}); });
test('map loader when initialLoading is true', async () => { test('map', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: true });
// Act
const mapLoader = wrapper.findComponent('#mapLoader');
// Assert
expect(mapLoader.exists()).toBeTruthy();
});
test('map when initialLoading is false', async () => {
// Arrange // Arrange
const zipCode = '12345'; const zipCode = '12345';
const { wrapper } = getMountedComponent(); const { wrapper } = getMountedComponent();
@ -174,8 +163,7 @@ describe('TPA search page', () => {
zipCode: '99230' zipCode: '99230'
} }
}], }],
mapZipCode: zipCode, mapZipCode: zipCode
initialLoading: false
}); });
const expectedAddresses = ['123 Lane Ave, New York, NY 99230']; const expectedAddresses = ['123 Lane Ave, New York, NY 99230'];
@ -188,10 +176,9 @@ describe('TPA search page', () => {
expect(map.props().addresses).toEqual(expectedAddresses); expect(map.props().addresses).toEqual(expectedAddresses);
expect(map.props().zipCode).toBe(zipCode); expect(map.props().zipCode).toBe(zipCode);
}); });
test('search radius filter when initialLoading is false', async () => { test('search radius filter', async () => {
// Arrange // Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false });
const expectedWidgetName = 'FilterByQuestion'; const expectedWidgetName = 'FilterByQuestion';
// Act // Act
@ -202,10 +189,10 @@ describe('TPA search page', () => {
expect(searchRadiusFilter.props().cmsWidgetName).toBe(expectedWidgetName); expect(searchRadiusFilter.props().cmsWidgetName).toBe(expectedWidgetName);
expect(searchRadiusFilter.props().validationRules).toBe(globalRules.OPTION_REQUIRED); expect(searchRadiusFilter.props().validationRules).toBe(globalRules.OPTION_REQUIRED);
}); });
test('providers loader when initialLoading is false and reloadProviders is true', async () => { test('providers loader when reloadingProviders is true', async () => {
// Arrange // Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false, reloadProviders: true }); await wrapper.setData({ reloadingProviders: true });
// Act // Act
const providersLoader = wrapper.findComponent('#providersLoader'); const providersLoader = wrapper.findComponent('#providersLoader');
@ -213,7 +200,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(providersLoader.exists()).toBeTruthy(); expect(providersLoader.exists()).toBeTruthy();
}); });
test('select provider question when initialLoading and reloadProviders are false', async () => { test('select provider question when reloadingProviders are false', async () => {
// Arrange // Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ await wrapper.setData({
@ -229,8 +216,7 @@ describe('TPA search page', () => {
zipCode: '99230' zipCode: '99230'
} }
}], }],
initialLoading: false, reloadingProviders: false
reloadProviders: false
}); });
const expectedAnswers = [{ const expectedAnswers = [{
buttonLabel: 'Shop Auto Glass', buttonLabel: 'Shop Auto Glass',
@ -257,17 +243,14 @@ describe('TPA search page', () => {
expect(selectProviderQuestion.props().additionalButtonData).toEqual(expectedAdditionalButtonData); expect(selectProviderQuestion.props().additionalButtonData).toEqual(expectedAdditionalButtonData);
}); });
test.each([[], null, undefined])( test.each([[], null, undefined])(
'no network providers alert when providers length is 0, undefined, or null and initialLoading and reloadProviders are false', 'no network providers alert when providers length is 0, undefined, or null and reloadingProviders is false',
async (providers) => { async (providers) => {
// Arrange // Arrange
const initialData = { const initialData = {
providers providers
}; };
const wrapper = shallowMount(tpaSearch, getMountOptions({}, initialData)); const wrapper = shallowMount(tpaSearch, getMountOptions({}, initialData));
await wrapper.setData({ await wrapper.setData({ reloadingProviders: false });
initialLoading: false,
reloadProviders: false
});
// Act // Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders'); const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@ -279,13 +262,10 @@ describe('TPA search page', () => {
expect(noNetworkProvidersAlert.props().isDismissible).toBeFalsy(); expect(noNetworkProvidersAlert.props().isDismissible).toBeFalsy();
} }
); );
test('preferred shop not listed link when initialLoading and reloadProviders are false', async () => { test('preferred shop not listed link when reloadingProviders is false', async () => {
// Arrange // Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ await wrapper.setData({ reloadingProviders: false });
initialLoading: false,
reloadProviders: false
});
// Act // Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
@ -308,62 +288,16 @@ describe('TPA search page', () => {
}); });
}); });
describe('should not render', () => { describe('should not render', () => {
test('map loader when initialLoading is false', async () => { test('select provider question when reloadingProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ initialLoading: false });
// Act
const mapLoader = wrapper.findComponent('#mapLoader');
// Assert
expect(mapLoader.exists()).toBeFalsy();
});
test('map when initialLoading is true', async () => {
// Arrange // Arrange
const { wrapper } = getMountedComponent(); const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true }); await wrapper.setData({ reloadingProviders: true });
// Act // Act
const map = wrapper.findComponent('#map'); const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert // Assert
expect(map.exists()).toBeFalsy(); expect(selectProviderQuestion.exists()).toBeFalsy();
});
test('search radius filter when initialLoading is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
// Act
const searchRadiusFilter = wrapper.findComponent('#searchRadiusFilter');
// Assert
expect(searchRadiusFilter.exists()).toBeFalsy();
});
describe('select provider question', () => {
test('when initialLoading is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ initialLoading: true });
// Act
const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
expect(selectProviderQuestion.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ reloadProviders: true });
// Act
const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
expect(selectProviderQuestion.exists()).toBeFalsy();
});
}); });
describe('no network providers alert', () => { describe('no network providers alert', () => {
test('when providers length is not 0', async () => { test('when providers length is not 0', async () => {
@ -377,21 +311,10 @@ describe('TPA search page', () => {
// Assert // Assert
expect(noNetworkProvidersAlert.exists()).toBeFalsy(); expect(noNetworkProvidersAlert.exists()).toBeFalsy();
}); });
test('when initialLoading is true', async () => { test('when reloadingProviders is true', async () => {
// Arrange // Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ providers: [], initialLoading: true }); await wrapper.setData({ providers: [], reloadingProviders: true });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
// Assert
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ providers: [], reloadProviders: true });
// Act // Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders'); const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@ -400,29 +323,16 @@ describe('TPA search page', () => {
expect(noNetworkProvidersAlert.exists()).toBeFalsy(); expect(noNetworkProvidersAlert.exists()).toBeFalsy();
}); });
}); });
describe('preferred shop not listed link', () => { test('preferred shop not listed link when reloadingProviders is true', async () => {
test('when initialLoading is true', async () => { // Arrange
// Arrange const { wrapper } = getMountedComponent();
const { wrapper } = getMountedComponent(); await wrapper.setData({ reloadingProviders: true });
await wrapper.setData({ initialLoading: true });
// Act // Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink'); const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
// Assert // Assert
expect(preferredShopNotListedLink.exists()).toBeFalsy(); expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
test('when reloadProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ reloadProviders: true });
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
// Assert
expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
}); });
}); });
describe('computed', () => { describe('computed', () => {
@ -538,41 +448,27 @@ describe('TPA search page', () => {
} }
); );
describe('radiusInMiles', () => { describe('radiusInMiles', () => {
test('returns 25 when filter is "25 miles"', async () => { test.each([
// Arrange [15, '15 miles'],
const { wrapper } = getMountedComponent(); [25, '25 miles'],
await wrapper.setData({ filter: '25 miles' }); [50, '50 miles'],
[100, '100 miles']
])(
'returns %p when filter is "%p"',
async (expectedRadius, filter) => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter });
// Act // Act
const result = wrapper.vm.radiusInMiles; const result = wrapper.vm.radiusInMiles;
// Assert // Assert
expect(result).toEqual(25); expect(result).toEqual(expectedRadius);
}); }
test('returns 50 when filter is "50 miles"', async () => { );
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter: '50 miles' });
// Act
const result = wrapper.vm.radiusInMiles;
// Assert
expect(result).toEqual(50);
});
test('returns 100 when filter is "100 miles"', async () => {
// Arrange
const { wrapper } = getMountedComponent();
await wrapper.setData({ filter: '100 miles' });
// Act
const result = wrapper.vm.radiusInMiles;
// Assert
expect(result).toEqual(100);
});
test.each([null, undefined, 'some random string'])( test.each([null, undefined, 'some random string'])(
'returns 0 when filter is not "25 miles", "50 miles", or "100 miles"', 'returns 0 when filter is "%p"',
async (filter) => { async (filter) => {
// Arrange // Arrange
const { wrapper } = getMountedComponent(); const { wrapper } = getMountedComponent();
@ -787,7 +683,10 @@ describe('TPA search page', () => {
expect(result).toEqual(false); expect(result).toEqual(false);
} }
); );
test.each([[true, true], [false, false]])( test.each([
[true, true],
[false, false]
])(
'returns %p when first instance of multiple matching providerNumbers has isSafeliteShop value %p', 'returns %p when first instance of multiple matching providerNumbers has isSafeliteShop value %p',
async (expectedOutput, isSafeliteShop) => { async (expectedOutput, isSafeliteShop) => {
// Arrange // Arrange
@ -803,7 +702,8 @@ describe('TPA search page', () => {
} }
]; ];
const wrapper = shallowMount(tpaSearch, getMountOptions()); const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({ selectedProviderNumber, providers }); await wrapper.setData({ providers });
await wrapper.setData({ selectedProviderNumber });
// Act // Act
const result = wrapper.vm.selectedProviderIsSafeliteShop; const result = wrapper.vm.selectedProviderIsSafeliteShop;
@ -841,9 +741,10 @@ describe('TPA search page', () => {
const initialMapZipCode = '88800'; const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, { const { wrapper } = getMountedComponent({}, {
zipCode, zipCode,
mapZipCode: initialMapZipCode mapZipCode: initialMapZipCode,
dataLoaded: true
}); });
const providers = { data: { shopProviders: ['some data', 'some more data']} }; const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers)); useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter'; const newFilter = 'new filter';
@ -855,6 +756,50 @@ describe('TPA search page', () => {
expect(wrapper.vm.providers).toEqual(providers.data.shopProviders); expect(wrapper.vm.providers).toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(zipCode); expect(wrapper.vm.mapZipCode).toBe(zipCode);
}); });
describe('on filter', () => {
test('calls getTpaProviders once and sets providers when dataLoaded is true', async () => {
// Arrange
const zipCode = '78220';
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
zipCode,
mapZipCode: initialMapZipCode,
dataLoaded: true
});
const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter';
// Act
await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter);
// Assert
expect(useMainStore().getTpaProviders).toBeCalled();
expect(wrapper.vm.providers).toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(zipCode);
});
test('never calls getTpaProviders and does not set providers when dataLoaded is false', async () => {
// Arrange
const zipCode = '78220';
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
zipCode,
mapZipCode: initialMapZipCode,
dataLoaded: false
});
const providers = { data: { shopProviders: ['some data', 'some more data'] } };
useMainStore().getTpaProviders = jest.fn().mockImplementationOnce(() => (providers));
const newFilter = 'new filter';
// Act
await wrapper.vm.$options.watch.filter.call(wrapper.vm, newFilter);
// Assert
expect(useMainStore().getTpaProviders).not.toBeCalled();
expect(wrapper.vm.providers).not.toEqual(providers.data.shopProviders);
expect(wrapper.vm.mapZipCode).toBe(initialMapZipCode);
});
});
// TODO confirm tests appropriate. Also should this method be async? // TODO confirm tests appropriate. Also should this method be async?
describe('on providers', () => { describe('on providers', () => {
test.each([null, undefined, []])( test.each([null, undefined, []])(
@ -897,10 +842,10 @@ describe('TPA search page', () => {
}); });
describe('method', () => { describe('method', () => {
test.each([ test.each([
['address', 'city', 'ST', 'zip', 'address, city, ST zip'], ['address', 'city', 'ST', 'zip', 'Address, City, ST zip'],
['address', null, 'ST', 'zip', 'address, ST zip'], ['address', null, 'ST', 'zip', 'Address, ST zip'],
['address', 'city', null, 'zip', 'address, city zip'], ['address', 'city', null, 'zip', 'Address, City zip'],
['address', 'city', 'ST', null, 'address, city, ST'], ['address', 'city', 'ST', null, 'Address, City, ST'],
[null, null, null, null, ''] [null, null, null, null, '']
])( ])(
'getProviderAddress returns expected', 'getProviderAddress returns expected',
@ -1240,6 +1185,32 @@ describe('TPA search page', () => {
}); });
}); });
describe('before route enter', () => { describe('before route enter', () => {
test('when providers exist at 15 mile radius, filter is set to "15 miles" and providers set to expected', async () => {
// Arrange
const { wrapper } = getMountedComponent();
const zipCode = '18394';
useMainStore().order.customer.address.zipCode = zipCode;
const providers = [{ companyName: 'provider' }];
useMainStore().getTpaProviders = jest.fn().mockImplementation((_, radius) =>
({ data: { shopProviders: radius === 15 ? providers : [] } }));
const expectedFilter = '15 miles';
// Act
await tpaSearch.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: 'tpa-search' } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(1);
});
test('when providers exist at 25 mile radius, filter is set to "25 miles" and providers set to expected', async () => { test('when providers exist at 25 mile radius, filter is set to "25 miles" and providers set to expected', async () => {
// Arrange // Arrange
const { wrapper } = getMountedComponent(); const { wrapper } = getMountedComponent();
@ -1264,7 +1235,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers); expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(1); expect(useMainStore().getTpaProviders).toBeCalledTimes(2);
}); });
test('when providers exist at 50 mile radius but not 25, filter is set to "50 miles" and providers set to expected', async () => { test('when providers exist at 50 mile radius but not 25, filter is set to "50 miles" and providers set to expected', async () => {
// Arrange // Arrange
@ -1290,7 +1261,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers); expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(2); expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
}); });
test( test(
'when providers exist at 100 mile radius but not 50 or 25, filter is set to "100 miles" and providers set to expected', 'when providers exist at 100 mile radius but not 50 or 25, filter is set to "100 miles" and providers set to expected',
@ -1318,7 +1289,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers); expect(wrapper.vm.providers).toEqual(providers);
expect(useMainStore().getTpaProviders).toBeCalledTimes(3); expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
} }
); );
test( test(
@ -1345,7 +1316,7 @@ describe('TPA search page', () => {
// Assert // Assert
expect(wrapper.vm.filter).toBe(expectedFilter); expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual([]); expect(wrapper.vm.providers).toEqual([]);
expect(useMainStore().getTpaProviders).toBeCalledTimes(3); expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
} }
); );
}); });

View file

@ -26,77 +26,71 @@
<textboxQuestion <textboxQuestion
id="tpaSearchQuestionField" id="tpaSearchQuestionField"
v-model="zipCode" v-model="zipCode"
inputId="tpaSearchQuestionField" inputId="tpaSearchQuestionFieldInput"
:cmsWidgetName="widget.tpaSearchQuestion" :cmsWidgetName="widget.tpaSearchQuestion"
:includeSearchIcon="true" :includeSearchIcon="true"
:displayQuestionText="false" :displayQuestionText="false"
isRequired isRequired
:isDisabled="reloadingProviders"
:validationRules="rules.zipCode" :validationRules="rules.zipCode"
@clickEvent="searchClick" /> @clickEvent="searchClick" />
</div> </div>
</div> </div>
</div> </div>
</Form> </Form>
<loader <googleMap
v-if="initialLoading" id="map"
id="mapLoader" class="mb-4"
loaderPosition="center" :addresses="providerAddresses"
loaderColor="blue" :zipCode="mapZipCode" />
:width="4" <Form
:height="4" /> id="providerSelectionForm"
<div v-else> v-slot="{ meta }"
<googleMap @submit="onSubmit"
id="map" @invalidSubmit="onInvalidSubmit">
class="mb-4" <div class="container-fluid pb-2">
:addresses="providerAddresses" <div class="mx-5">
:zipCode="mapZipCode"></googleMap> <dropdownQuestion
<Form id="searchRadiusFilter"
id="providerSelectionForm" v-model="filter"
v-slot="{ meta }" :cmsWidgetName="widget.filterByQuestion"
@submit="onSubmit" inputId="searchRadiusFilterInput"
@invalidSubmit="onInvalidSubmit"> :options="filterOptions"
<div class="container-fluid pb-2"> disableAutoFill
<div class="mx-5"> :isDisabled="reloadingProviders"
<dropdownQuestion :validationRules="rules.filter" />
id="searchRadiusFilter" <!-- <dropdownQuestion
v-model="filter" inputId="filterByQuestionField" /> -->
:cmsWidgetName="widget.filterByQuestion" <loader
inputId="filterByQuestionField" v-if="reloadingProviders"
:options="filterOptions" id="providersLoader"
disableAutoFill loaderPosition="center"
:validationRules="rules.filter" /> loaderColor="blue"
<loader :width="2"
v-if="reloadProviders" :height="2"
id="providersLoader" class="my-4" />
loaderPosition="center" <div v-else>
loaderColor="blue" <div class="my-4">
:width="4" <buttonQuestion
:height="4" id="selectProviderQuestion"
class="my-4" /> v-model="selectedProviderNumber"
<div v-else> buttonTypeString="shopListButton"
<div class="my-4"> :buttonTypeObject="shopListButton"
<buttonQuestion class="radioQuestion"
id="selectProviderQuestion" :answers="providerButtonData"
v-model="selectedProviderNumber" groupName="chooseShop"
buttonTypeString="shopListButton" textPosition="text-start"
:buttonTypeObject="shopListButton" isRequired
class="radioQuestion" :validationRules="rules.provider"
:answers="providerButtonData" :additionalButtonData="additionalButtonData" />
groupName="chooseShop" <alert
textPosition="text-start" v-if="providers?.length === 0 ?? true"
isRequired id="alertNoNetworkProviders"
:validationRules="rules.provider" :cmsWidgetName="widget.noNetworkShopsAlert"
:additionalButtonData="additionalButtonData" /> alertClass="alert-warning"
<alert :isDismissible="false"
v-if="providers?.length === 0 ?? true" :manualHeadline="noNetworkShopsAlertHeaderText" />
id="alertNoNetworkProviders" <div class="text-center">
:cmsWidgetName="widget.noNetworkShopsAlert"
alertClass="alert-warning"
:isDismissible="false"
:manualHeadline="noNetworkShopsAlertHeaderText" />
</div>
<div
class="text-center">
<textLink <textLink
id="preferredShopNotListedLink" id="preferredShopNotListedLink"
linkType="navigation" linkType="navigation"
@ -106,15 +100,15 @@
</div> </div>
</div> </div>
</div> </div>
<siteFooter
ref="siteFooter"
:cmsWidgetName="widget.siteFooter"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="backButtonAction" />
</div> </div>
</Form> <siteFooter
</div> ref="siteFooter"
:cmsWidgetName="widget.siteFooter"
:isForwardActionDisabled="!meta.valid"
@ForwardClicked="forwardButtonAction"
@backClicked="backButtonAction" />
</div>
</Form>
</div> </div>
</div> </div>
</template> </template>
@ -134,13 +128,40 @@ import loader from '@/ux-components/loader/loader.vue';
// Supporting files // Supporting files
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-helper';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import globalRules from '@/constants/global-rules.js'; import globalRules from '@/constants/global-rules.js';
import widgetFields from '@/constants/cms-widget-fields.js'; import widgetFields from '@/constants/cms-widget-fields.js';
import { shallowRef } from 'vue'; import { shallowRef } from 'vue';
import { toTitleCase } from '@/helpers/text-helper.js'; import routerParams from '@/router/router-constants/router-params';
import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
const radiusFilterPairs = [
{ radius: 15, filter: '15 miles' },
{ radius: 25, filter: '25 miles' },
{ radius: 50, filter: '50 miles' },
{ radius: 100, filter: '100 miles' }
];
async function getInitialFilterAndProviders() {
const { zipCode } = useMainStore().order.customer.address;
let pairIndex = 0;
let providers = [];
let filter = '';
while (providers.length === 0 && pairIndex < radiusFilterPairs.length) {
const pair = radiusFilterPairs[pairIndex];
const { radius } = pair;
filter = pair.filter;
// eslint-disable-next-line no-await-in-loop
const result = await useMainStore().getTpaProviders(zipCode, radius);
providers = result?.data?.shopProviders ?? [];
pairIndex += 1;
}
return { filter, providers };
}
export default { export default {
name: 'tpa-search', name: 'tpa-search',
@ -159,30 +180,25 @@ export default {
}, },
mixins: [BaseFormMixin], mixins: [BaseFormMixin],
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); const { filter, providers } = await getInitialFilterAndProviders();
const promiseResultMap = [ const cmsContent = await fetchCmsContentForPage(to.query.issPage);
{
resultKey: 'cmsContent',
promise: cmsContentPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
next(async (vm) => { next(async (vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(cmsContent);
await vm.setInitialFilterAndProviders(); vm.setFilter(filter);
vm.setProviders(providers);
}); });
}, },
data() { data() {
const { zipCode } = useMainStore().order.customer.address; const { zipCode } = useMainStore().order.customer.address;
return { return {
dataLoaded: false,
zipCode, zipCode,
mapZipCode: zipCode, mapZipCode: zipCode,
filter: '', filter: '',
providers: [], providers: [],
selectedProviderNumber: '', selectedProviderNumber: '',
initialLoading: false, reloadingProviders: false,
reloadProviders: false,
additionalButtonData: { additionalButtonData: {
displayAvailabilityIndicators: false displayAvailabilityIndicators: false
}, },
@ -200,21 +216,7 @@ export default {
filter: globalRules.OPTION_REQUIRED, // TODO do we even need this? filter: globalRules.OPTION_REQUIRED, // TODO do we even need this?
provider: globalRules.OPTION_REQUIRED provider: globalRules.OPTION_REQUIRED
}, },
shopListButton: shallowRef(shopListButton), shopListButton: shallowRef(shopListButton)
radiusFilterPairs: [
{
radius: 25,
filter: '25 miles'
},
{
radius: 50,
filter: '50 miles'
},
{
radius: 100,
filter: '100 miles'
}
]
}; };
}, },
computed: { computed: {
@ -248,7 +250,7 @@ export default {
); );
}, },
radiusInMiles() { radiusInMiles() {
const pair = this.radiusFilterPairs.find((p) => p.filter === this.filter); const pair = radiusFilterPairs.find((p) => p.filter === this.filter);
return pair?.radius ?? 0; return pair?.radius ?? 0;
}, },
noNetworkShopsAlertHeaderText() { noNetworkShopsAlertHeaderText() {
@ -269,122 +271,108 @@ export default {
}, },
watch: { watch: {
async filter() { async filter() {
if (!this.initialLoading) { if (this.dataLoaded) {
this.reloadProviders = true;
await this.getProviderButtonData().then((providers) => { await this.getProviderButtonData().then((providers) => {
this.providers = providers; this.providers = providers;
}); });
this.mapZipCode = this.zipCode; this.mapZipCode = this.zipCode;
this.reloadProviders = false;
} else {
this.initialLoading = false;
} }
}, },
async providers(newProviders) { providers(newProviders) {
if (newProviders?.length === 1 ?? false) { this.selectedProviderNumber = newProviders?.length === 1 ?? false
this.selectedProviderNumber = newProviders[0]?.providerNumber ?? ''; ? newProviders[0]?.providerNumber ?? ''
} : '';
} }
}, },
methods: beforeUpdate() {
{ if (!this.dataLoaded) {
getProviderAddress(provider) { this.dataLoaded = true;
const city = provider?.address?.city ?? '';
const state = provider?.address?.state ?? '';
const zipCode = provider?.address?.zipCode ?? '';
let addressLine2 = '';
if (city) {
addressLine2 = city;
if (state || zipCode) {
if (state) {
addressLine2 += ',';
}
addressLine2 += ' ';
}
}
if (state) {
addressLine2 += `${state}`;
if (zipCode) {
addressLine2 += ' ';
}
}
if (zipCode) {
addressLine2 += `${zipCode}`;
}
return provider?.address?.streetAddress
? `${provider.address.streetAddress}, ${addressLine2}`
: addressLine2;
},
async setInitialFilterAndProviders() {
this.initialLoading = true;
const { zipCode } = useMainStore().order.customer.address;
let pairIndex = 0;
let providers = [];
let filter = '';
while (providers.length === 0 && pairIndex < this.radiusFilterPairs.length) {
const pair = this.radiusFilterPairs[pairIndex];
const { radius } = pair;
filter = pair.filter;
// eslint-disable-next-line no-await-in-loop
const result = await useMainStore().getTpaProviders(zipCode, radius);
providers = result?.data?.shopProviders ?? [];
pairIndex += 1;
}
this.filter = filter;
this.providers = providers;
},
async getProviderButtonData() {
const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles);
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.$route
);
},
async searchClick() {
this.reloadProviders = true;
this.providers = await this.getProviderButtonData();
this.mapZipCode = this.zipCode;
this.reloadProviders = false;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
const scenario = this.selectedProviderIsSafeliteShop
? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP
: this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP;
this.$router.navigate(scenario, this.$route);
},
getCustomValueFromString(str) {
switch (str) {
case 'radiusInMiles':
return this.radiusInMiles;
default:
return null;
}
},
getShopButtonDataFromProvider(provider) {
const cellNumber = provider?.phoneNumber ?? '';
const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles))
? +provider.distanceInMiles.toFixed(1)
: null;
return {
buttonLabel: provider?.companyName ?? '',
buttonLabelSubCopy: distance === null
? ''
: `${distance} mi`,
buttonBodyCopy: `${this.getProviderAddress(provider)}<br>${cellNumber ?? ''}`,
value: provider?.providerNumber ?? ''
};
}
} }
},
methods: {
setFilter(filter) {
this.filter = filter;
},
setProviders(providers) {
this.providers = providers;
},
getProviderAddress(provider) {
const city = toTitleCase(provider?.address?.city);
const state = provider?.address?.state ?? '';
const zipCode = provider?.address?.zipCode ?? '';
let addressLine2 = '';
if (city) {
addressLine2 += city;
if (state || zipCode) {
addressLine2 += state ? ', ' : ' ';
}
}
if (state) {
addressLine2 += state;
addressLine2 += zipCode ? ' ' : '';
}
if (zipCode) {
addressLine2 += zipCode;
}
const addressLine1 = this.toTitleCase(provider?.address?.streetAddress);
const joinString = addressLine1.length > 0 && addressLine2.length > 0 ? ', ' : '';
return [addressLine1, addressLine2].join(joinString);
},
async getProviderButtonData() {
this.reloadingProviders = true;
const getTpaProvidersResult = await useMainStore().getTpaProviders(this.zipCode, this.radiusInMiles);
this.reloadingProviders = false;
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.$route,
{},
{},
{ [routerParams.NOT_SEEING_PREFERRED_SHOP]: true }
);
},
async searchClick() {
this.providers = await this.getProviderButtonData();
this.mapZipCode = this.zipCode;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
const scenario = this.selectedProviderIsSafeliteShop
? this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP
: this.navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP;
this.$router.navigate(scenario, this.$route);
},
getCustomValueFromString(str) {
switch (str) {
case 'radiusInMiles':
return this.radiusInMiles;
default:
return null;
}
},
getShopButtonDataFromProvider(provider) {
const cellNumber = this.toDisplayPhoneNumber(provider?.phoneNumber);
const distance = provider?.distanceInMiles !== null && !Number.isNaN(parseFloat(provider?.distanceInMiles))
? +provider.distanceInMiles.toFixed(1)
: null;
return {
buttonLabel: provider?.companyName ?? '',
buttonLabelSubCopy: distance === null
? ''
: `${distance} mi`,
buttonBodyCopy: `${this.getProviderAddress(provider)}<br>${cellNumber ?? ''}`,
value: provider?.providerNumber ?? ''
};
},
toDisplayPhoneNumber,
toTitleCase
}
}; };
</script> </script>

View file

@ -186,7 +186,7 @@ router.overrideNavigation = (
isSavingNavigation, isSavingNavigation,
optionalQuery = {}, optionalQuery = {},
optionalParams = {}, optionalParams = {},
optionalPageData optionalPageData = {}
) => { ) => {
navigate( navigate(
scenario, scenario,