diff --git a/src/helpers/text-helper.js b/src/helpers/text-helper.js
index d08e0c04..41e19a66 100644
--- a/src/helpers/text-helper.js
+++ b/src/helpers/text-helper.js
@@ -17,9 +17,30 @@ export function stripRteStyle(stringWithStyleTag) {
* @returns {string}
*/
export function toTitleCase(text) {
- const temp = text.toLowerCase().split(' ');
+ const temp = text?.toLowerCase()?.split(' ') ?? [];
for (let i = 0; i < temp.length; i++) {
temp[i] = temp[i].charAt(0).toUpperCase() + temp[i].slice(1);
}
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;
+}
diff --git a/src/helpers/text-helper.spec.js b/src/helpers/text-helper.spec.js
new file mode 100644
index 00000000..1b2daf64
--- /dev/null
+++ b/src/helpers/text-helper.spec.js
@@ -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);
+ }
+ );
+});
diff --git a/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap b/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap
index fc429c1b..b34c010c 100644
--- a/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap
+++ b/src/layouts/tpa-search/__snapshots__/tpa-search.spec.js.snap
@@ -5,25 +5,11 @@ Object {
"additionalButtonData": Object {
"displayAvailabilityIndicators": false,
},
+ "dataLoaded": false,
"filter": "",
- "initialLoading": false,
"mapZipCode": "12663",
"providers": Array [],
- "radiusFilterPairs": Array [
- Object {
- "filter": "25 miles",
- "radius": 25,
- },
- Object {
- "filter": "50 miles",
- "radius": 50,
- },
- Object {
- "filter": "100 miles",
- "radius": 100,
- },
- ],
- "reloadProviders": false,
+ "reloadingProviders": false,
"rules": Object {
"filter": "option-required",
"provider": "option-required",
diff --git a/src/layouts/tpa-search/tpa-search.spec.js b/src/layouts/tpa-search/tpa-search.spec.js
index d8185733..99754c6b 100644
--- a/src/layouts/tpa-search/tpa-search.spec.js
+++ b/src/layouts/tpa-search/tpa-search.spec.js
@@ -132,7 +132,7 @@ describe('TPA search page', () => {
// Assert
expect(searchQuestionField.exists()).toBeTruthy();
- expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionField');
+ expect(searchQuestionField.props().inputId).toBe('tpaSearchQuestionFieldInput');
expect(searchQuestionField.props().isRequired).toBeTruthy();
expect(searchQuestionField.props().cmsWidgetName).toBe(expectedWidgetName);
expect(searchQuestionField.props().includeSearchIcon).toBeTruthy();
@@ -150,18 +150,7 @@ describe('TPA search page', () => {
// Assert
expect(providerSelectionForm.exists()).toBeTruthy();
});
- test('map loader when initialLoading is true', 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 () => {
+ test('map', async () => {
// Arrange
const zipCode = '12345';
const { wrapper } = getMountedComponent();
@@ -174,8 +163,7 @@ describe('TPA search page', () => {
zipCode: '99230'
}
}],
- mapZipCode: zipCode,
- initialLoading: false
+ mapZipCode: zipCode
});
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().zipCode).toBe(zipCode);
});
- test('search radius filter when initialLoading is false', async () => {
+ test('search radius filter', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
- await wrapper.setData({ initialLoading: false });
const expectedWidgetName = 'FilterByQuestion';
// Act
@@ -202,10 +189,10 @@ describe('TPA search page', () => {
expect(searchRadiusFilter.props().cmsWidgetName).toBe(expectedWidgetName);
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
const wrapper = shallowMount(tpaSearch, getMountOptions());
- await wrapper.setData({ initialLoading: false, reloadProviders: true });
+ await wrapper.setData({ reloadingProviders: true });
// Act
const providersLoader = wrapper.findComponent('#providersLoader');
@@ -213,7 +200,7 @@ describe('TPA search page', () => {
// Assert
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
const wrapper = shallowMount(tpaSearch, getMountOptions());
await wrapper.setData({
@@ -229,8 +216,7 @@ describe('TPA search page', () => {
zipCode: '99230'
}
}],
- initialLoading: false,
- reloadProviders: false
+ reloadingProviders: false
});
const expectedAnswers = [{
buttonLabel: 'Shop Auto Glass',
@@ -257,17 +243,14 @@ describe('TPA search page', () => {
expect(selectProviderQuestion.props().additionalButtonData).toEqual(expectedAdditionalButtonData);
});
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) => {
// Arrange
const initialData = {
providers
};
const wrapper = shallowMount(tpaSearch, getMountOptions({}, initialData));
- await wrapper.setData({
- initialLoading: false,
- reloadProviders: false
- });
+ await wrapper.setData({ reloadingProviders: false });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@@ -279,13 +262,10 @@ describe('TPA search page', () => {
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
const wrapper = shallowMount(tpaSearch, getMountOptions());
- await wrapper.setData({
- initialLoading: false,
- reloadProviders: false
- });
+ await wrapper.setData({ reloadingProviders: false });
// Act
const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
@@ -308,62 +288,16 @@ describe('TPA search page', () => {
});
});
describe('should not render', () => {
- test('map loader when initialLoading is false', 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 () => {
+ test('select provider question when reloadingProviders is true', async () => {
// Arrange
const { wrapper } = getMountedComponent();
- await wrapper.setData({ initialLoading: true });
+ await wrapper.setData({ reloadingProviders: true });
// Act
- const map = wrapper.findComponent('#map');
+ const selectProviderQuestion = wrapper.findComponent('#selectProviderQuestion');
// Assert
- expect(map.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();
- });
+ expect(selectProviderQuestion.exists()).toBeFalsy();
});
describe('no network providers alert', () => {
test('when providers length is not 0', async () => {
@@ -377,21 +311,10 @@ describe('TPA search page', () => {
// Assert
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
- test('when initialLoading is true', async () => {
+ test('when reloadingProviders is true', async () => {
// Arrange
const wrapper = shallowMount(tpaSearch, getMountOptions());
- await wrapper.setData({ providers: [], initialLoading: 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 });
+ await wrapper.setData({ providers: [], reloadingProviders: true });
// Act
const noNetworkProvidersAlert = wrapper.findComponent('#alertNoNetworkProviders');
@@ -400,29 +323,16 @@ describe('TPA search page', () => {
expect(noNetworkProvidersAlert.exists()).toBeFalsy();
});
});
- describe('preferred shop not listed link', () => {
- test('when initialLoading is true', async () => {
- // Arrange
- const { wrapper } = getMountedComponent();
- await wrapper.setData({ initialLoading: true });
+ test('preferred shop not listed link when reloadingProviders is true', async () => {
+ // Arrange
+ const { wrapper } = getMountedComponent();
+ await wrapper.setData({ reloadingProviders: true });
- // Act
- const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
+ // Act
+ const preferredShopNotListedLink = wrapper.findComponent('#preferredShopNotListedLink');
- // Assert
- 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();
- });
+ // Assert
+ expect(preferredShopNotListedLink.exists()).toBeFalsy();
});
});
describe('computed', () => {
@@ -538,41 +448,27 @@ describe('TPA search page', () => {
}
);
describe('radiusInMiles', () => {
- test('returns 25 when filter is "25 miles"', async () => {
- // Arrange
- const { wrapper } = getMountedComponent();
- await wrapper.setData({ filter: '25 miles' });
+ test.each([
+ [15, '15 miles'],
+ [25, '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
- const result = wrapper.vm.radiusInMiles;
+ // Act
+ const result = wrapper.vm.radiusInMiles;
- // Assert
- expect(result).toEqual(25);
- });
- 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);
- });
+ // Assert
+ expect(result).toEqual(expectedRadius);
+ }
+ );
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) => {
// Arrange
const { wrapper } = getMountedComponent();
@@ -787,7 +683,10 @@ describe('TPA search page', () => {
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',
async (expectedOutput, isSafeliteShop) => {
// Arrange
@@ -803,7 +702,8 @@ describe('TPA search page', () => {
}
];
const wrapper = shallowMount(tpaSearch, getMountOptions());
- await wrapper.setData({ selectedProviderNumber, providers });
+ await wrapper.setData({ providers });
+ await wrapper.setData({ selectedProviderNumber });
// Act
const result = wrapper.vm.selectedProviderIsSafeliteShop;
@@ -841,9 +741,10 @@ describe('TPA search page', () => {
const initialMapZipCode = '88800';
const { wrapper } = getMountedComponent({}, {
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));
const newFilter = 'new filter';
@@ -855,6 +756,50 @@ describe('TPA search page', () => {
expect(wrapper.vm.providers).toEqual(providers.data.shopProviders);
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?
describe('on providers', () => {
test.each([null, undefined, []])(
@@ -897,10 +842,10 @@ describe('TPA search page', () => {
});
describe('method', () => {
test.each([
- ['address', 'city', 'ST', 'zip', 'address, city, ST zip'],
- ['address', null, 'ST', 'zip', 'address, ST zip'],
- ['address', 'city', null, 'zip', 'address, city zip'],
- ['address', 'city', 'ST', null, 'address, city, ST'],
+ ['address', 'city', 'ST', 'zip', 'Address, City, ST zip'],
+ ['address', null, 'ST', 'zip', 'Address, ST zip'],
+ ['address', 'city', null, 'zip', 'Address, City zip'],
+ ['address', 'city', 'ST', null, 'Address, City, ST'],
[null, null, null, null, '']
])(
'getProviderAddress returns expected',
@@ -1240,6 +1185,32 @@ describe('TPA search page', () => {
});
});
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 () => {
// Arrange
const { wrapper } = getMountedComponent();
@@ -1264,7 +1235,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
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 () => {
// Arrange
@@ -1290,7 +1261,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
- expect(useMainStore().getTpaProviders).toBeCalledTimes(2);
+ expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
});
test(
'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
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual(providers);
- expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
+ expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
}
);
test(
@@ -1345,7 +1316,7 @@ describe('TPA search page', () => {
// Assert
expect(wrapper.vm.filter).toBe(expectedFilter);
expect(wrapper.vm.providers).toEqual([]);
- expect(useMainStore().getTpaProviders).toBeCalledTimes(3);
+ expect(useMainStore().getTpaProviders).toBeCalledTimes(4);
}
);
});
diff --git a/src/layouts/tpa-search/tpa-search.vue b/src/layouts/tpa-search/tpa-search.vue
index 00ebacdc..8ec7742e 100644
--- a/src/layouts/tpa-search/tpa-search.vue
+++ b/src/layouts/tpa-search/tpa-search.vue
@@ -26,95 +26,88 @@