Merge branch 'develop' into SSR-1160-add-desktop-functionality

This commit is contained in:
bmauger 2024-04-15 13:38:42 -04:00 committed by GitHub
commit 3537fee2ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1108 additions and 337 deletions

View file

@ -45,7 +45,8 @@ module.exports = {
}], }],
'import/extensions': ['error', 'always', { js: 'ignorePackages' }], 'import/extensions': ['error', 'always', { js: 'ignorePackages' }],
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['item'] }], 'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['item'] }],
'no-restricted-syntax': ['off', 'ForOfStatement'] 'no-restricted-syntax': ['off', 'ForOfStatement'],
'no-return-await': 'off'
}, },
settings: { settings: {
'import/resolver': { 'import/resolver': {

View file

@ -19,8 +19,6 @@ const applicationConfig = Object.freeze({
SAFELITE_HOP: process.env.VUE_APP_SAFELITE_HOP, SAFELITE_HOP: process.env.VUE_APP_SAFELITE_HOP,
ISS_DEV_CMS_DOMAIN: 'https://digitalisscms.dev.safelite.io', ISS_DEV_CMS_DOMAIN: 'https://digitalisscms.dev.safelite.io',
CASH_PARENT_ACCOUNT_NUMBER: 167132, CASH_PARENT_ACCOUNT_NUMBER: 167132,
ITAC_FAIR_AND_REASONABLE_BILLTO: '214616', // Lib Mutal FnR BillTo
ITAC_CASH_BILLTO: '283393', // Lib Mutal ITAC Cash BillTo
GOOGLE_CALENDAR: 'https://www.google.com/calendar/render?action=TEMPLATE', GOOGLE_CALENDAR: 'https://www.google.com/calendar/render?action=TEMPLATE',
YAHOO_CALENDAR: 'https://calendar.yahoo.com/?v=60', YAHOO_CALENDAR: 'https://calendar.yahoo.com/?v=60',
OUTLOOK_CALENDAR: OUTLOOK_CALENDAR:

View file

@ -0,0 +1,7 @@
const cartItemType = Object.freeze({
RECYCLE_FEE: 'RECYCLE FEE',
MOBILE_FEE: 'MOBILE FEE',
VAP: 'VAP'
});
export default cartItemType;

View file

@ -1,15 +1,15 @@
const CONTENT_BASE_URL = '/content/api/v1/content';
const LOCATION_BASE_URL = '/location/api/v1/location';
const SCHEDULE_BASE_URL = '/schedule/api/v1/schedule';
const PARTS_BASE_URL = '/parts/api/v1/parts';
const VEHICLE_BASE_URL = '/vehicle/api/v1/vehicle';
const PRICE_BASE_URL = '/price/api/v1/price';
const ACCOUNT_BASE_URL = '/account/api/v1/account'; const ACCOUNT_BASE_URL = '/account/api/v1/account';
const EXPERIMENTS_BASE_URL = '/experiments/api/v1/experiments';
const ANALYTICS_BASE_URL = '/analytics/api/v1/analytics'; const ANALYTICS_BASE_URL = '/analytics/api/v1/analytics';
const CLIENT_AUTH_BASE_URL = '/clientauth/api/v1/clientauth'; const CLIENT_AUTH_BASE_URL = '/clientauth/api/v1/clientauth';
const CONTENT_BASE_URL = '/content/api/v1/content';
const COVERAGE_BASE_URL = '/coverage/api/v1/coverage'; const COVERAGE_BASE_URL = '/coverage/api/v1/coverage';
const EXPERIMENTS_BASE_URL = '/experiments/api/v1/experiments';
const LOCATION_BASE_URL = '/location/api/v1/location';
const ORDER_BASE_URL = '/order/api/v1/order'; const ORDER_BASE_URL = '/order/api/v1/order';
const PARTS_BASE_URL = '/parts/api/v1/parts';
const PRICE_BASE_URL = '/price/api/v1/price';
const SCHEDULE_BASE_URL = '/schedule/api/v1/schedule';
const VEHICLE_BASE_URL = '/vehicle/api/v1/vehicle';
const endpoints = Object.freeze({ const endpoints = Object.freeze({
GetRouteInfo: { GetRouteInfo: {
@ -24,6 +24,10 @@ const endpoints = Object.freeze({
url: (applicationAbbreviation, pageName) => `${CONTENT_BASE_URL}/${applicationAbbreviation}/${pageName}`, url: (applicationAbbreviation, pageName) => `${CONTENT_BASE_URL}/${applicationAbbreviation}/${pageName}`,
method: 'GET' method: 'GET'
}, },
GetBillToInfo: {
url: `${ACCOUNT_BASE_URL}/bill-to-info`,
method: 'POST'
},
GetAlertReasons: { GetAlertReasons: {
url: `${LOCATION_BASE_URL}/alert-reasons`, url: `${LOCATION_BASE_URL}/alert-reasons`,
method: 'GET' method: 'GET'

View file

@ -1,4 +1,4 @@
const partNumberStrings = Object.freeze({ const partNumberStrings = Object.freeze({
RECYCLE_FEE: 'RECYCLE FEE' RECYCLE_FEE: 'RECYCLE FEE'
}); });

View file

@ -2,6 +2,11 @@
exports[`cart-dropdown component initial data rendered as expected 1`] = ` exports[`cart-dropdown component initial data rendered as expected 1`] = `
Object { Object {
"cartItemType": Object {
"MOBILE_FEE": "MOBILE FEE",
"RECYCLE_FEE": "RECYCLE FEE",
"VAP": "VAP",
},
"isExpanded": false, "isExpanded": false,
"widget": Object { "widget": Object {
"amountDue": "AmountDueTextWidget", "amountDue": "AmountDueTextWidget",

View file

@ -46,6 +46,14 @@ function getMountedComponent(mainInitialState = {}, initialData = {}, propsData
return { wrapper }; return { wrapper };
} }
beforeEach(() => {
const store = useMainStore();
const defaultState = getDefaultState();
Object.keys(defaultState).forEach((key) => {
store[key] = defaultState[key];
});
});
describe('cart-dropdown component', () => { describe('cart-dropdown component', () => {
test('initial data rendered as expected', () => { test('initial data rendered as expected', () => {
// Arrange // Arrange
@ -142,6 +150,42 @@ describe('cart-dropdown component', () => {
// Assert // Assert
expect(servicePackage.exists()).toBeTruthy(); expect(servicePackage.exists()).toBeTruthy();
}); });
test('non service package cart items', () => {
// Arrange
const reference = '#non-packaged-cart-items';
const isExpanded = true;
const initialData = { isExpanded };
const { wrapper } = getMountedComponent({}, {}, initialData);
// Act
const nonPackagedCartItems = wrapper.find(reference);
// Assert
expect(nonPackagedCartItems.exists()).toBeTruthy();
});
test('recycle cart item label when isRecycle true for some cart item', () => {
// Arrange
const reference = '#recycle-fee-label';
const isExpanded = true;
const initialPropsData = { isExpanded };
const storeData = {
order: {
lineItems: {
supportingItems: [
{ partNumber: partNumberStrings.RECYCLE_FEE }
]
}
}
};
const { wrapper } = getMountedComponent(storeData, {}, initialPropsData);
// Act
const recycleFeeLabel = wrapper.find(reference);
// Assert
expect(wrapper.vm.recycleFeeCartItem).not.toBeNull();
expect(recycleFeeLabel.exists()).toBeTruthy();
});
test('cart footer', () => { test('cart footer', () => {
// Arrange // Arrange
const reference = '#cart-footer'; const reference = '#cart-footer';
@ -181,45 +225,6 @@ describe('cart-dropdown component', () => {
// Assert // Assert
expect(salesTax.exists()).toBeTruthy(); expect(salesTax.exists()).toBeTruthy();
}); });
test('recycle fee when preset in supported items', () => {
// Arrange
const reference = '#recycle-fee-item';
const { wrapper } = getMountedComponent({
order: {
lineItems: {
supportingItems: [{
partNumber: partNumberStrings.RECYCLE_FEE
}]
}
}
});
// Act
const recycleFee = wrapper.find(reference);
// Assert
expect(wrapper.vm.recycleFeeCartItem).not.toBeNull();
expect(recycleFee.exists()).toBeTruthy();
});
test('mobile fee when preset', () => {
// Arrange
const reference = '#mobile-fee-item';
const { wrapper } = getMountedComponent({
order: {
lineItems: {
supportingItems: [],
mobileFee: {}
}
}
});
// Act
const mobileFee = wrapper.find(reference);
// Assert
expect(wrapper.vm.mobileFeeCartItem).not.toBeNull();
expect(mobileFee.exists()).toBeTruthy();
});
test('bottom amount due', () => { test('bottom amount due', () => {
// Arrange // Arrange
const reference = '#bottom-amount-due'; const reference = '#bottom-amount-due';
@ -285,42 +290,26 @@ describe('cart-dropdown component', () => {
// Assert // Assert
expect(cartBasePrice.exists()).toBeFalsy(); expect(cartBasePrice.exists()).toBeFalsy();
}); });
test('recycle fee when not in supported items', () => { test('recycle cart item label when isRecycle false for all cart items', () => {
// Arrange // Arrange
const reference = '#recycle-fee-item'; const reference = '#recycle-fee-label';
const { wrapper } = getMountedComponent({ const isExpanded = true;
const initialPropsData = { isExpanded };
const storeData = {
order: { order: {
lineItems: { lineItems: {
supportingItems: [] supportingItems: []
} }
} }
}); };
const { wrapper } = getMountedComponent(storeData, {}, initialPropsData);
// Act // Act
const recycleFee = wrapper.find(reference); const recycleFeeLabel = wrapper.find(reference);
// Assert // Assert
expect(wrapper.vm.recycleFeeCartItem).toBeNull(); expect(wrapper.vm.recycleFeeCartItem).toBeNull();
expect(recycleFee.exists()).toBeFalsy(); expect(recycleFeeLabel.exists()).toBeFalsy();
});
test('mobile fee when not in supported items', () => {
// Arrange
const reference = '#mobile-fee-item';
const { wrapper } = getMountedComponent({
order: {
lineItems: {
supportingItems: [],
mobileFee: null
}
}
});
// Act
const mobileFee = wrapper.find(reference);
// Assert
expect(wrapper.vm.mobileFeeCartItem).toBeNull();
expect(mobileFee.exists()).toBeFalsy();
}); });
}); });
describe('computed', () => { describe('computed', () => {
@ -452,16 +441,129 @@ describe('cart-dropdown component', () => {
}); });
}); });
describe('subTotal', () => { describe('subTotal', () => {
// TODO when method implemented const supportingItemPartNumber = 'supporter';
const glassPartNumber = 'glass part';
const otherPartNumber = 'other';
const vapPartNumber = 'vap';
const mobileFeePartNumber = 'mobile';
const supportingItems = [{ partNumber: supportingItemPartNumber }];
const glassParts = [{ partNumber: glassPartNumber }];
const otherParts = [{ partNumber: otherPartNumber }];
const vaps = [{ partNumber: vapPartNumber }];
const mobileFee = { partNumber: mobileFeePartNumber };
const includesPartNumber = (lineItems, partNumber) => lineItems.some((item) => item?.partNumber === partNumber);
const deductiblePrice = 100;
const supportingAndGlassAndOtherPrice = 30;
const feesAndVapsPrice = 50;
const allLineItemsPrice = 70;
getPriceOfLineItems.mockImplementation((lineItems) => {
const allPartNumbers = [
supportingItemPartNumber,
glassPartNumber,
otherPartNumber,
mobileFeePartNumber,
vapPartNumber
];
if (allPartNumbers.every((partNumber) => includesPartNumber(lineItems, partNumber))) {
return allLineItemsPrice;
}
const supportingAndGlassAndOtherPartNumbers = [
supportingItemPartNumber,
glassPartNumber,
otherPartNumber
];
if (supportingAndGlassAndOtherPartNumbers.every((partNumber) => includesPartNumber(lineItems, partNumber))) {
return supportingAndGlassAndOtherPrice;
}
if (includesPartNumber(lineItems, mobileFeePartNumber) && includesPartNumber(lineItems, vapPartNumber)) {
return feesAndVapsPrice;
}
return 1;
});
const lineItems = {
supportingItems,
glassParts,
otherParts,
vaps,
mobileFee
};
test('when not no comp and not itac, includes deductible price plus fee and vap price', () => {
// Arrange
const storeData = {
order: {
lineItems,
policy: {
noCoverage: false,
isITAC: false
},
currentDeductible: deductiblePrice
}
};
const { wrapper } = getMountedComponent(storeData);
const expected = deductiblePrice + feesAndVapsPrice;
// Act
const result = wrapper.vm.subTotal;
// Assert
expect(result).toBe(expected);
});
test('when no comp, returns all line items price', () => {
// Arrange
const storeData = {
order: {
lineItems,
policy: {
noCoverage: true,
isITAC: false
},
currentDeductible: deductiblePrice
}
};
const { wrapper } = getMountedComponent(storeData);
const expected = allLineItemsPrice;
// Act
const result = wrapper.vm.subTotal;
// Assert
expect(result).toBe(expected);
});
test('when ITAC, returns all line items price', () => {
// Arrange
const storeData = {
order: {
lineItems,
policy: {
noCoverage: false,
isITAC: true
},
currentDeductible: deductiblePrice
}
};
const { wrapper } = getMountedComponent(storeData);
const expected = allLineItemsPrice;
// Act
const result = wrapper.vm.subTotal;
// Assert
expect(result).toBe(expected);
});
}); });
describe('salesTax', () => { describe('salesTax', () => {
test('salesTax is treated as 0 when line items are null', () => { test('salesTax is treated as 0 when line items are null', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = {
storeData.order.lineItems.glassParts = null; order: {
storeData.order.lineItems.otherParts = null; lineItems: {
storeData.order.lineItems.supportingItems = null; glassParts: null,
storeData.order.lineItems.vaps = null; otherParts: null,
supportingItems: null,
vaps: null
}
}
};
const { wrapper } = getMountedComponent(storeData); const { wrapper } = getMountedComponent(storeData);
@ -474,20 +576,24 @@ describe('cart-dropdown component', () => {
test("salesTax is treated as 0 when null or undefined is set as the line item's sales tax.", () => { test("salesTax is treated as 0 when null or undefined is set as the line item's sales tax.", () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = {
storeData.order.lineItems.glassParts = [ order: {
{ partType: 'mock', salesTax: null }, lineItems: {
{ partType: 'mock', salesTax: undefined } glassParts: [
]; { partType: 'mock', salesTax: null },
storeData.order.lineItems.supportingItems = [ { partType: 'mock', salesTax: undefined }
{ partType: 'mock', salesTax: null }, ],
{ partType: 'mock', salesTax: undefined } supportingItems: [
]; { partType: 'mock', salesTax: null },
storeData.order.lineItems.vaps = [ { partType: 'mock', salesTax: undefined }
{ partType: 'mock', salesTax: null }, ],
{ partType: 'mock', salesTax: undefined } vaps: [
]; { partType: 'mock', salesTax: null },
{ partType: 'mock', salesTax: undefined }
]
}
}
};
const { wrapper } = getMountedComponent(storeData); const { wrapper } = getMountedComponent(storeData);
// Act // Act
@ -496,19 +602,29 @@ describe('cart-dropdown component', () => {
// Assert // Assert
expect(result).toBe(0); expect(result).toBe(0);
}); });
test('Returns 0 as sales tax when coverage is unverified and order does not contain vaps.', () => { test('Returns 0 as sales tax when coverage is unverified and order does not contain vaps.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = {
storeData.order.lineItems.glassParts = [ order: {
{ partType: 'mock', salesTax: 10 } lineItems: {
]; glassParts: [{ partType: 'mock', salesTax: 10 }],
storeData.order.lineItems.supportingItems = [ supportingItems: [
{ partNumber: partNumberStrings.RECYCLE_FEE, partType: 'mock', salesTax: 10, sellingPrice: 39.99 } {
]; partNumber: partNumberStrings.RECYCLE_FEE,
storeData.order.lineItems.vaps = []; partType: 'mock',
storeData.order.payment.insuranceCoverage.isVerified = false; salesTax: 10,
sellingPrice: 39.99
}
],
vaps: []
},
payment: {
insuranceCoverage: {
isVerified: false
}
}
}
};
const { wrapper } = getMountedComponent(storeData); const { wrapper } = getMountedComponent(storeData);
// Act // Act
@ -520,7 +636,7 @@ describe('cart-dropdown component', () => {
test('Returns sum of vaps sales tax when coverage is unverified and order has vaps.', () => { test('Returns sum of vaps sales tax when coverage is unverified and order has vaps.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = useMainStore().$state;
storeData.order.lineItems.glassParts = [ storeData.order.lineItems.glassParts = [
{ partType: 'mock', salesTax: 10 } { partType: 'mock', salesTax: 10 }
]; ];
@ -541,7 +657,7 @@ describe('cart-dropdown component', () => {
test('Returns Recycle Fee tax when coverage is Verified-Deductible, replace service, and no vaps.', () => { test('Returns Recycle Fee tax when coverage is Verified-Deductible, replace service, and no vaps.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = useMainStore().$state;
storeData.order.currentDeductible = 250; storeData.order.currentDeductible = 250;
storeData.order.lineItems.glassParts = [ storeData.order.lineItems.glassParts = [
{ partType: 'mock', salesTax: 10, sellingPrice: 150 } { partType: 'mock', salesTax: 10, sellingPrice: 150 }
@ -563,7 +679,7 @@ describe('cart-dropdown component', () => {
test('Returns sum of vaps + recycle fee sales tax when Verified-Deductible, replace service, and has vaps.', () => { test('Returns sum of vaps + recycle fee sales tax when Verified-Deductible, replace service, and has vaps.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = useMainStore().$state;
storeData.order.currentDeductible = 250; storeData.order.currentDeductible = 250;
storeData.order.lineItems.glassParts = [ storeData.order.lineItems.glassParts = [
{ partType: 'mock', salesTax: 10, sellingPrice: 100 } { partType: 'mock', salesTax: 10, sellingPrice: 100 }
@ -592,7 +708,7 @@ describe('cart-dropdown component', () => {
test('Returns sum of sales tax when Verified-ITAC.', () => { test('Returns sum of sales tax when Verified-ITAC.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = useMainStore().$state;
storeData.order.currentDeductible = 0; storeData.order.currentDeductible = 0;
storeData.order.lineItems.glassParts = [ storeData.order.lineItems.glassParts = [
{ partType: 'mock', salesTax: 10, sellingPrice: 100 } { partType: 'mock', salesTax: 10, sellingPrice: 100 }
@ -620,7 +736,7 @@ describe('cart-dropdown component', () => {
test('Returns sum of sales tax when Verified-NoComp.', () => { test('Returns sum of sales tax when Verified-NoComp.', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = useMainStore().$state;
storeData.order.currentDeductible = 0; storeData.order.currentDeductible = 0;
storeData.order.lineItems.glassParts = [ storeData.order.lineItems.glassParts = [
{ partType: 'mock', salesTax: 10, sellingPrice: 100 } { partType: 'mock', salesTax: 10, sellingPrice: 100 }
@ -647,18 +763,10 @@ describe('cart-dropdown component', () => {
}); });
}); });
describe('availableLineItems', () => { describe('availableLineItems', () => {
test('returns expected when glassParts null', async () => { test('returns expected when all null', () => {
// Arrange // Arrange
const storeData = { const propsData = { availableVaps: null };
order: { const { wrapper } = getMountedComponent({}, {}, propsData);
lineItems: {
glassParts: null,
supportingItems: []
}
}
};
const propsData = { availableVaps: [] };
const { wrapper } = getMountedComponent(storeData, {}, propsData);
// Act // Act
const result = wrapper.vm.availableLineItems; const result = wrapper.vm.availableLineItems;
@ -666,58 +774,106 @@ describe('cart-dropdown component', () => {
// Assert // Assert
expect(result).toStrictEqual([]); expect(result).toStrictEqual([]);
}); });
test('returns expected when supportingItems null', async () => { test('returns expected when glassParts not null', async () => {
// Arrange // Arrange
const glassParts = [{ partNumber: 'glass' }];
const storeData = { const storeData = {
order: { order: {
lineItems: { lineItems: { glassParts }
glassParts: [],
supportingItems: null
}
} }
}; };
const propsData = { availableVaps: [] }; const propsData = { availableVaps: null };
const { wrapper } = getMountedComponent(storeData, {}, propsData); const { wrapper } = getMountedComponent(storeData, {}, propsData);
const expected = glassParts;
// Act // Act
const result = wrapper.vm.availableLineItems; const result = wrapper.vm.availableLineItems;
// Assert // Assert
expect(result).toStrictEqual([]); expect(result).toStrictEqual(expected);
});
test('returns expected when supportingItems not null', async () => {
// Arrange
const supportingItems = [{ partNumber: 'support' }];
const storeData = {
order: {
lineItems: { supportingItems }
}
};
const propsData = { availableVaps: null };
const { wrapper } = getMountedComponent(storeData, {}, propsData);
const expected = supportingItems;
// Act
const result = wrapper.vm.availableLineItems;
// Assert
expect(result).toStrictEqual(expected);
});
test('returns expected when otherParts not null', () => {
// Arrange
const otherParts = [{ partNumber: 'other' }];
const storeData = {
order: {
lineItems: { otherParts }
}
};
const propsData = { availableVaps: null };
const { wrapper } = getMountedComponent(storeData, {}, propsData);
const expected = otherParts;
// Act
const result = wrapper.vm.availableLineItems;
// Assert
expect(result).toStrictEqual(expected);
});
test('returns expected when mobileFee not null', () => {
// Arrange
const mobileFee = { partNumber: 'mobile' };
const storeData = {
order: {
lineItems: { mobileFee }
}
};
const propsData = { availableVaps: null };
const { wrapper } = getMountedComponent(storeData, {}, propsData);
const expected = [mobileFee];
// Act
const result = wrapper.vm.availableLineItems;
// Assert
expect(result).toStrictEqual(expected);
}); });
test('returns expected when availableVaps null', async () => { test('returns expected when availableVaps null', async () => {
// Arrange // Arrange
const storeData = { const availableVaps = [{ partNumber: 'vaps1' }];
order: { const propsData = { availableVaps };
lineItems: { const { wrapper } = getMountedComponent({}, {}, propsData);
glassParts: [], const expected = availableVaps;
supportingItems: []
}
}
};
const propsData = {
availableVaps: undefined
};
const { wrapper } = getMountedComponent(storeData, {}, propsData);
// Act // Act
const result = wrapper.vm.availableLineItems; const result = wrapper.vm.availableLineItems;
// Assert // Assert
expect(result).toStrictEqual([]); expect(result).toStrictEqual(expected);
}); });
test('returns expected when glassParts, supportingItems, and availableVaps have content', async () => { test('returns expected when glassParts, supportingItems, otherParts, mobileFee, and availableVaps have content', async () => {
// Arrange // Arrange
const part1 = { partType: 'apple' }; const part1 = { partType: 'apple' };
const part2 = { partType: 'banana' }; const part2 = { partType: 'banana' };
const part3 = { partType: 'orange' }; const part3 = { partType: 'orange' };
const part4 = { partType: 'grape' }; const part4 = { partType: 'grape' };
const part5 = { partType: 'raspberry' }; const part5 = { partType: 'raspberry' };
const mobileFee = { partType: 'mobile' };
const storeData = { const storeData = {
order: { order: {
lineItems: { lineItems: {
glassParts: [part1], glassParts: [part1],
supportingItems: [part2, part3] supportingItems: [part2, part3],
otherParts: [],
mobileFee
} }
} }
}; };
@ -725,13 +881,24 @@ describe('cart-dropdown component', () => {
availableVaps: [part4, part5] availableVaps: [part4, part5]
}; };
const { wrapper } = getMountedComponent(storeData, {}, propsData); const { wrapper } = getMountedComponent(storeData, {}, propsData);
const expected = [part1, part2, part3, part4, part5]; const sortByPartType = (a, b) => {
const typeA = a.partType.toUpperCase();
const typeB = b.partType.toUpperCase();
if (typeA < typeB) {
return -1;
}
if (typeA > typeB) {
return 1;
}
return 0;
};
const expected = [part1, part2, part3, part4, part5, mobileFee];
// Act // Act
const result = wrapper.vm.availableLineItems; const result = wrapper.vm.availableLineItems;
// Assert // Assert
expect(result).toStrictEqual(expected); expect(result.sort(sortByPartType)).toStrictEqual(expected.sort(sortByPartType));
}); });
}); });
describe('servicePackageCartItems', () => { describe('servicePackageCartItems', () => {
@ -959,6 +1126,267 @@ describe('cart-dropdown component', () => {
})); }));
}); });
}); });
describe('nonServicePackageCartItems', () => {
test('when recycleFee, includes recycle fee', () => {
// Arrange
const storeData = {
order: {
lineItems: {
supportingItems: [
{
partNumber: partNumberStrings.RECYCLE_FEE
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.REPLACE_FEE
}));
});
test('when mobileFee, includes mobile fee', () => {
// Arrange
const storeData = {
order: {
lineItems: {
mobileFee: {
partType: partTypeStrings.MOBILE_FEE
}
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.MOBILE_FEE
}));
});
test('front wiper not included when front wiper in service package', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER]);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.FRONT_WIPER
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).not.toContainEqual(expect.objectContaining({
partType: partTypeStrings.FRONT_WIPER
}));
});
test('rear wiper not included when rear wiper in service package', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => [partTypeStrings.REAR_WIPER]);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.REAR_WIPER
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).not.toContainEqual(expect.objectContaining({
partType: partTypeStrings.REAR_WIPER
}));
});
test('rain defense not included when rain defense in service package', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => [partTypeStrings.RAIN_DEFENSE]);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.RAIN_DEFENSE
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).not.toContainEqual(expect.objectContaining({
partType: partTypeStrings.RAIN_DEFENSE
}));
});
test('front wiper included when not in service package and in vaps', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => []);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.FRONT_WIPER
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.FRONT_WIPER
}));
});
test('rear wiper included when not in service package and in vaps', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => []);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.REAR_WIPER
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.REAR_WIPER
}));
});
test('rain defense included when not in service package and in vaps', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => []);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.RAIN_DEFENSE
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.RAIN_DEFENSE
}));
});
test('item in vaps outside front wiper, rear wiper, and rain defense never included', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => []);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.RECALIBRATION
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result).not.toContainEqual(expect.objectContaining({
partType: partTypeStrings.RECALIBRATION
}));
});
test('returns expected when multiple variables apply', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER]);
const storeData = {
order: {
lineItems: {
supportingItems: [
{
partNumber: partNumberStrings.RECYCLE_FEE
}
],
mobileFee: {
partType: partTypeStrings.MOBILE_FEE
},
vaps: [
{ partType: partTypeStrings.RECALIBRATION },
{ partType: partTypeStrings.FRONT_WIPER },
{ partType: partTypeStrings.REAR_WIPER }
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.nonServicePackageCartItems;
// Assert
expect(result.length).toBe(3);
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.REPLACE_FEE
}));
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.MOBILE_FEE
}));
expect(result).toContainEqual(expect.objectContaining({
partType: partTypeStrings.REAR_WIPER
}));
});
});
describe('servicePackageLabelWidget', () => { describe('servicePackageLabelWidget', () => {
test.each([ test.each([
[null], [null],
@ -1181,15 +1609,105 @@ describe('cart-dropdown component', () => {
expect(result.name).toBe(expectedName); expect(result.name).toBe(expectedName);
}); });
}); });
describe('packagePrice', () => {
test('returns 0 when servicePackageCartItems is empty', () => {
// Arrange
getPriceOfLineItems.mockImplementation(() => 123);
getPackageContents.mockImplementationOnce(() => []);
const storeData = {
order: {
lineItems: {
vaps: [
{
partType: partTypeStrings.REAR_WIPER
}
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.packagePrice;
// Assert
expect(result).toBe(0);
});
test('returns expected when servicePackageCartItems not empty', () => {
// Arrange
const rearPrice = 101;
const frontPrice = 9;
getPriceOfLineItems.mockImplementation((lineItems) => {
if (lineItems.some((item) => item?.partType === partTypeStrings.FRONT_WIPER)) {
return frontPrice;
}
if (lineItems.some((item) => item?.partType === partTypeStrings.REAR_WIPER)) {
return rearPrice;
}
return 1;
});
getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER, partTypeStrings.REAR_WIPER]);
const storeData = {
order: {
lineItems: {
vaps: [
{ partType: partTypeStrings.FRONT_WIPER },
{ partType: partTypeStrings.REAR_WIPER }
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
const expectedPrice = 110;
// Act
const result = wrapper.vm.packagePrice;
// Assert
expect(result).toBe(expectedPrice);
});
test('returns expected when servicePackageCartItems has one item', () => {
// Arrange
const frontPrice = 9;
getPriceOfLineItems.mockImplementation((lineItems) => {
if (lineItems.some((item) => item?.partType === partTypeStrings.FRONT_WIPER)) {
return frontPrice;
}
return 1;
});
getPackageContents.mockImplementationOnce(() => [partTypeStrings.FRONT_WIPER, partTypeStrings.REAR_WIPER]);
const storeData = {
order: {
lineItems: {
vaps: [
{ partType: partTypeStrings.FRONT_WIPER }
]
}
}
};
const { wrapper } = getMountedComponent(storeData);
// Act
const result = wrapper.vm.packagePrice;
// Assert
expect(result).toBe(frontPrice);
});
});
}); });
describe('method', () => { describe('method', () => {
describe('getDisplayed', () => { describe('getDisplayed', () => {
test('returns "Verifying coverage" when not no comp, not itac, and deductible null', () => { test('returns "Verifying coverage" when not no comp, not itac, and deductible null', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = {
storeData.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.VERIFIED; order: {
storeData.order.policy.isITAC = false; policy: {
storeData.order.currentDeductible = null; noCoverage: false,
isITAC: false
},
currentDeductible: null
}
};
const { wrapper } = getMountedComponent(storeData); const { wrapper } = getMountedComponent(storeData);
const amount = 123; const amount = 123;
@ -1202,10 +1720,15 @@ describe('cart-dropdown component', () => {
}); });
test('returns "Verifying coverage" when not no comp, not itac, and coverage status PENDING', () => { test('returns "Verifying coverage" when not no comp, not itac, and coverage status PENDING', () => {
// Arrange // Arrange
const storeData = getDefaultState(); const storeData = {
storeData.order.payment.insuranceCoverage.coverageStatus = coverageStatuses.PENDING; order: {
storeData.order.policy.isITAC = false; policy: {
storeData.order.currentDeductible = 321; noCoverage: false,
isITAC: false
},
currentDeductible: 321
}
};
const { wrapper } = getMountedComponent(storeData); const { wrapper } = getMountedComponent(storeData);
const amount = 123; const amount = 123;
@ -1521,8 +2044,5 @@ describe('cart-dropdown component', () => {
expect(result.subTotal).toBe(expectedSubtotal); expect(result.subTotal).toBe(expectedSubtotal);
}); });
}); });
describe('removeItem', () => {
// TODO when written
});
}); });
}); });

View file

@ -1,5 +1,5 @@
<template> <template>
<div :class="[isExpanded ? 'pb-5' : 'pb-4']"> <div>
<div <div
id="cart-dropdown-head" id="cart-dropdown-head"
class="row cart-toggle flex align-items-center pt-4" class="row cart-toggle flex align-items-center pt-4"
@ -41,7 +41,7 @@
<!-- Packaged Cart Items --> <!-- Packaged Cart Items -->
<div <div
id="cart-service-package" id="cart-service-package"
class="color-darker-gray px-5"> class="px-5">
<div <div
id="service-package-name" id="service-package-name"
class="py-1 d-flex justify-content-between align-items-center"> class="py-1 d-flex justify-content-between align-items-center">
@ -55,8 +55,7 @@
class="ps-4"> class="ps-4">
<div <div
v-for="(item, i) in servicePackageCartItems" v-for="(item, i) in servicePackageCartItems"
:key="i" :key="i">
class="packaged-cart-item">
<div class="py-1 d-flex justify-content-between align-items-center"> <div class="py-1 d-flex justify-content-between align-items-center">
<span>{{ item?.name ?? '' }}</span> <span>{{ item?.name ?? '' }}</span>
<textLink <textLink
@ -64,7 +63,7 @@
linkType="text" linkType="text"
text="Remove" text="Remove"
href="javascript:void(0)" href="javascript:void(0)"
@clickEvent="removeItem"> @clickEvent="removeVap(item.partType)">
<template #after-text> <template #after-text>
<span class="sr-only">{{ item?.name ?? '' }}</span> <span class="sr-only">{{ item?.name ?? '' }}</span>
</template> </template>
@ -74,42 +73,41 @@
</div> </div>
</div> </div>
<!-- Nonpackaged Cart Items --> <!-- NonPackaged Cart Items -->
<!-- This will be a loop when this is implemented --> <div id="non-packaged-cart-items">
<div class="non-packaged-cart-item">
<div <div
v-if="mobileFeeCartItem" v-for="(item, i) in nonServicePackageCartItems"
id="mobile-fee" :key="i"
class="cart-item"> class="px-5 py-1 non-packaged-cart-item">
<div <div class="d-flex justify-content-between align-items-center">
id="mobile-fee-item" <span
class="d-flex justify-content-between align-items-center"> v-if="item.cartItemType === cartItemType.RECYCLE_FEE"
<span id="mobile-fee-label">{{ mobileFeeCartItem?.name ?? '' }}</span> id="recycle-fee-label">
<span id="mobile-fee-value">{{ getDisplayed(mobileFeeCartItem.subTotal) }}</span> <textLink
</div> linkType="text"
</div> :text="item?.name ?? ''"
href="javascript:void(0)"
<div @clickEvent="openModal(recyclingModalCmsWidgetName)" />
v-if="recycleFeeCartItem"
id="recycle-fee"
class="cart-item cart-gray">
<div
id="recycle-fee-item"
class="d-flex justify-content-between align-items-center">
<span id="recycle-fee-label">
<textLink
linkType="text"
:text="recycleFeeCartItem?.name ?? ''"
href="javascript:void(0)"
@clickEvent="openModal(recyclingModalCmsWidgetName)" />
</span> </span>
<span id="recycle-fee-value">{{ getDisplayed(recycleFeeCartItem.subTotal) }}</span> <span v-else>{{ item?.name ?? '' }}</span>
<span>{{ formatAmountInDollars(item?.subTotal ?? 0) }}</span>
</div> </div>
<textLink
v-if="item.cartItemType === cartItemType.VAP
&& (!readOnly || !showAsPaid)"
linkType="text"
text="Remove"
href="javascript:void(0)"
@clickEvent="removeVap(item.partType)">
<template #after-text>
<span class="sr-only">{{ item?.name ?? '' }}</span>
</template>
</textLink>
</div> </div>
</div> </div>
<div <div
id="cart-footer" id="cart-footer"
class="cart-footer"> class="cart-footer pb-5">
<div <div
id="cart-subtotal-and-tax" id="cart-subtotal-and-tax"
class="subtotal-and-tax"> class="subtotal-and-tax">
@ -154,6 +152,7 @@ import { getHighestFullySatisfiedTier, getPackageContents } from '@/helpers/serv
// Constants // Constants
import partTypeStrings from '@/constants/part-type-strings.js'; import partTypeStrings from '@/constants/part-type-strings.js';
import cartItemType from '@/constants/cart-item-type.js';
import partNumberStrings from '@/constants/part-number-strings.js'; import partNumberStrings from '@/constants/part-number-strings.js';
import widgetFields from '@/constants/cms-widget-fields.js'; import widgetFields from '@/constants/cms-widget-fields.js';
@ -185,7 +184,8 @@ export default {
mobileFee: 'MobileServiceWidget', mobileFee: 'MobileServiceWidget',
servicePackage: 'ServicePackageTitle', servicePackage: 'ServicePackageTitle',
vapsItemDescriptions: 'VapsItemDescriptions' vapsItemDescriptions: 'VapsItemDescriptions'
} },
cartItemType
}; };
}, },
computed: { computed: {
@ -194,27 +194,51 @@ export default {
return useMainStore().order.currentDeductible; return useMainStore().order.currentDeductible;
}, },
showDeductibleCartItem() { showDeductibleCartItem() {
return !useMainStore().isNoComp && !useMainStore().policy.isITAC; return !useMainStore().isNoComp && !useMainStore().isITAC;
},
recycleFeeLineItem() {
return useMainStore().lineItems.supportingItems
?.find((lineItem) => lineItem.partNumber === partNumberStrings.RECYCLE_FEE);
}, },
baseServiceLineItems() { baseServiceLineItems() {
return [ const { supportingItems, glassParts, otherParts } = useMainStore().lineItems;
...(useMainStore().lineItems.supportingItems ?? []), const parts = [
...(useMainStore().lineItems.glassParts ?? []), ...(supportingItems ?? []),
...(useMainStore().lineItems.otherParts ?? []) ...(glassParts ?? []),
...(otherParts ?? [])
]; ];
return parts.filter((part) => part !== this.recycleFeeLineItem);
}, },
baseServicePrice() { baseServicePrice() {
return getPriceOfLineItems(this.baseServiceLineItems); return getPriceOfLineItems(this.baseServiceLineItems) ?? 0;
}, },
isUnverified() { isUnverified() {
return !useMainStore().isNoComp && !useMainStore().policy.isITAC return !useMainStore().isNoComp && !useMainStore().isITAC
&& (this.deductible == null || !useMainStore().isVerifiedCoverageStatus); && (this.deductible == null || !useMainStore().isVerifiedCoverageStatus);
}, },
subTotal() { subTotal() {
const basePrice = !useMainStore().isNoComp && !useMainStore().policy.isITAC const { supportingItems, glassParts, otherParts, vaps, mobileFee } = useMainStore().lineItems;
? this.deductible const allLineItems = [
: this.baseServicePrice; ...(supportingItems ?? []),
return basePrice + this.packagePrice; ...(glassParts ?? []),
...(otherParts ?? []),
...(vaps ?? []),
mobileFee
];
return !useMainStore().isNoComp && !useMainStore().isITAC
? this.deductible + getPriceOfLineItems([...this.feeLineItems, ...(vaps ?? [])])
: getPriceOfLineItems(allLineItems);
},
feeLineItems() {
const { mobileFee } = useMainStore().lineItems;
const result = [];
if (mobileFee) {
result.push(mobileFee);
}
if (this.recycleFeeLineItem) {
result.push(this.recycleFeeLineItem);
}
return result;
}, },
salesTax() { salesTax() {
function sumTax(lineItems) { function sumTax(lineItems) {
@ -228,10 +252,7 @@ export default {
result += sumTax(this.baseServiceLineItems); result += sumTax(this.baseServiceLineItems);
} else { } else {
// deductible-case need to show tax for Recycle Fee // deductible-case need to show tax for Recycle Fee
const recycleFeeLineItem = useMainStore().lineItems.supportingItems result += this.recycleFeeLineItem?.salesTax ?? 0;
?.find((lineItem) => lineItem.partNumber === partNumberStrings.RECYCLE_FEE);
result += recycleFeeLineItem != null ? recycleFeeLineItem.salesTax : 0;
} }
} }
@ -245,40 +266,76 @@ export default {
: this.subTotal + this.salesTax; : this.subTotal + this.salesTax;
}, },
availableLineItems() { availableLineItems() {
const { glassParts, supportingItems } = useMainStore().lineItems; const { supportingItems, glassParts, otherParts, mobileFee } = useMainStore().lineItems;
return [ const result = [
...(glassParts ?? []),
...(supportingItems ?? []), ...(supportingItems ?? []),
...(glassParts ?? []),
...(otherParts ?? []),
...(this.availableVaps ?? []) ...(this.availableVaps ?? [])
]; ];
if (mobileFee) {
result.push(mobileFee);
}
return result;
}, },
servicePackageTier() { servicePackageTier() {
const { glassToReplace, isRepair } = useMainStore().damage;
const { vaps } = useMainStore().lineItems;
return getHighestFullySatisfiedTier( return getHighestFullySatisfiedTier(
useMainStore().damage.glassToReplace ?? [], glassToReplace ?? [],
this.availableLineItems, this.availableLineItems,
useMainStore().damage.isRepair, isRepair,
useMainStore().lineItems.vaps ?? [] vaps ?? []
); );
}, },
servicePackageCartItems() { partTypesInServicePackage() {
const packageContentTypes = getPackageContents( const { glassToReplace, isRepair } = useMainStore().damage;
useMainStore().damage.glassToReplace ?? [], return getPackageContents(
glassToReplace ?? [],
this.availableLineItems, this.availableLineItems,
useMainStore().damage.isRepair, isRepair,
this.servicePackageTier this.servicePackageTier
) ?? []; ) ?? [];
},
servicePackageCartItems() {
const items = []; const items = [];
if (packageContentTypes.includes(partTypeStrings.FRONT_WIPER) ?? this.frontWipersCartItem) { if (this.partTypesInServicePackage.includes(partTypeStrings.FRONT_WIPER) ?? this.frontWipersCartItem) {
items.push(this.frontWipersCartItem); items.push(this.frontWipersCartItem);
} }
if (packageContentTypes.includes(partTypeStrings.REAR_WIPER) ?? this.rearWipersCartItem) { if (this.partTypesInServicePackage.includes(partTypeStrings.REAR_WIPER) ?? this.rearWipersCartItem) {
items.push(this.rearWipersCartItem); items.push(this.rearWipersCartItem);
} }
if (packageContentTypes.includes(partTypeStrings.RAIN_DEFENSE) ?? this.rainDefenseCartItem) { if (this.partTypesInServicePackage.includes(partTypeStrings.RAIN_DEFENSE) ?? this.rainDefenseCartItem) {
items.push(this.rainDefenseCartItem); items.push(this.rainDefenseCartItem);
} }
return items; return items;
}, },
nonServicePackageCartItems() {
const vapPartTypesInOrder = Array.from(new Set(useMainStore().lineItems.vaps?.map((vap) => vap.partType) ?? []));
const vapPartTypesInOrderButNotPackage = vapPartTypesInOrder
.filter((partType) => !this.partTypesInServicePackage.includes(partType))
?? [];
const vapsCartItemsNotInPackage = vapPartTypesInOrderButNotPackage.map((partType) => {
switch (partType) {
case partTypeStrings.FRONT_WIPER:
return this.frontWipersCartItem;
case partTypeStrings.REAR_WIPER:
return this.rearWipersCartItem;
case partTypeStrings.RAIN_DEFENSE:
return this.rainDefenseCartItem;
default:
return null;
}
});
const items = vapsCartItemsNotInPackage.filter((item) => item != null);
if (this.recycleFeeCartItem) {
items.push(this.recycleFeeCartItem);
}
if (this.mobileFeeCartItem) {
items.push(this.mobileFeeCartItem);
}
return items;
},
frontWipersCartItem() { frontWipersCartItem() {
return this.getCartItemForVapsPart(partTypeStrings.FRONT_WIPER); return this.getCartItemForVapsPart(partTypeStrings.FRONT_WIPER);
}, },
@ -289,7 +346,10 @@ export default {
return this.getCartItemForVapsPart(partTypeStrings.RAIN_DEFENSE); return this.getCartItemForVapsPart(partTypeStrings.RAIN_DEFENSE);
}, },
packagePrice() { packagePrice() {
return getPriceOfLineItems(useMainStore().lineItems.vaps ?? []); return this.servicePackageCartItems?.reduce(
(accumulator, cartItem) => accumulator + (cartItem?.subTotal ?? 0),
0
) ?? 0;
}, },
amountDueLabel() { amountDueLabel() {
return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT); return this.getCmsContent(this.widget.amountDue, widgetFields.TEXT_BLOCK_WIDGET.TEXT);
@ -322,12 +382,12 @@ export default {
return currentPackage?.SubWidgetName ?? ''; return currentPackage?.SubWidgetName ?? '';
}, },
recycleFeeCartItem() { recycleFeeCartItem() {
const recycleFeeLineItem = useMainStore().lineItems.supportingItems return this.recycleFeeLineItem
?.find((lineItem) => lineItem.partNumber === partNumberStrings.RECYCLE_FEE);
return recycleFeeLineItem
? this.getCartItem( ? this.getCartItem(
this.getCmsContent(this.widget.recycleFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT), this.getCmsContent(this.widget.recycleFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
[recycleFeeLineItem] [this.recycleFeeLineItem],
cartItemType.RECYCLE_FEE,
partTypeStrings.REPLACE_FEE
) )
: null; : null;
}, },
@ -336,7 +396,9 @@ export default {
return mobileFeeLineItem return mobileFeeLineItem
? this.getCartItem( ? this.getCartItem(
this.getCmsContent(this.widget.mobileFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT), this.getCmsContent(this.widget.mobileFee, widgetFields.TEXT_BLOCK_WIDGET.TEXT),
[mobileFeeLineItem] [mobileFeeLineItem],
cartItemType.MOBILE_FEE,
partTypeStrings.MOBILE_FEE
) )
: null; : null;
} }
@ -351,21 +413,23 @@ export default {
getDisplayed(amount) { getDisplayed(amount) {
return this.isUnverified return this.isUnverified
&& !useMainStore().isNoComp && !useMainStore().isNoComp
&& !useMainStore().policy.isITAC && !useMainStore().isITAC
? VERIFYING_COVERAGE ? VERIFYING_COVERAGE
: formatAmountInDollars(amount); : formatAmountInDollars(amount);
}, },
getCartItem(label, lineItems) { getCartItem(label, lineItems, cartItemTypeString, partType) {
let cartItem = null; let cartItem = null;
if (lineItems && lineItems.length > 0) { if (lineItems && lineItems.length > 0) {
cartItem = { cartItem = {
name: label, name: label,
cartItemType: cartItemTypeString,
partType,
subTotal: getPriceOfLineItems(lineItems), subTotal: getPriceOfLineItems(lineItems),
salesTax: lineItems.reduce( salesTax: lineItems?.reduce(
(accumulator, lineItem) => accumulator + lineItem.salesTax, (accumulator, lineItem) => accumulator + lineItem.salesTax,
0 0
) ) ?? 0
}; };
} }
@ -374,13 +438,14 @@ export default {
getCartItemForVapsPart(partType) { getCartItemForVapsPart(partType) {
const label = this.getCmsContentForVapsType(partType); const label = this.getCmsContentForVapsType(partType);
const lineItems = useMainStore().lineItems.vaps const lineItems = useMainStore().lineItems.vaps
?.filter((vapsLineItem) => vapsLineItem.partType === partType); ?.filter((vapsLineItem) => vapsLineItem.partType === partType) ?? [];
return this.getCartItem(label, lineItems); return this.getCartItem(label, lineItems, cartItemType.VAP, partType);
}, },
removeItem() { removeVap(partType) {
// TODO in later ticket const newVaps = useMainStore().lineItems.vaps?.filter((vap) => vap?.partType !== partType) ?? [];
useMainStore().updateVaps(newVaps);
}, },
getCmsContentForVapsType(vapsType) { getCmsContentForVapsType(vapsPartType) {
const vapsItemDescriptions = this.getCmsContent( const vapsItemDescriptions = this.getCmsContent(
this.widget.vapsItemDescriptions, this.widget.vapsItemDescriptions,
widgetFields.INPUT_QUESTION_WIDGET.ANSWERS widgetFields.INPUT_QUESTION_WIDGET.ANSWERS
@ -390,7 +455,7 @@ export default {
return ''; return '';
} }
const vapsTypeDescription = vapsItemDescriptions?.find((entry) => entry?.Name === vapsType); const vapsTypeDescription = vapsItemDescriptions?.find((entry) => entry?.Name === vapsPartType);
return vapsTypeDescription?.Text ?? ''; return vapsTypeDescription?.Text ?? '';
}, },
formatAmountInDollars formatAmountInDollars
@ -417,11 +482,6 @@ export default {
color: $darker-gray; color: $darker-gray;
} }
.cart-line-item {
padding: 0.25rem 1.5rem;
color: $darker-gray;
}
.cart-table { .cart-table {
max-height: 0; max-height: 0;
transition: all 350ms ease-in; transition: all 350ms ease-in;
@ -435,6 +495,10 @@ export default {
text-underline-offset: auto !important; text-underline-offset: auto !important;
} }
.non-packaged-cart-item:nth-child(odd){
background-color: $gray-100;
}
.cart-item { .cart-item {
padding: 0.25rem 1.5rem; padding: 0.25rem 1.5rem;
} }

View file

@ -160,14 +160,16 @@ describe('contactDetails.vue', () => {
const firstName = getRandomString(4, 15); const firstName = getRandomString(4, 15);
const lastName = getRandomString(4, 15); const lastName = getRandomString(4, 15);
const emailAddress = getRandomString(10, 20); const emailAddress = getRandomString(10, 20);
const phoneNumber = getRandomInt(1000000000, 9999999999); const servicePhone = getRandomInt(1000000000, 9999999999).toString();
const mainInitialState = { const mainInitialState = {
order: { order: {
customer: { customer: {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress
phoneNumber },
contactInfo: {
servicePhone
} }
} }
}; };
@ -185,7 +187,7 @@ describe('contactDetails.vue', () => {
expect(wrapper.vm.firstName).toBe(firstName); expect(wrapper.vm.firstName).toBe(firstName);
expect(wrapper.vm.lastName).toBe(lastName); expect(wrapper.vm.lastName).toBe(lastName);
expect(wrapper.vm.emailAddress).toBe(emailAddress); expect(wrapper.vm.emailAddress).toBe(emailAddress);
expect(wrapper.vm.phoneNumber).toBe(phoneNumber); expect(wrapper.vm.phoneNumber).toBe(servicePhone);
}); });
test('Mock store with contact info yields expected data', () => { test('Mock store with contact info yields expected data', () => {
// Arrange // Arrange
@ -199,7 +201,7 @@ describe('contactDetails.vue', () => {
firstName: getRandomString(4, 15), firstName: getRandomString(4, 15),
lastName: getRandomString(4, 15), lastName: getRandomString(4, 15),
emailAddress: getRandomString(10, 20), emailAddress: getRandomString(10, 20),
phoneNumber: getRandomInt(1000000000, 9999999999), servicePhone: getRandomInt(1000000000, 9999999999),
requestTextUpdates: getRandomBoolean(), requestTextUpdates: getRandomBoolean(),
notesForTechnician: getRandomString(50, 100) notesForTechnician: getRandomString(50, 100)
}; };
@ -224,7 +226,7 @@ describe('contactDetails.vue', () => {
expect(wrapper.vm.firstName).toBe(contactInfo.firstName); expect(wrapper.vm.firstName).toBe(contactInfo.firstName);
expect(wrapper.vm.lastName).toBe(contactInfo.lastName); expect(wrapper.vm.lastName).toBe(contactInfo.lastName);
expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress); expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress);
expect(wrapper.vm.phoneNumber).toBe(contactInfo.phoneNumber); expect(wrapper.vm.phoneNumber).toBe(contactInfo.servicePhone);
expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates); expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates);
expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician); expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician);
}); });
@ -315,7 +317,7 @@ describe('contactDetails.vue', () => {
const firstName = getRandomString(4, 15); const firstName = getRandomString(4, 15);
const lastName = getRandomString(4, 15); const lastName = getRandomString(4, 15);
const emailAddress = getRandomString(10, 20); const emailAddress = getRandomString(10, 20);
const phoneNumber = getRandomInt(1000000000, 9999999999); const phoneNumber = getRandomInt(1000000000, 9999999999).toString();
const requestTextUpdates = getRandomBoolean(); const requestTextUpdates = getRandomBoolean();
const notesForTechnician = getRandomString(1, 100); const notesForTechnician = getRandomString(1, 100);
wrapper.setData({ wrapper.setData({
@ -335,11 +337,60 @@ describe('contactDetails.vue', () => {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber,
requestTextUpdates, requestTextUpdates,
notesForTechnician notesForTechnician
}); });
}); });
test('Forward button click updates phone numbers request text updates', () => {
// Arrange
const mountOptions = getMountOptions({
router: {
navigate: jest.fn()
}
});
const wrapper = shallowMount(contactDetails, mountOptions);
const phoneNumber = getRandomInt(1000000000, 9999999999).toString();
const requestTextUpdates = true;
wrapper.setData({
phoneNumber,
requestTextUpdates
});
// Act
wrapper.vm.forwardButtonAction();
// Assert
expect(useMainStore().updatePhoneNumbers).toHaveBeenCalledWith({
service: phoneNumber,
alternative: phoneNumber
});
});
test('Forward button click updates phone numbers dot not request text updates', () => {
// Arrange
const mountOptions = getMountOptions({
router: {
navigate: jest.fn()
}
});
const wrapper = shallowMount(contactDetails, mountOptions);
const phoneNumber = getRandomInt(1000000000, 9999999999).toString();
const requestTextUpdates = false;
wrapper.setData({
phoneNumber,
requestTextUpdates
});
// Act
wrapper.vm.forwardButtonAction();
// Assert
expect(useMainStore().updatePhoneNumbers).toHaveBeenCalledWith({
home: phoneNumber,
service: phoneNumber
});
});
}); });
test('Mocked store with no contact info yields expected data', () => { test('Mocked store with no contact info yields expected data', () => {
@ -349,20 +400,19 @@ describe('contactDetails.vue', () => {
const firstName = getRandomString(4, 15); const firstName = getRandomString(4, 15);
const lastName = getRandomString(4, 15); const lastName = getRandomString(4, 15);
const emailAddress = getRandomString(10, 20); const emailAddress = getRandomString(10, 20);
const phoneNumber = getRandomInt(1000000000, 9999999999); const servicePhone = getRandomInt(1000000000, 9999999999);
const mainInitialState = { const mainInitialState = {
order: { order: {
customer: { customer: {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress
phoneNumber
}, },
contactInfo: { contactInfo: {
firstName: null, firstName: null,
lastName: null, lastName: null,
emailAddress: null, emailAddress: null,
phoneNumber: null, servicePhone,
requestTextUpdates: null, requestTextUpdates: null,
notesForTechnician: null notesForTechnician: null
} }
@ -382,7 +432,7 @@ describe('contactDetails.vue', () => {
expect(wrapper.vm.firstName).toBe(firstName); expect(wrapper.vm.firstName).toBe(firstName);
expect(wrapper.vm.lastName).toBe(lastName); expect(wrapper.vm.lastName).toBe(lastName);
expect(wrapper.vm.emailAddress).toBe(emailAddress); expect(wrapper.vm.emailAddress).toBe(emailAddress);
expect(wrapper.vm.phoneNumber).toBe(phoneNumber); expect(wrapper.vm.phoneNumber).toBe(servicePhone);
}); });
test('Mock store with contact info yields expected data', () => { test('Mock store with contact info yields expected data', () => {
@ -397,7 +447,7 @@ describe('contactDetails.vue', () => {
firstName: getRandomString(4, 15), firstName: getRandomString(4, 15),
lastName: getRandomString(4, 15), lastName: getRandomString(4, 15),
emailAddress: getRandomString(10, 20), emailAddress: getRandomString(10, 20),
phoneNumber: getRandomInt(1000000000, 9999999999), servicePhone: getRandomInt(1000000000, 9999999999),
requestTextUpdates: getRandomBoolean(), requestTextUpdates: getRandomBoolean(),
notesForTechnician: getRandomString(50, 100) notesForTechnician: getRandomString(50, 100)
}; };
@ -422,7 +472,7 @@ describe('contactDetails.vue', () => {
expect(wrapper.vm.firstName).toBe(contactInfo.firstName); expect(wrapper.vm.firstName).toBe(contactInfo.firstName);
expect(wrapper.vm.lastName).toBe(contactInfo.lastName); expect(wrapper.vm.lastName).toBe(contactInfo.lastName);
expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress); expect(wrapper.vm.emailAddress).toBe(contactInfo.emailAddress);
expect(wrapper.vm.phoneNumber).toBe(contactInfo.phoneNumber); expect(wrapper.vm.phoneNumber).toBe(contactInfo.servicePhone);
expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates); expect(wrapper.vm.requestTextUpdates).toBe(contactInfo.requestTextUpdates);
expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician); expect(wrapper.vm.notesForTechnician).toBe(contactInfo.notesForTechnician);
}); });

View file

@ -144,7 +144,7 @@ export default {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber, servicePhone,
requestTextUpdates, requestTextUpdates,
notesForTechnician notesForTechnician
} = useMainStore().contactInfo; } = useMainStore().contactInfo;
@ -152,7 +152,7 @@ export default {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber, phoneNumber: servicePhone,
requestTextUpdates, requestTextUpdates,
notesForTechnician, notesForTechnician,
widget: { widget: {

View file

@ -30,8 +30,25 @@ export default {
}, },
computed: { computed: {
}, },
mounted() { async mounted() {
this.validateClientTagOnEntry(); const queryStringParams = this.parseQueryParms();
const { isAuthorized, clientData } = await this.validateClientTagOnEntry(queryStringParams);
this.unauthorized = !isAuthorized;
if (isAuthorized) {
await this.populateISSConfigValues(clientData);
if (clientData.parameters?.length > 0) {
const finalParams = this.combineClientParameters(clientData.parameters, queryStringParams);
this.populateStoreItemsFromParams(finalParams);
}
this.mainStore.applicationUser.coverageAttempts = 0;
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`;
}
}, },
methods: methods:
{ {
@ -53,11 +70,11 @@ export default {
return queryStringParams; return queryStringParams;
}, },
async validateClientTagOnEntry() { async validateClientTagOnEntry(queryStringParams) {
const queryStringParams = this.parseQueryParms();
const clientTag = queryStringParams.clienttag; const clientTag = queryStringParams.clienttag;
const clientTagPresent = !!clientTag; const clientTagPresent = !!clientTag;
let authorized = false; let authorized = false;
let clientData = null;
if (clientTagPresent) { if (clientTagPresent) {
const resp = await validateISSClientTag(clientTag); const resp = await validateISSClientTag(clientTag);
@ -76,23 +93,12 @@ export default {
} }
if (authorized) { if (authorized) {
await this.populateISSConfigValues(resp.data); clientData = resp.data;
if (resp.data.parameters?.length > 0) {
const finalParams = this.combineClientParameters(resp.data.parameters, queryStringParams);
this.populateStoreItemsFromParams(finalParams);
}
} }
} }
} }
this.unauthorized = !authorized; return { isAuthorized: authorized, clientData };
if (authorized) {
this.mainStore.applicationUser.coverageAttempts = 0;
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`;
}
}, },
async populateISSConfigValues(data) { async populateISSConfigValues(data) {
this.mainStore.issConfig.clientName = data.accountName; this.mainStore.issConfig.clientName = data.accountName;
@ -100,6 +106,7 @@ export default {
this.mainStore.issConfig.parentAccountNumber = data.parentAccountNumber; this.mainStore.issConfig.parentAccountNumber = data.parentAccountNumber;
this.mainStore.issConfig.styleSheet = data.styleSheet; this.mainStore.issConfig.styleSheet = data.styleSheet;
this.mainStore.issConfig.isCoverageEnabled = data.coverageEnabled; this.mainStore.issConfig.isCoverageEnabled = data.coverageEnabled;
this.mainStore.issConfig.siteType = data.siteType;
try { try {
if (data.clientFlags) { if (data.clientFlags) {

View file

@ -76,7 +76,7 @@ const initialStore = {
contactInfo: { contactInfo: {
firstName: 'Test', firstName: 'Test',
lastName: 'Test', lastName: 'Test',
phoneNumber: '111-111-1111', servicePhone: '111-111-1111',
emailAddress: 'test@email.com' emailAddress: 'test@email.com'
} }
} }

View file

@ -318,7 +318,7 @@ export default {
const contactInfoReqs = !!( const contactInfoReqs = !!(
contactInfo.firstName contactInfo.firstName
&& contactInfo.lastName && contactInfo.lastName
&& contactInfo.phoneNumber && contactInfo.servicePhone
&& contactInfo.emailAddress && contactInfo.emailAddress
); );

View file

@ -247,14 +247,22 @@ export default {
); );
// Customer // Customer
const { firstName, lastName, phoneNumber, emailAddress } = useMainStore().order.customer; const { firstName, lastName, emailAddress } = useMainStore().order.customer;
const customerReqs = !!( const customerReqs = !!(
firstName firstName
&& lastName && lastName
&& phoneNumber
&& emailAddress && emailAddress
); );
// Contact Info
const { contactInfo } = useMainStore().order;
const contactInfoReqs = !!(
contactInfo.firstName
&& contactInfo.lastName
&& contactInfo.servicePhone
&& contactInfo.emailAddress
);
return ( return (
vehicleReqs vehicleReqs
&& damageReqs && damageReqs
@ -262,6 +270,7 @@ export default {
&& serviceLocationReqs && serviceLocationReqs
&& scheduleReqs && scheduleReqs
&& customerReqs && customerReqs
&& contactInfoReqs
); );
}, },
getPaymentMethodFromStore() { getPaymentMethodFromStore() {

View file

@ -183,7 +183,7 @@ describe('payment-page.vue', () => {
firstName: 'first', firstName: 'first',
lastName: 'last', lastName: 'last',
emailAddress: 'builddigitaltest@safelite.com', emailAddress: 'builddigitaltest@safelite.com',
phoneNumber: '555-555-5555' servicePhone: '555-555-5555'
}, },
damage: { damage: {
isRepair: false, isRepair: false,

View file

@ -500,7 +500,7 @@ export default {
zipCode: this.getZipCode(), zipCode: this.getZipCode(),
firstName: useMainStore().order.contactInfo.firstName, firstName: useMainStore().order.contactInfo.firstName,
lastName: useMainStore().order.contactInfo.lastName, lastName: useMainStore().order.contactInfo.lastName,
phoneNumber: useMainStore().order.contactInfo.phoneNumber, phoneNumber: useMainStore().order.contactInfo.servicePhone,
ctu: useMainStore().order.serviceLocation.zipCodeCtu, ctu: useMainStore().order.serviceLocation.zipCodeCtu,
referralCorrelationId: useMainStore().order.referralCorrelationId, referralCorrelationId: useMainStore().order.referralCorrelationId,
workOrderNumber: this.getWorkOrderNumber(), workOrderNumber: this.getWorkOrderNumber(),
@ -597,7 +597,7 @@ export default {
const contactInfoReqs = !!( const contactInfoReqs = !!(
contactInfo.firstName contactInfo.firstName
&& contactInfo.lastName && contactInfo.lastName
&& contactInfo.phoneNumber && contactInfo.servicePhone
&& contactInfo.emailAddress && contactInfo.emailAddress
); );

View file

@ -35,14 +35,14 @@ describe('contact-details-drawer', () => {
const firstName = 'Frederick'; const firstName = 'Frederick';
const lastName = 'Taylor'; const lastName = 'Taylor';
const emailAddress = 'fred.tay@gmail.com'; const emailAddress = 'fred.tay@gmail.com';
const phoneNumber = '606-009-2943'; const servicePhone = '606-009-2943';
const mainInitialState = { const mainInitialState = {
order: { order: {
contactInfo: { contactInfo: {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber servicePhone
} }
} }
}; };
@ -81,7 +81,7 @@ describe('contact-details-drawer', () => {
firstName: 'Frederick', firstName: 'Frederick',
lastName: 'Taylor', lastName: 'Taylor',
emailAddress: 'fred.tay@gmail.com', emailAddress: 'fred.tay@gmail.com',
phoneNumber: '606-009-2943' servicePhone: '606-009-2943'
} }
} }
}; };
@ -96,7 +96,9 @@ describe('contact-details-drawer', () => {
// Assert // Assert
expect(wrapper.emitted()['update-contact-details']).toBeTruthy(); expect(wrapper.emitted()['update-contact-details']).toBeTruthy();
expect(useMainStore().updateContactInfo).toBeCalledTimes(1); expect(useMainStore().updateContactInfo).toBeCalledTimes(1);
expect(useMainStore().updateContactInfo).toBeCalledWith({ firstName, lastName, emailAddress, phoneNumber }); expect(useMainStore().updateContactInfo).toBeCalledWith({ firstName, lastName, emailAddress });
expect(useMainStore().updatePhoneNumbers).toBeCalledTimes(1);
expect(useMainStore().updatePhoneNumbers).toBeCalledWith({ home: phoneNumber, service: phoneNumber });
} }
); );
}); });

View file

@ -67,13 +67,13 @@ export default {
const { firstName, const { firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber } = useMainStore().contactInfo; servicePhone } = useMainStore().contactInfo;
return { return {
isModalOpened: false, isModalOpened: false,
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber, phoneNumber: servicePhone,
widget: { widget: {
title: 'ContactDetailsDrawerHeaderWidget', title: 'ContactDetailsDrawerHeaderWidget',
firstNameQuestion: 'FirstNameQuestionWidget', firstNameQuestion: 'FirstNameQuestionWidget',
@ -119,21 +119,24 @@ export default {
const contactInfo = { const contactInfo = {
firstName: this.firstName, firstName: this.firstName,
lastName: this.lastName, lastName: this.lastName,
emailAddress: this.emailAddress, emailAddress: this.emailAddress
phoneNumber: this.phoneNumber
}; };
useMainStore().updateContactInfo(contactInfo); useMainStore().updateContactInfo(contactInfo);
useMainStore().updatePhoneNumbers({
home: this.phoneNumber,
service: this.phoneNumber
});
this.$emit('update-contact-details'); this.$emit('update-contact-details');
}, },
resetFormValues() { resetFormValues() {
const { firstName, const { firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber } = useMainStore().contactInfo; servicePhone } = useMainStore().contactInfo;
this.firstName = firstName; this.firstName = firstName;
this.lastName = lastName; this.lastName = lastName;
this.emailAddress = emailAddress; this.emailAddress = emailAddress;
this.phoneNumber = phoneNumber; this.phoneNumber = servicePhone;
}, },
openModal() { openModal() {
this.modal.openModal(); this.modal.openModal();

View file

@ -499,14 +499,14 @@ describe('tpa-submit', () => {
const firstName = 'Jones'; const firstName = 'Jones';
const lastName = 'Eddison'; const lastName = 'Eddison';
const emailAddress = 'myname@gmail.com'; const emailAddress = 'myname@gmail.com';
const phoneNumber = '0001112222'; const servicePhone = '0001112222';
const initialStore = { const initialStore = {
order: { order: {
contactInfo: { contactInfo: {
firstName, firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber servicePhone
} }
} }
}; };
@ -514,7 +514,7 @@ describe('tpa-submit', () => {
const expectedLine1 = 'Jones Eddison'; const expectedLine1 = 'Jones Eddison';
const expectedLine2 = emailAddress; const expectedLine2 = emailAddress;
const expectedLine3 = 'some value returned'; const expectedLine3 = 'some value returned';
toDisplayPhoneNumber.mockImplementation((number) => (number === phoneNumber ? expectedLine3 : '')); toDisplayPhoneNumber.mockImplementation((number) => (number === servicePhone ? expectedLine3 : ''));
const contactInfoSectionIndex = 3; const contactInfoSectionIndex = 3;
// Act // Act
@ -530,7 +530,7 @@ describe('tpa-submit', () => {
expect(contactInfoSection.lines[0]).toBe(expectedLine1); expect(contactInfoSection.lines[0]).toBe(expectedLine1);
expect(contactInfoSection.lines[1]).toBe(expectedLine2); expect(contactInfoSection.lines[1]).toBe(expectedLine2);
expect(contactInfoSection.lines[2]).toBe(expectedLine3); expect(contactInfoSection.lines[2]).toBe(expectedLine3);
expect(toDisplayPhoneNumber).toHaveBeenCalledWith(phoneNumber); expect(toDisplayPhoneNumber).toHaveBeenCalledWith(servicePhone);
}); });
}); });
describe('computed', () => { describe('computed', () => {

View file

@ -236,11 +236,11 @@ export default {
return [toTitleCase(this.companyName ?? ''), displayAddress, displayPhoneNumber]; return [toTitleCase(this.companyName ?? ''), displayAddress, displayPhoneNumber];
}, },
getContactInfoLines() { getContactInfoLines() {
const { firstName, lastName, emailAddress, phoneNumber } = useMainStore().contactInfo; const { firstName, lastName, emailAddress, servicePhone } = useMainStore().contactInfo;
return [ return [
`${firstName} ${lastName}`, `${firstName} ${lastName}`,
emailAddress ?? '', emailAddress ?? '',
toDisplayPhoneNumber(phoneNumber) toDisplayPhoneNumber(servicePhone)
]; ];
} }
}, },

View file

@ -174,6 +174,8 @@ import states from '@/constants/states';
import globalRules from '@/constants/global-rules'; import globalRules from '@/constants/global-rules';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
import MaskaFormattedMasks from '@/constants/maska-masks'; import MaskaFormattedMasks from '@/constants/maska-masks';
import globalMethods from '@/global-methods';
import { endpoints } from '@/constants/endpoints';
// define validation rules // define validation rules
defineRule( defineRule(

View file

@ -108,6 +108,12 @@ export default {
this.logPageView(analyticsPageEvents.ENTRY); this.logPageView(analyticsPageEvents.ENTRY);
}, },
pushValueToGA() {
pushToDataLayerIfDefined({
siteType: useMainStore().issConfig.siteType
});
},
pushExperimentsToDataLayer() { pushExperimentsToDataLayer() {
const { experiments } = useMainStore().applicationUser; const { experiments } = useMainStore().applicationUser;
experiments?.forEach((exp) => { experiments?.forEach((exp) => {

View file

@ -189,6 +189,9 @@ router.afterEach(async (to, from) => {
// Push experiments to Data Layer // Push experiments to Data Layer
analyticsMixin.methods.pushExperimentsToDataLayer(); analyticsMixin.methods.pushExperimentsToDataLayer();
// Push values to GA
analyticsMixin.methods.pushValueToGA();
} }
}); });

View file

@ -23,7 +23,7 @@ import {
} from '@/helpers/policy-vehicle-helper'; } from '@/helpers/policy-vehicle-helper';
import partTypeStrings from '@/constants/part-type-strings'; import partTypeStrings from '@/constants/part-type-strings';
import bailoutMessage from '@/constants/bailoutMessage'; import bailoutMessage from '@/constants/bailoutMessage';
import bailoutCode from "@/constants/bailoutCode"; import bailoutCode from '@/constants/bailoutCode';
const storeId = 'main'; const storeId = 'main';
@ -119,8 +119,7 @@ export const getDefaultState = () => ({
}, },
firstName: null, firstName: null,
lastName: null, lastName: null,
emailAddress: null, emailAddress: null
phoneNumber: null
}, },
serviceLocation: { serviceLocation: {
address: null, address: null,
@ -182,7 +181,9 @@ export const getDefaultState = () => ({
firstName: null, firstName: null,
lastName: null, lastName: null,
emailAddress: null, emailAddress: null,
phoneNumber: null, homePhone: null,
alternativePhone: null,
servicePhone: null,
requestTextUpdates: false, requestTextUpdates: false,
notesForTechnician: '' notesForTechnician: ''
}, },
@ -227,6 +228,9 @@ export const getDefaultState = () => ({
clientHeader: {}, clientHeader: {},
styleSheet: '', // Stylesheet used by the client. styleSheet: '', // Stylesheet used by the client.
parentAccountNumber: 0, // Parent account number used by the client. parentAccountNumber: 0, // Parent account number used by the client.
billToAccountNumber: null,
itacCashBillToNumber: null,
itacFnrBillToNumber: null,
isCoverageEnabled: false, // Indicates if we should be calling coverage on this flow. isCoverageEnabled: false, // Indicates if we should be calling coverage on this flow.
isClaimRegistrationRequired: false, // Indicates if the claim registration call needs to be made for a client to complete coverage verification. isClaimRegistrationRequired: false, // Indicates if the claim registration call needs to be made for a client to complete coverage verification.
isAuthenticated: false, // Indicates if user is authenticated or not. isAuthenticated: false, // Indicates if user is authenticated or not.
@ -237,7 +241,8 @@ export const getDefaultState = () => ({
policyNumber: null, policyNumber: null,
policyZipCode: null, policyZipCode: null,
dateOfLoss: null dateOfLoss: null
} },
siteType: null
} }
}); });
@ -247,9 +252,20 @@ export const useMainStore = defineStore({
id: storeId, id: storeId,
state: () => state, state: () => state,
getters: { getters: {
hasRecalibrationPart: (state) => getHasRecalibrationPart(state), billToNumberToUse(storeState) {
vehicle: (state) => state.order.vehicle, if (this.isITAC) {
damage: (state) => state.order.damage, return storeState.issConfig.itacCashBillToNumber;
}
if (this.isNoComp) {
return storeState.issConfig.itacFnrBillToNumber;
}
return storeState.issConfig.billToAccountNumber;
},
hasRecalibrationPart: (storeState) => getHasRecalibrationPart(storeState),
vehicle: (storeState) => storeState.order.vehicle,
damage: (storeState) => storeState.order.damage,
lineItems: (state) => state.order.lineItems, lineItems: (state) => state.order.lineItems,
payment: (state) => state.order.payment, payment: (state) => state.order.payment,
policy: (state) => state.order.policy, policy: (state) => state.order.policy,
@ -307,7 +323,9 @@ export const useMainStore = defineStore({
firstName: s.order.contactInfo.firstName ?? s.order.customer.firstName, firstName: s.order.contactInfo.firstName ?? s.order.customer.firstName,
lastName: s.order.contactInfo.lastName ?? s.order.customer.lastName, lastName: s.order.contactInfo.lastName ?? s.order.customer.lastName,
emailAddress: s.order.contactInfo.emailAddress ?? s.order.customer.emailAddress, emailAddress: s.order.contactInfo.emailAddress ?? s.order.customer.emailAddress,
phoneNumber: s.order.contactInfo.phoneNumber ?? s.order.customer.phoneNumber, homePhone: s.order.contactInfo.homePhone,
alternativePhone: s.order.contactInfo.alternativePhone,
servicePhone: s.order.contactInfo.servicePhone,
requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false, requestTextUpdates: s.order.contactInfo.requestTextUpdates ?? false,
notesForTechnician: s.order.contactInfo.notesForTechnician notesForTechnician: s.order.contactInfo.notesForTechnician
}), }),
@ -553,7 +571,7 @@ export const useMainStore = defineStore({
country: 'US' // TODO set from store country: 'US' // TODO set from store
}, },
homePhone: { homePhone: {
number: this.order.customer.phoneNumber?.replaceAll(nonNumberCharRegex, '') ?? '' number: this.contactInfo.homePhone?.replaceAll(nonNumberCharRegex, '') ?? ''
} }
}, },
driver: { driver: {
@ -813,7 +831,7 @@ export const useMainStore = defineStore({
startDate, startDate,
endDate, endDate,
applicationName: applicationConfig.APPLICATION_NAME, applicationName: applicationConfig.APPLICATION_NAME,
billToAccountNumber: this.issConfig.parentAccountNumber.toString(), // TODO: MAKE THIS REAL billToAccountNumber: this.billToNumberToUse,
parentAccountNumber: this.issConfig.parentAccountNumber, // this.payment.parentAccountNumber, parentAccountNumber: this.issConfig.parentAccountNumber, // this.payment.parentAccountNumber,
carId: vehicle.carId, carId: vehicle.carId,
lineItems, lineItems,
@ -876,7 +894,7 @@ export const useMainStore = defineStore({
endDate, endDate,
shopAppointmentType, shopAppointmentType,
applicationName: applicationConfig.APPLICATION_NAME, applicationName: applicationConfig.APPLICATION_NAME,
billToAccountNumber: order.policy.isITAC ? applicationConfig.ITAC_CASH_BILLTO : applicationConfig.ITAC_FAIR_AND_REASONABLE_BILLTO, // TODO: MAKE THIS REAL billToAccountNumber: this.billToNumberToUse,
parentAccountNumber: this.issConfig.parentAccountNumber, // this.payment.parentAccountNumber, parentAccountNumber: this.issConfig.parentAccountNumber, // this.payment.parentAccountNumber,
carId: vehicle.carId, carId: vehicle.carId,
lineItems, lineItems,
@ -1001,6 +1019,7 @@ export const useMainStore = defineStore({
let queryString = let queryString =
`ParentAccountNumber=${this.order.accountNumber}` `ParentAccountNumber=${this.order.accountNumber}`
+ `&BillToAccountNumber=${this.billToNumberToUse}`
+ `&CTU=${ctuToUse}` + `&CTU=${ctuToUse}`
+ `&Deductible=${deductibleToUse}` + `&Deductible=${deductibleToUse}`
+ `&ZipCode=${zipCodeToUse}` + `&ZipCode=${zipCodeToUse}`
@ -1029,12 +1048,10 @@ export const useMainStore = defineStore({
getMobileFeePart() { getMobileFeePart() {
const damageType = this.damage.isRepair ? 'Repair' : 'Replace'; const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
const parentAccountNumber = 167132; // TODO: MAKE THIS REAL
const billToAccountNumber = 87291; // TODO: MAKE THIS REAL
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetMobileFeePart.method, method: endpoints.GetMobileFeePart.method,
endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}` endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${this.order.accountNumber}/${this.billToNumberToUse}`
}); });
}, },
@ -1203,7 +1220,7 @@ export const useMainStore = defineStore({
policyHolder: { policyHolder: {
policyFirstName: customer.firstName, policyFirstName: customer.firstName,
policyLastName: customer.lastName, policyLastName: customer.lastName,
policyPhoneNumber: customer.phoneNumber, policyPhoneNumber: contactInfo.servicePhone,
policyEmail: customer.emailAddress, policyEmail: customer.emailAddress,
policyState: customer.address.state policyState: customer.address.state
}, },
@ -1227,8 +1244,10 @@ export const useMainStore = defineStore({
emailAddress: contactInfo.emailAddress || customer.emailAddress, emailAddress: contactInfo.emailAddress || customer.emailAddress,
firstName: contactInfo.firstName || customer.firstName, firstName: contactInfo.firstName || customer.firstName,
lastName: contactInfo.lastName || customer.lastName, lastName: contactInfo.lastName || customer.lastName,
phoneNumber: contactInfo.phoneNumber, homePhone: contactInfo.homePhone,
optInSms: contactInfo.requestTextUpdates ?? false servicePhone: contactInfo.servicePhone,
alternativePhone: contactInfo.alternativePhone,
isSmsOptIn: contactInfo.requestTextUpdates ?? false
}, },
lineItems: { lineItems: {
glassParts: lineItems.glassParts, glassParts: lineItems.glassParts,
@ -1324,7 +1343,6 @@ export const useMainStore = defineStore({
order.customer.emailAddress = data.customer?.emailAddress; order.customer.emailAddress = data.customer?.emailAddress;
order.customer.firstName = data.customer?.firstName; order.customer.firstName = data.customer?.firstName;
order.customer.lastName = data.customer?.lastName; order.customer.lastName = data.customer?.lastName;
order.customer.phoneNumber = data?.customer?.phoneNumber;
order.customer.address.streetAddress = data.customer?.address?.streetAddress; order.customer.address.streetAddress = data.customer?.address?.streetAddress;
order.customer.address.streetAddress2 = data.customer?.address?.streetAddress2; order.customer.address.streetAddress2 = data.customer?.address?.streetAddress2;
@ -1335,7 +1353,8 @@ export const useMainStore = defineStore({
order.contactInfo.firstName = data?.customer?.firstName; order.contactInfo.firstName = data?.customer?.firstName;
order.contactInfo.lastName = data?.customer?.lastName; order.contactInfo.lastName = data?.customer?.lastName;
order.contactInfo.emailAddress = data?.customer?.emailAddress; order.contactInfo.emailAddress = data?.customer?.emailAddress;
order.contactInfo.phoneNumber = data?.customer?.phoneNumber; order.contactInfo.homePhone = data?.customer?.phoneNumber;
order.contactInfo.servicephone = data?.customer?.phoneNumber;
order.contactInfo.requestTextUpdates = data?.customer?.isSmsOptIn; order.contactInfo.requestTextUpdates = data?.customer?.isSmsOptIn;
order.payment.insuranceCoverage.isVerified = data?.payment?.insuranceCoverage?.isVerified; order.payment.insuranceCoverage.isVerified = data?.payment?.insuranceCoverage?.isVerified;
@ -1671,6 +1690,10 @@ export const useMainStore = defineStore({
this.issConfig.disabledFields.policyNumber = false; this.issConfig.disabledFields.policyNumber = false;
this.issConfig.disabledFields.policyZipCode = false; this.issConfig.disabledFields.policyZipCode = false;
this.issConfig.disabledFields.dateOfLoss = false; this.issConfig.disabledFields.dateOfLoss = false;
this.issConfig.siteType = null;
this.issConfig.billToAccountNumber = null;
this.issConfig.itacCashBillToNumber = null;
this.issConfig.itacFnrBillToNumber = null;
}, },
disableKeyFields() { disableKeyFields() {
@ -1773,8 +1796,11 @@ export const useMainStore = defineStore({
this.order.policy.damageState = welcomePageModel?.damageState; this.order.policy.damageState = welcomePageModel?.damageState;
this.order.policy.damageCity = welcomePageModel?.damageCity; this.order.policy.damageCity = welcomePageModel?.damageCity;
this.order.policy.isDamageGlassOnly = welcomePageModel?.isDamageGlassOnly; this.order.policy.isDamageGlassOnly = welcomePageModel?.isDamageGlassOnly;
this.order.customer.phoneNumber = welcomePageModel?.phoneNumber;
this.order.customer.emailAddress = welcomePageModel?.email; this.order.customer.emailAddress = welcomePageModel?.email;
this.updatePhoneNumbers({
home: welcomePageModel?.phoneNumber,
service: welcomePageModel?.phoneNumber
});
}, },
updatePolicyHolderDetails(customerQuestions) { updatePolicyHolderDetails(customerQuestions) {
this.order.customer.address.streetAddress = customerQuestions.addressQuestions.streetAddress; this.order.customer.address.streetAddress = customerQuestions.addressQuestions.streetAddress;
@ -1871,7 +1897,7 @@ export const useMainStore = defineStore({
const { vehicle } = this.order; const { vehicle } = this.order;
let queryString = let queryString =
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` `ParentAccountNumber=${this.order.accountNumber}`
+ `&CTU=${ctuToUse}` + `&CTU=${ctuToUse}`
+ `&CarId=${vehicle.carId}` + `&CarId=${vehicle.carId}`
+ `&Make=${vehicle.make}` + `&Make=${vehicle.make}`
@ -1898,7 +1924,6 @@ export const useMainStore = defineStore({
async taxOrderItemsAndSaveServerData(pricedLineItems) { async taxOrderItemsAndSaveServerData(pricedLineItems) {
const { order } = this; const { order } = this;
const { serviceLocation } = order; const { serviceLocation } = order;
const billToAccountNumber = this.issConfig.parentAccountNumber.toString(); // payment
const { providerNumber } = serviceLocation.provider; const { providerNumber } = serviceLocation.provider;
const { appointmentType } = serviceLocation; const { appointmentType } = serviceLocation;
const serviceLocationCity = serviceLocation.city; const serviceLocationCity = serviceLocation.city;
@ -1924,7 +1949,7 @@ export const useMainStore = defineStore({
|| appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) { || appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
queryString = queryString =
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}`
+ `&BillToAccountNumber=${billToAccountNumber}` + `&BillToAccountNumber=${this.billToNumberToUse}`
+ `&ProviderNumber=${providerNumber}` + `&ProviderNumber=${providerNumber}`
+ `&AppointmentType=${appointmentType}` + `&AppointmentType=${appointmentType}`
+ `&ServiceLocation.City=${serviceLocationCity}` + `&ServiceLocation.City=${serviceLocationCity}`
@ -1934,7 +1959,7 @@ export const useMainStore = defineStore({
} else { } else {
queryString = queryString =
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}`
+ `&BillToAccountNumber=${billToAccountNumber}` + `&BillToAccountNumber=${this.billToNumberToUse}`
+ `&ProviderNumber=${providerNumber}` + `&ProviderNumber=${providerNumber}`
+ `&AppointmentType=${appointmentType}` + `&AppointmentType=${appointmentType}`
+ `&${pricedLineItemsFormattedForRequest}`; + `&${pricedLineItemsFormattedForRequest}`;
@ -2121,11 +2146,17 @@ export const useMainStore = defineStore({
this.order.contactInfo.firstName = contactInfo?.firstName ?? ''; this.order.contactInfo.firstName = contactInfo?.firstName ?? '';
this.order.contactInfo.lastName = contactInfo?.lastName ?? ''; this.order.contactInfo.lastName = contactInfo?.lastName ?? '';
this.order.contactInfo.emailAddress = contactInfo?.emailAddress ?? ''; this.order.contactInfo.emailAddress = contactInfo?.emailAddress ?? '';
this.order.contactInfo.phoneNumber = contactInfo?.phoneNumber ?? '';
this.order.contactInfo.requestTextUpdates = contactInfo?.requestTextUpdates ?? false; this.order.contactInfo.requestTextUpdates = contactInfo?.requestTextUpdates ?? false;
this.order.contactInfo.notesForTechnician = contactInfo?.notesForTechnician ?? ''; this.order.contactInfo.notesForTechnician = contactInfo?.notesForTechnician ?? '';
}, },
updatePhoneNumbers(phoneNumbers) {
const contact = this.order.contactInfo;
contact.homePhone = phoneNumbers.home !== undefined ? phoneNumbers.home : contact.homePhone;
contact.alternativePhone = phoneNumbers.alternative !== undefined ? phoneNumbers.alternative : contact.alternativePhone;
contact.servicePhone = phoneNumbers.service !== undefined ? phoneNumbers.service : contact.servicePhone;
},
GetExperimentsByUser(userId) { GetExperimentsByUser(userId) {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetExperimentsByUser.method, method: endpoints.GetExperimentsByUser.method,
@ -2277,8 +2308,11 @@ export const useMainStore = defineStore({
setBailoutContactInfo(contact) { setBailoutContactInfo(contact) {
this.order.customer.firstName = contact.firstName; this.order.customer.firstName = contact.firstName;
this.order.customer.lastName = contact.lastName; this.order.customer.lastName = contact.lastName;
this.order.customer.phoneNumber = contact.phoneNumber;
this.order.customer.emailAddress = contact.email; this.order.customer.emailAddress = contact.email;
this.updatePhoneNumbers({
home: contact.phoneNumber,
service: contact.phoneNumber
});
this.pageData(issPageValues.BAILOUT_PAGE).submit = true; this.pageData(issPageValues.BAILOUT_PAGE).submit = true;
}, },
@ -2309,7 +2343,6 @@ export const useMainStore = defineStore({
this.order.policy.damageCity = null; this.order.policy.damageCity = null;
this.order.policy.damageState = null; this.order.policy.damageState = null;
this.order.policy.isITAC = false; this.order.policy.isITAC = false;
this.order.customer.phoneNumber = null;
this.order.customer.emailAddress = null; this.order.customer.emailAddress = null;
this.order.customer.firstName = null; this.order.customer.firstName = null;
this.order.customer.lastName = null; this.order.customer.lastName = null;

View file

@ -1,5 +1,5 @@
import { setActivePinia, createPinia } from 'pinia'; import { setActivePinia, createPinia } from 'pinia';
import { useMainStore } from '@/store/index.js'; import { useMainStore, getDefaultState } from '@/store/index.js';
import globalMethods from '@/global-methods.js'; import globalMethods from '@/global-methods.js';
import { getRandomString, getRandomGuid, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js'; import { getRandomString, getRandomGuid, getRandomInt, getRandomBoolean } from '@/helpers/data-generation.js';
import coverageStatuses from '@/constants/coverage-statuses.js'; import coverageStatuses from '@/constants/coverage-statuses.js';
@ -14,7 +14,13 @@ describe('Store', () => {
beforeEach(() => { beforeEach(() => {
const pinia = createPinia(); const pinia = createPinia();
setActivePinia(pinia); setActivePinia(pinia);
store = useMainStore(); store = useMainStore();
const defaultState = getDefaultState();
Object.keys(defaultState).forEach((key) => {
store[key] = defaultState[key];
});
store.applicationUser.eventBus = []; store.applicationUser.eventBus = [];
jest.resetAllMocks(); jest.resetAllMocks();
}); });
@ -478,7 +484,6 @@ describe('Store', () => {
const firstName = getRandomString(4, 10); const firstName = getRandomString(4, 10);
const lastName = getRandomString(5, 15); const lastName = getRandomString(5, 15);
const emailAddress = false; const emailAddress = false;
const phoneNumber = getRandomInt(1000000000, 9999999999);
const requestTextUpdates = getRandomBoolean(); const requestTextUpdates = getRandomBoolean();
const notesForTechnician = getRandomString(50, 150); const notesForTechnician = getRandomString(50, 150);
@ -486,7 +491,6 @@ describe('Store', () => {
store.updateContactInfo({ firstName, store.updateContactInfo({ firstName,
lastName, lastName,
emailAddress, emailAddress,
phoneNumber,
requestTextUpdates, requestTextUpdates,
notesForTechnician }); notesForTechnician });
@ -494,10 +498,27 @@ describe('Store', () => {
expect(store.contactInfo.firstName).toEqual(firstName); expect(store.contactInfo.firstName).toEqual(firstName);
expect(store.contactInfo.lastName).toEqual(lastName); expect(store.contactInfo.lastName).toEqual(lastName);
expect(store.contactInfo.emailAddress).toEqual(emailAddress); expect(store.contactInfo.emailAddress).toEqual(emailAddress);
expect(store.contactInfo.phoneNumber).toEqual(phoneNumber);
expect(store.contactInfo.requestTextUpdates).toEqual(requestTextUpdates); expect(store.contactInfo.requestTextUpdates).toEqual(requestTextUpdates);
expect(store.contactInfo.notesForTechnician).toEqual(notesForTechnician); expect(store.contactInfo.notesForTechnician).toEqual(notesForTechnician);
}); });
it('updatePhoneNumbers updates phone info in store', () => {
// Arrange
const homePhone = getRandomInt(1000000000, 9999999999);
const servicePhone = getRandomInt(1000000000, 9999999999);
const altPhone = getRandomInt(1000000000, 9999999999);
// Act
store.updatePhoneNumbers({
home: homePhone,
service: servicePhone,
alternative: altPhone
});
// Assert
expect(store.contactInfo.homePhone).toEqual(homePhone);
expect(store.contactInfo.servicePhone).toEqual(servicePhone);
expect(store.contactInfo.alternativePhone).toEqual(altPhone);
});
it('All null values => contact info set in store to all nulls', () => { it('All null values => contact info set in store to all nulls', () => {
// Act // Act
store.updateContactInfo({}); store.updateContactInfo({});
@ -506,7 +527,6 @@ describe('Store', () => {
expect(store.contactInfo.firstName).toEqual(''); expect(store.contactInfo.firstName).toEqual('');
expect(store.contactInfo.lastName).toEqual(''); expect(store.contactInfo.lastName).toEqual('');
expect(store.contactInfo.emailAddress).toEqual(''); expect(store.contactInfo.emailAddress).toEqual('');
expect(store.contactInfo.phoneNumber).toEqual('');
expect(store.contactInfo.requestTextUpdates).toEqual(false); expect(store.contactInfo.requestTextUpdates).toEqual(false);
expect(store.contactInfo.notesForTechnician).toEqual(''); expect(store.contactInfo.notesForTechnician).toEqual('');
}); });
@ -666,8 +686,9 @@ describe('Store', () => {
store.order.customer.firstName = customerFirstName; store.order.customer.firstName = customerFirstName;
store.order.customer.lastName = customerLastName; store.order.customer.lastName = customerLastName;
store.order.customer.emailAddress = customerEmail; store.order.customer.emailAddress = customerEmail;
store.order.customer.phoneNumber = customerPhoneNumber;
store.order.customer.address.state = customerState; store.order.customer.address.state = customerState;
store.order.contactInfo.homePhone = customerPhoneNumber;
store.order.contactInfo.servicePhone = customerPhoneNumber;
store.order.policy.policyNumber = policyNumber; store.order.policy.policyNumber = policyNumber;
store.order.policy.policyZipCode = policyZipCode; store.order.policy.policyZipCode = policyZipCode;
store.order.policy.policyLookupSuccessful = policyLookupSuccessful; store.order.policy.policyLookupSuccessful = policyLookupSuccessful;
@ -708,12 +729,16 @@ describe('Store', () => {
const contactFirstName = getRandomString(6, 6); const contactFirstName = getRandomString(6, 6);
const contactLastName = getRandomString(6, 6); const contactLastName = getRandomString(6, 6);
const contactEmail = getRandomString(6, 6); const contactEmail = getRandomString(6, 6);
const contactPhoneNumber = getRandomString(6, 6); const contactHomePhone = getRandomString(6, 6);
const contactServicePhone = getRandomString(6, 6);
const contactAlternativePhone = getRandomString(6, 6);
const requestTextUpdates = getRandomBoolean(); const requestTextUpdates = getRandomBoolean();
store.order.contactInfo.firstName = contactFirstName; store.order.contactInfo.firstName = contactFirstName;
store.order.contactInfo.lastName = contactLastName; store.order.contactInfo.lastName = contactLastName;
store.order.contactInfo.emailAddress = contactEmail; store.order.contactInfo.emailAddress = contactEmail;
store.order.contactInfo.phoneNumber = contactPhoneNumber; store.order.contactInfo.homePhone = contactHomePhone;
store.order.contactInfo.servicePhone = contactServicePhone;
store.order.contactInfo.alternativePhone = contactAlternativePhone;
store.order.contactInfo.requestTextUpdates = requestTextUpdates; store.order.contactInfo.requestTextUpdates = requestTextUpdates;
store.order.customer.address.streetAddress = streetAddress; store.order.customer.address.streetAddress = streetAddress;
store.order.customer.address.streetAddress2 = streetAddress2; store.order.customer.address.streetAddress2 = streetAddress2;
@ -740,8 +765,10 @@ describe('Store', () => {
emailAddress: contactEmail, emailAddress: contactEmail,
firstName: contactFirstName, firstName: contactFirstName,
lastName: contactLastName, lastName: contactLastName,
phoneNumber: contactPhoneNumber, homePhone: contactHomePhone,
optInSms: requestTextUpdates servicePhone: contactServicePhone,
alternativePhone: contactAlternativePhone,
isSmsOptIn: requestTextUpdates
}) })
}) })
})); }));
@ -1122,7 +1149,7 @@ describe('Store', () => {
expect(store.order.customer.firstName).toBe(customer.firstName); expect(store.order.customer.firstName).toBe(customer.firstName);
expect(store.order.customer.lastName).toBe(customer.lastName); expect(store.order.customer.lastName).toBe(customer.lastName);
expect(store.order.customer.emailAddress).toBe(customer.emailAddress); expect(store.order.customer.emailAddress).toBe(customer.emailAddress);
expect(store.order.customer.phoneNumber).toBe(customer.phoneNumber); expect(store.order.contactInfo.homePhone).toBe(customer.phoneNumber);
}); });
it('sets expected remaining order data', async () => { it('sets expected remaining order data', async () => {
// Arrange // Arrange
@ -1948,4 +1975,34 @@ describe('Store', () => {
expect(store.order.payment.paypalToken).toEqual(paypalToken); expect(store.order.payment.paypalToken).toEqual(paypalToken);
}); });
}); });
describe('billToNumberToUse getter', () => {
it('returns itacCashBillToNumber when in ITAC flow', () => {
// Arrange
store.order.policy.isITAC = true;
store.issConfig.itacCashBillToNumber = '12345';
// Assert
expect(store.billToNumberToUse).toEqual(store.issConfig.itacCashBillToNumber);
});
it('returns itacFnrBillToNumber when in NoComp flow', () => {
// Arrange
store.order.policy.noCoverage = true;
store.issConfig.itacFnrBillToNumber = '12345';
// Assert
expect(store.billToNumberToUse).toEqual(store.issConfig.itacFnrBillToNumber);
});
it('returns billToAccountNumber when not ITAC and not NoComp', () => {
// Arrange
store.order.policy.isITAC = null;
store.order.policy.noCoverage = null;
store.issConfig.billToAccountNumber = '12345';
// Assert
expect(store.billToNumberToUse).toEqual(store.issConfig.billToAccountNumber);
});
});
}); });