1067 lines
38 KiB
JavaScript
1067 lines
38 KiB
JavaScript
// Components
|
|
import tpaSearch from '@/layouts/tpa-search/tpa-search.vue';
|
|
|
|
// Supporting Files
|
|
import { nextTick } from 'vue';
|
|
import { shallowMount } from '@vue/test-utils';
|
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
|
import { createTestingPinia } from '@pinia/testing';
|
|
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
|
|
import settleAllPromises from '@/helpers/layout-helper.js';
|
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
|
import { useMainStore } from '@/store';
|
|
import { toTitleCase, toDisplayPhoneNumber } from '@/helpers/text-helper.js';
|
|
import bailoutMessage from '@/constants/bailoutMessage';
|
|
import globalRules from '@/constants/global-rules.js';
|
|
|
|
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
|
|
|
|
jest.mock('@/helpers/cms-content-helper', () => ({
|
|
fetchCmsContentForPage: jest.fn(),
|
|
setupModalLinks: jest.fn(),
|
|
processIfStatements: jest.fn()
|
|
}));
|
|
|
|
jest.mock('@/helpers/text-helper', () => ({
|
|
toTitleCase: jest.fn((text) => text?.toLowerCase()?.replace(/(^|\s|-)\S/g, (letter) => letter.toUpperCase()) ?? ''),
|
|
toDisplayPhoneNumber: jest.fn((phone) => phone ?? '')
|
|
}));
|
|
|
|
const mockMixin = {
|
|
methods: {
|
|
getCmsContent: jest.fn().mockImplementation(() => ''),
|
|
setCmsContent: jest.fn(),
|
|
onSubmit: jest.fn(),
|
|
onInvalidSubmit: jest.fn(),
|
|
navigateBack: jest.fn(),
|
|
savePageDataToStore: jest.fn()
|
|
}
|
|
};
|
|
|
|
const footerStub = {
|
|
render: () => {},
|
|
methods: {
|
|
updateButtonText: jest.fn()
|
|
}
|
|
};
|
|
|
|
const loaderStub = {
|
|
render: () => {},
|
|
template: '<div></div>'
|
|
};
|
|
|
|
function getMountedComponent(mainInitialState = {}, initialData = {}, methodToRun = () => {}) {
|
|
const mountOptions = getMountOptions({
|
|
router: {
|
|
navigate: jest.fn()
|
|
},
|
|
route: {
|
|
query: { issPage: 'tpa-search' }
|
|
}
|
|
});
|
|
|
|
mountOptions.global.stubs = {
|
|
...mountOptions.global.stubs,
|
|
siteFooter: footerStub,
|
|
siteHeader: true,
|
|
textboxQuestion: true,
|
|
dropdownQuestion: true,
|
|
buttonQuestion: true,
|
|
textLink: true,
|
|
alert: true,
|
|
googleMap: true,
|
|
loader: loaderStub
|
|
};
|
|
|
|
const testingPinia = createTestingPinia({
|
|
initialState: {
|
|
main: {
|
|
order: {
|
|
customer: {
|
|
address: {
|
|
zipCode: '43215'
|
|
}
|
|
},
|
|
serviceLocation: {
|
|
provider: {
|
|
providerNumber: ''
|
|
}
|
|
}
|
|
},
|
|
...mainInitialState
|
|
}
|
|
}
|
|
});
|
|
useMainStore(testingPinia);
|
|
methodToRun();
|
|
|
|
mountOptions.global.plugins = [testingPinia];
|
|
mountOptions.mixins = [mockMixin];
|
|
mountOptions.data = () => ({
|
|
dataLoaded: true,
|
|
...initialData
|
|
});
|
|
|
|
const apiResponses = {
|
|
cmsContent: {},
|
|
providers: []
|
|
};
|
|
const apiPromise = Promise.resolve(apiResponses);
|
|
settleAllPromises.mockImplementation(() => apiPromise);
|
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
|
|
const wrapper = shallowMount(tpaSearch, mountOptions);
|
|
return { wrapper };
|
|
}
|
|
|
|
describe('tpa-search.vue', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
test('Should render site header', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const siteHeader = wrapper.findComponent({ ref: 'siteHeader' });
|
|
|
|
// Assert
|
|
expect(siteHeader.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render site footer', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const siteFooter = wrapper.findComponent({ ref: 'siteFooter' });
|
|
|
|
// Assert
|
|
expect(siteFooter.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render tpa search question label', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const label = wrapper.find('#tpaSearchQuestionLabel');
|
|
|
|
// Assert
|
|
expect(label.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render search instructions label', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const label = wrapper.find('#searchInstructions');
|
|
|
|
// Assert
|
|
expect(label.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render textbox question for TPA search', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const textbox = wrapper.find('#tpaSearchQuestionField');
|
|
|
|
// Assert
|
|
expect(textbox.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render dropdown for radius filter', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const dropdown = wrapper.find('#searchRadiusFilter');
|
|
|
|
// Assert
|
|
expect(dropdown.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render google map', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const map = wrapper.find('#map');
|
|
|
|
// Assert
|
|
expect(map.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should show loader state when reloadingProviders is true', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { reloadingProviders: true });
|
|
|
|
// Assert
|
|
expect(wrapper.vm.reloadingProviders).toBe(true);
|
|
});
|
|
|
|
test('Should show provider selection when reloadingProviders is false', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { reloadingProviders: false });
|
|
|
|
// Assert
|
|
expect(wrapper.vm.reloadingProviders).toBe(false);
|
|
});
|
|
|
|
test('Should render no network shops alert when providers is empty', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { providers: [] });
|
|
|
|
// Act
|
|
const alert = wrapper.find('#alertNoNetworkProviders');
|
|
|
|
// Assert
|
|
expect(alert.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should render preferred shop not listed link', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { reloadingProviders: false });
|
|
|
|
// Act
|
|
const link = wrapper.find('#preferredShopNotListedLink');
|
|
|
|
// Assert
|
|
expect(link.exists()).toBe(true);
|
|
});
|
|
|
|
test('Should have needHelpLinkText computed property', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, {
|
|
reloadingProviders: false
|
|
});
|
|
|
|
// Assert - needHelpLinkText computed exists and returns a value (empty string from mock)
|
|
expect(wrapper.vm.needHelpLinkText).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('Computed', () => {
|
|
describe('radiusFilterOptions', () => {
|
|
test('returns empty object when no options', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
const result = wrapper.vm.radiusFilterOptions;
|
|
|
|
// Assert
|
|
expect(result).toEqual({});
|
|
});
|
|
|
|
test('returns formatted options when CMS content exists', () => {
|
|
// Arrange
|
|
const mockOptions = [
|
|
{ Name: '10', Text: '10 miles' },
|
|
{ Name: '25', Text: '25 miles' },
|
|
{ Name: '50', Text: '50 miles' }
|
|
];
|
|
const mountOptions = getMountOptions({ router: { navigate: jest.fn() } });
|
|
mountOptions.global.stubs = { siteFooter: footerStub, siteHeader: true, loader: loaderStub };
|
|
mountOptions.mixins = [{
|
|
methods: {
|
|
getCmsContent: jest.fn().mockImplementation(() => mockOptions),
|
|
setCmsContent: jest.fn(),
|
|
onSubmit: jest.fn(),
|
|
onInvalidSubmit: jest.fn(),
|
|
navigateBack: jest.fn(),
|
|
savePageDataToStore: jest.fn()
|
|
}
|
|
}];
|
|
mountOptions.data = () => ({ dataLoaded: true });
|
|
const wrapper = shallowMount(tpaSearch, mountOptions);
|
|
|
|
// Act
|
|
const result = wrapper.vm.radiusFilterOptions;
|
|
|
|
// Assert
|
|
expect(result).toEqual({
|
|
'10': '10 miles',
|
|
'25': '25 miles',
|
|
'50': '50 miles'
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('radiusFilteredAndCappedProviders', () => {
|
|
test('filters providers by radius and caps at 5', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '1', distanceInMiles: 5, companyName: 'Shop 1', address: {} },
|
|
{ providerNumber: '2', distanceInMiles: 15, companyName: 'Shop 2', address: {} },
|
|
{ providerNumber: '3', distanceInMiles: 20, companyName: 'Shop 3', address: {} },
|
|
{ providerNumber: '4', distanceInMiles: 30, companyName: 'Shop 4', address: {} },
|
|
{ providerNumber: '5', distanceInMiles: 35, companyName: 'Shop 5', address: {} },
|
|
{ providerNumber: '6', distanceInMiles: 40, companyName: 'Shop 6', address: {} },
|
|
{ providerNumber: '7', distanceInMiles: 45, companyName: 'Shop 7', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { providers, radiusFilter: 50 });
|
|
|
|
// Act
|
|
const result = wrapper.vm.radiusFilteredAndCappedProviders;
|
|
|
|
// Assert
|
|
expect(result.length).toBe(5);
|
|
});
|
|
|
|
test('filters out providers beyond radius', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '1', distanceInMiles: 5, companyName: 'Shop 1', address: {} },
|
|
{ providerNumber: '2', distanceInMiles: 15, companyName: 'Shop 2', address: {} },
|
|
{ providerNumber: '3', distanceInMiles: 30, companyName: 'Shop 3', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { providers, radiusFilter: 25 });
|
|
|
|
// Act
|
|
const result = wrapper.vm.radiusFilteredAndCappedProviders;
|
|
|
|
// Assert
|
|
expect(result.length).toBe(2);
|
|
expect(result.map(p => p.providerNumber)).toEqual(['1', '2']);
|
|
});
|
|
});
|
|
|
|
describe('providerAddresses', () => {
|
|
test('maps providers to address objects for google map', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{
|
|
providerNumber: '1',
|
|
companyName: 'TEST SHOP',
|
|
distanceInMiles: 5,
|
|
address: {
|
|
streetAddress: '123 MAIN ST',
|
|
city: 'COLUMBUS',
|
|
state: 'OH',
|
|
zipCode: '43215'
|
|
}
|
|
}
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { providers, radiusFilter: 25 });
|
|
|
|
// Act
|
|
const result = wrapper.vm.providerAddresses;
|
|
|
|
// Assert
|
|
expect(result.length).toBe(1);
|
|
expect(result[0].title).toBe('test shop');
|
|
expect(result[0].addressLines.length).toBe(2);
|
|
});
|
|
|
|
test('returns empty array when no providers', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { providers: [], radiusFilter: 25 });
|
|
|
|
// Act
|
|
const result = wrapper.vm.providerAddresses;
|
|
|
|
// Assert
|
|
expect(result).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('providerButtonData', () => {
|
|
test('maps providers to button data format', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{
|
|
providerNumber: '12345',
|
|
companyName: 'AUTO GLASS SHOP',
|
|
distanceInMiles: 5.75,
|
|
phoneNumber: '6145551234',
|
|
address: {
|
|
streetAddress: '456 OAK AVE',
|
|
city: 'DUBLIN',
|
|
state: 'OH',
|
|
zipCode: '43017'
|
|
}
|
|
}
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { providers, radiusFilter: 25 });
|
|
|
|
// Act
|
|
const result = wrapper.vm.providerButtonData;
|
|
|
|
// Assert
|
|
expect(result.length).toBe(1);
|
|
expect(result[0].buttonLabel).toBe('auto glass shop');
|
|
expect(result[0].buttonLabelSubCopy).toBe('5.8 mi');
|
|
expect(result[0].value).toBe('12345');
|
|
});
|
|
});
|
|
|
|
describe('selectedProviderIsSafeliteShop', () => {
|
|
test('returns true when selected provider is Safelite shop', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: true },
|
|
{ providerNumber: '456', isSafeliteShop: false }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '123',
|
|
radiusFilter: 25
|
|
});
|
|
|
|
// Act
|
|
const result = wrapper.vm.selectedProviderIsSafeliteShop;
|
|
|
|
// Assert
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
test('returns false when selected provider is not Safelite shop', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: true },
|
|
{ providerNumber: '456', isSafeliteShop: false }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '456',
|
|
radiusFilter: 25
|
|
});
|
|
|
|
// Act
|
|
const result = wrapper.vm.selectedProviderIsSafeliteShop;
|
|
|
|
// Assert
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
test('returns false when no provider is selected', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: true }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '',
|
|
radiusFilter: 25
|
|
});
|
|
|
|
// Act
|
|
const result = wrapper.vm.selectedProviderIsSafeliteShop;
|
|
|
|
// Assert
|
|
expect(result).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('noNetworkShopsAlertHeaderText', () => {
|
|
test('replaces radius placeholder with actual value', () => {
|
|
// Arrange
|
|
const mountOptions = getMountOptions({ router: { navigate: jest.fn() } });
|
|
mountOptions.global.stubs = { siteFooter: footerStub, siteHeader: true, loader: loaderStub };
|
|
mountOptions.mixins = [{
|
|
methods: {
|
|
getCmsContent: jest.fn().mockImplementation(() => 'No shops within {custom:radiusInMiles}'),
|
|
setCmsContent: jest.fn(),
|
|
onSubmit: jest.fn(),
|
|
onInvalidSubmit: jest.fn(),
|
|
navigateBack: jest.fn(),
|
|
savePageDataToStore: jest.fn()
|
|
}
|
|
}];
|
|
mountOptions.data = () => ({ dataLoaded: true, radiusFilter: 25 });
|
|
const wrapper = shallowMount(tpaSearch, mountOptions);
|
|
|
|
// Act
|
|
const result = wrapper.vm.noNetworkShopsAlertHeaderText;
|
|
|
|
// Assert
|
|
expect(result).toBe('No shops within 25 miles');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Methods', () => {
|
|
describe('getFullProviderAddress', () => {
|
|
test('returns combined address lines', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
address: {
|
|
streetAddress: '123 MAIN ST',
|
|
city: 'COLUMBUS',
|
|
state: 'OH',
|
|
zipCode: '43215'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getFullProviderAddress(provider);
|
|
|
|
// Assert
|
|
expect(result).toContain('123 Main St');
|
|
expect(result).toContain('Columbus');
|
|
expect(result).toContain('OH');
|
|
expect(result).toContain('43215');
|
|
});
|
|
});
|
|
|
|
describe('getProviderAddress', () => {
|
|
test('returns title cased street address', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
address: {
|
|
streetAddress: 'UPPERCASE STREET'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getProviderAddress(provider);
|
|
|
|
// Assert
|
|
expect(toTitleCase).toHaveBeenCalledWith('UPPERCASE STREET');
|
|
});
|
|
|
|
test('handles null address', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = { address: null };
|
|
|
|
// Act
|
|
const result = wrapper.vm.getProviderAddress(provider);
|
|
|
|
// Assert
|
|
expect(result).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('getProviderCityZipState', () => {
|
|
test('returns formatted city, state, zip', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
address: {
|
|
city: 'COLUMBUS',
|
|
state: 'OH',
|
|
zipCode: '43215'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getProviderCityZipState(provider);
|
|
|
|
// Assert
|
|
expect(result).toContain('OH');
|
|
expect(result).toContain('43215');
|
|
});
|
|
|
|
test('handles missing city', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
address: {
|
|
state: 'OH',
|
|
zipCode: '43215'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getProviderCityZipState(provider);
|
|
|
|
// Assert
|
|
expect(result).toBe('OH 43215');
|
|
});
|
|
|
|
test('handles missing state and zip', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
address: {
|
|
city: 'COLUMBUS'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getProviderCityZipState(provider);
|
|
|
|
// Assert
|
|
expect(result).toContain('Columbus');
|
|
});
|
|
});
|
|
|
|
describe('getShopButtonDataFromProvider', () => {
|
|
test('returns formatted button data with distance', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
providerNumber: '12345',
|
|
companyName: 'TEST SHOP',
|
|
distanceInMiles: 5.789,
|
|
phoneNumber: '6145551234',
|
|
address: {
|
|
streetAddress: '123 MAIN ST',
|
|
city: 'COLUMBUS',
|
|
state: 'OH',
|
|
zipCode: '43215'
|
|
}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getShopButtonDataFromProvider(provider);
|
|
|
|
// Assert
|
|
expect(result.buttonLabel).toBe('test shop');
|
|
expect(result.buttonLabelSubCopy).toBe('5.8 mi');
|
|
expect(result.value).toBe('12345');
|
|
expect(result.buttonBodyCopy).toContain('<br>');
|
|
});
|
|
|
|
test('returns empty distance when distanceInMiles is null', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
providerNumber: '12345',
|
|
companyName: 'TEST SHOP',
|
|
distanceInMiles: null,
|
|
phoneNumber: '6145551234',
|
|
address: {}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getShopButtonDataFromProvider(provider);
|
|
|
|
// Assert
|
|
expect(result.buttonLabelSubCopy).toBe('');
|
|
});
|
|
|
|
test('returns empty distance when distanceInMiles is NaN', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
const provider = {
|
|
providerNumber: '12345',
|
|
companyName: 'TEST SHOP',
|
|
distanceInMiles: NaN,
|
|
phoneNumber: '6145551234',
|
|
address: {}
|
|
};
|
|
|
|
// Act
|
|
const result = wrapper.vm.getShopButtonDataFromProvider(provider);
|
|
|
|
// Assert
|
|
expect(result.buttonLabelSubCopy).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('searchClick', () => {
|
|
test('searches by shop name when input is not a zip code', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
wrapper.vm.tpaSearchValue = 'Auto Glass Shop';
|
|
wrapper.vm.getProviderButtonData = jest.fn().mockResolvedValue([]);
|
|
|
|
// Act
|
|
await wrapper.vm.searchClick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.getProviderButtonData).toHaveBeenCalledWith('Auto Glass Shop');
|
|
});
|
|
|
|
test('updates mapZipCode when input is a zip code', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
wrapper.vm.tpaSearchValue = '43215';
|
|
wrapper.vm.mapZipCode = '12345';
|
|
wrapper.vm.getProviderButtonData = jest.fn().mockResolvedValue([]);
|
|
|
|
// Act
|
|
await wrapper.vm.searchClick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mapZipCode).toBe('43215');
|
|
expect(wrapper.vm.getProviderButtonData).toHaveBeenCalledWith();
|
|
});
|
|
});
|
|
|
|
describe('forwardButtonAction', () => {
|
|
test('navigates with SAFELITE_SHOP scenario when provider is Safelite', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: true, distanceInMiles: 5, companyName: 'Safelite', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '123',
|
|
radiusFilter: 25,
|
|
tpaSearchValue: 'test',
|
|
mapZipCode: '43215'
|
|
});
|
|
|
|
// Act
|
|
wrapper.vm.forwardButtonAction();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.updateIsSafeliteProvider).toHaveBeenCalledWith(true);
|
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
|
navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE_SHOP,
|
|
expect.anything()
|
|
);
|
|
});
|
|
|
|
test('navigates with NON_SAFELITE_SHOP scenario when provider is not Safelite', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '456', isSafeliteShop: false, distanceInMiles: 5, companyName: 'Other Shop', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '456',
|
|
radiusFilter: 25,
|
|
tpaSearchValue: 'test',
|
|
mapZipCode: '43215'
|
|
});
|
|
|
|
// Act
|
|
wrapper.vm.forwardButtonAction();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
|
navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP,
|
|
expect.anything()
|
|
);
|
|
});
|
|
|
|
test('saves empty tpaSearchValue when it equals mapZipCode', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: false, distanceInMiles: 5, companyName: 'Test Shop', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '123',
|
|
radiusFilter: 25,
|
|
tpaSearchValue: '43215',
|
|
mapZipCode: '43215'
|
|
});
|
|
const savePageDataSpy = jest.spyOn(wrapper.vm, 'savePageDataToStore');
|
|
|
|
// Act
|
|
wrapper.vm.forwardButtonAction();
|
|
|
|
// Assert
|
|
expect(savePageDataSpy).toHaveBeenCalledWith(
|
|
expect.anything(),
|
|
expect.objectContaining({ tpaSearchValue: '' })
|
|
);
|
|
});
|
|
|
|
test('saves tpaSearchValue when different from mapZipCode', () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '123', isSafeliteShop: false, distanceInMiles: 5, companyName: 'Auto Shop', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, {
|
|
providers,
|
|
selectedProviderNumber: '123',
|
|
radiusFilter: 25,
|
|
tpaSearchValue: 'Auto Shop',
|
|
mapZipCode: '43215'
|
|
});
|
|
const savePageDataSpy = jest.spyOn(wrapper.vm, 'savePageDataToStore');
|
|
|
|
// Act
|
|
wrapper.vm.forwardButtonAction();
|
|
|
|
// Assert
|
|
expect(savePageDataSpy).toHaveBeenCalledWith(
|
|
expect.anything(),
|
|
expect.objectContaining({ tpaSearchValue: 'Auto Shop' })
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('needHelpLinkClick', () => {
|
|
test('sets bailout and navigates', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Act
|
|
wrapper.vm.needHelpLinkClick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalled();
|
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
|
navigationScenarios.CLICKED_NEED_HELP,
|
|
expect.anything()
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('getProviderButtonData', () => {
|
|
test('sets reloadingProviders to true then false', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
wrapper.vm.mainStore.getTpaAndSafeliteProviders = jest.fn().mockResolvedValue({ data: [] });
|
|
|
|
// Act
|
|
const promise = wrapper.vm.getProviderButtonData();
|
|
expect(wrapper.vm.reloadingProviders).toBe(true);
|
|
await promise;
|
|
|
|
// Assert
|
|
expect(wrapper.vm.reloadingProviders).toBe(false);
|
|
});
|
|
|
|
test('calls store method with zipCode and shopName', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
wrapper.vm.mapZipCode = '43215';
|
|
wrapper.vm.mainStore.getTpaAndSafeliteProviders = jest.fn().mockResolvedValue({ data: [] });
|
|
|
|
// Act
|
|
await wrapper.vm.getProviderButtonData('Test Shop');
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.getTpaAndSafeliteProviders).toHaveBeenCalledWith('43215', 'Test Shop');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Watchers', () => {
|
|
describe('providers watcher', () => {
|
|
test('auto-selects provider when only one provider exists', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: true });
|
|
wrapper.vm.selectedProviderNumber = '';
|
|
|
|
// Act
|
|
wrapper.vm.providers = [{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Test Shop', address: {} }];
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.selectedProviderNumber).toBe('12345');
|
|
});
|
|
|
|
test('clears selection when multiple providers exist', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: true });
|
|
wrapper.vm.selectedProviderNumber = '12345';
|
|
|
|
// Act
|
|
wrapper.vm.providers = [
|
|
{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Shop 1', address: {} },
|
|
{ providerNumber: '67890', distanceInMiles: 10, companyName: 'Shop 2', address: {} }
|
|
];
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.selectedProviderNumber).toBe('');
|
|
});
|
|
|
|
test('does not auto-select when dataLoaded is false', async () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: false });
|
|
wrapper.vm.selectedProviderNumber = '';
|
|
|
|
// Act
|
|
wrapper.vm.providers = [{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Test', address: {} }];
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.selectedProviderNumber).toBe('');
|
|
});
|
|
});
|
|
|
|
describe('selectedProviderNumber watcher', () => {
|
|
test('updates service location in store when provider is selected', async () => {
|
|
// Arrange
|
|
const providers = [
|
|
{
|
|
providerNumber: '12345',
|
|
companyName: 'Test Shop',
|
|
phoneNumber: '6145551234',
|
|
address: {
|
|
streetAddress: '123 Main St',
|
|
city: 'Columbus',
|
|
state: 'OH',
|
|
zipCode: '43215',
|
|
zipCodeCtu: '01234'
|
|
},
|
|
distanceInMiles: 5
|
|
}
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: true, providers, radiusFilter: 25 });
|
|
|
|
// Act
|
|
wrapper.vm.selectedProviderNumber = '12345';
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.updateServiceLocation).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
provider: expect.objectContaining({
|
|
providerNumber: '12345',
|
|
companyName: 'Test Shop'
|
|
})
|
|
})
|
|
);
|
|
});
|
|
|
|
test('does not update store when provider not found', async () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Test', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: true, providers, radiusFilter: 25 });
|
|
wrapper.vm.mainStore.updateServiceLocation.mockClear();
|
|
|
|
// Act
|
|
wrapper.vm.selectedProviderNumber = '99999';
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.updateServiceLocation).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('does not update store when dataLoaded is false', async () => {
|
|
// Arrange
|
|
const providers = [
|
|
{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Test', address: {} }
|
|
];
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: false, providers, radiusFilter: 25 });
|
|
wrapper.vm.mainStore.updateServiceLocation.mockClear();
|
|
|
|
// Act
|
|
wrapper.vm.selectedProviderNumber = '12345';
|
|
await nextTick();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.mainStore.updateServiceLocation).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('beforeRouteEnter', () => {
|
|
test('fetches CMS content and providers on route enter', async () => {
|
|
// Arrange
|
|
const mockProviders = [
|
|
{ providerNumber: '123', distanceInMiles: 5 }
|
|
];
|
|
const { wrapper } = getMountedComponent();
|
|
settleAllPromises.mockImplementation(() => ({
|
|
cmsContent: {},
|
|
providers: mockProviders
|
|
}));
|
|
|
|
const to = { query: { issPage: 'tpa-search' } };
|
|
const next = jest.fn((callback) => {
|
|
if (typeof callback === 'function') {
|
|
callback(wrapper.vm);
|
|
}
|
|
});
|
|
|
|
// Act
|
|
await tpaSearch.beforeRouteEnter(to, undefined, next);
|
|
|
|
// Assert
|
|
expect(next).toHaveBeenCalled();
|
|
});
|
|
|
|
test('restores page data from store if available', async () => {
|
|
// Arrange
|
|
const pageData = {
|
|
tpaSearchValue: 'Test Shop',
|
|
radiusFilter: 50
|
|
};
|
|
const { wrapper } = getMountedComponent();
|
|
wrapper.vm.mainStore.pageData = jest.fn().mockReturnValue(pageData);
|
|
settleAllPromises.mockImplementation(() => ({
|
|
cmsContent: {},
|
|
providers: []
|
|
}));
|
|
|
|
const to = { query: { issPage: 'tpa-search' } };
|
|
const next = jest.fn((callback) => {
|
|
if (typeof callback === 'function') {
|
|
callback(wrapper.vm);
|
|
}
|
|
});
|
|
|
|
// Act
|
|
await tpaSearch.beforeRouteEnter(to, undefined, next);
|
|
|
|
// Assert
|
|
expect(next).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('Data initialization', () => {
|
|
test('widget names are correctly defined', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.widget.siteHeader).toBe('SiteHeaderWidget');
|
|
expect(wrapper.vm.widget.tpaSearchQuestion).toBe('TPASearchQuestion');
|
|
expect(wrapper.vm.widget.filterByQuestion).toBe('FilterByQuestion');
|
|
expect(wrapper.vm.widget.noNetworkShopsAlert).toBe('NoNetworkShopsAlertWidget');
|
|
expect(wrapper.vm.widget.siteFooter).toBe('SiteFooterWidget');
|
|
});
|
|
|
|
test('validation rules are correctly defined', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.rules.tpaSearch).toBe(globalRules.TPA_SEARCH_FORMAT);
|
|
expect(wrapper.vm.rules.filter).toBe(globalRules.OPTION_REQUIRED);
|
|
expect(wrapper.vm.rules.provider).toBe(globalRules.OPTION_REQUIRED);
|
|
});
|
|
|
|
test('additionalButtonData is correctly initialized', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.additionalButtonData).toEqual({
|
|
displayAvailabilityIndicators: false
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('dataLoaded flag', () => {
|
|
test('dataLoaded can be initialized as false', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: false });
|
|
|
|
// Assert - verify initial state
|
|
expect(wrapper.vm.dataLoaded).toBe(false);
|
|
});
|
|
|
|
test('dataLoaded can be initialized as true', () => {
|
|
// Arrange
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: true });
|
|
|
|
// Assert
|
|
expect(wrapper.vm.dataLoaded).toBe(true);
|
|
});
|
|
|
|
test('dataLoaded affects provider watcher behavior', async () => {
|
|
// Arrange - with dataLoaded false, provider watcher should not auto-select
|
|
const { wrapper } = getMountedComponent({}, { dataLoaded: false, selectedProviderNumber: '' });
|
|
|
|
// Act - set providers (watcher should not auto-select because dataLoaded is false)
|
|
wrapper.vm.providers = [{ providerNumber: '12345', distanceInMiles: 5, companyName: 'Test', address: {} }];
|
|
await nextTick();
|
|
|
|
// Assert - selectedProviderNumber should remain empty
|
|
expect(wrapper.vm.selectedProviderNumber).toBe('');
|
|
});
|
|
});
|
|
});
|