INSR-8882: add unit tests, address possible errors, formatting fixes
This commit is contained in:
parent
50404eb4e6
commit
d4f7213a25
5 changed files with 258 additions and 11 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import packageNames from "./package-names";
|
||||
import { paymentMethods } from "./payment-method-constants";
|
||||
import packageNames from './package-names';
|
||||
import { paymentMethods } from './payment-method-constants';
|
||||
|
||||
const analyticsPageEvents = Object.freeze({
|
||||
ENTRY: 'ENTRY',
|
||||
|
|
@ -49,12 +49,12 @@ const analyticsPaymentTypeMap = new Map([
|
|||
[paymentMethods.PAY_AT_TIME_OF_SERVICE, 'pay_at_service'],
|
||||
[paymentMethods.PAYPAL, 'pay_pal'],
|
||||
[paymentMethods.APPLEPAY, 'apple_pay'],
|
||||
])
|
||||
]);
|
||||
|
||||
const analyticsServicePackageMap = new Map([
|
||||
[packageNames.TIER_ONE, 'basic'],
|
||||
[packageNames.TIER_TWO, 'essentials'],
|
||||
[packageNames.TIER_THREE, 'essentialsplus']
|
||||
])
|
||||
]);
|
||||
|
||||
export { analyticsPageEvents, GaCategories, GaActions, GaLabels, GaEvents, ValueToLogTypes, analyticsPaymentTypeMap, analyticsServicePackageMap };
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import coverageType from '@/constants/coverage-type';
|
|||
import { deepClone } from '@/helpers/object-helper';
|
||||
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
|
||||
import { paymentMethods } from '@/constants/payment-method-constants';
|
||||
import partTypeStrings from '@/constants/part-type-strings';
|
||||
import packageNames from '@/constants/package-names';
|
||||
|
||||
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
|
||||
|
||||
|
|
@ -28,7 +30,8 @@ const mockMixin = {
|
|||
methods: {
|
||||
getCmsContent: jest.fn(),
|
||||
setCmsContent: jest.fn(),
|
||||
savePageDataToStore: jest.fn()
|
||||
savePageDataToStore: jest.fn(),
|
||||
pushEventToGA: jest.fn()
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -958,6 +961,250 @@ describe('OrderConfirmation.vue', () => {
|
|||
});
|
||||
});
|
||||
describe('Methods', () => {
|
||||
describe('handleAnalyticsEvents', () => {
|
||||
let mixin;
|
||||
beforeEach(() => {
|
||||
mixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn(),
|
||||
setCmsContent: jest.fn(),
|
||||
savePageDataToStore: jest.fn(),
|
||||
pushEventToGA: jest.fn()
|
||||
}
|
||||
};
|
||||
});
|
||||
test('should call pushEventToGA with confirmation event for mobile repair', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.serviceLocation.appointmentType = AppointmentTypeStrings.MOBILE;
|
||||
order.damage.isRepair = true;
|
||||
order.isVerified = false;
|
||||
order.isMobileAppointment = true;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('confirmation', 'safelite', expect.stringContaining('mobile'), true);
|
||||
});
|
||||
test('should call pushEventToGA with confirmation event for in-shop replace', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.serviceLocation.appointmentType = AppointmentTypeStrings.IN_SHOP;
|
||||
order.damage.isRepair = false;
|
||||
order.isVerified = true;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('confirmation', 'safelite', expect.stringContaining('replace'), true);
|
||||
});
|
||||
test('should call pushEventToGA for payment PIA successful when payment.isPayInAdvance is true', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.payment.isPayInAdvance = true;
|
||||
order.payment.paymentMethod = paymentMethods.CREDIT_CARD;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('payment_page', 'pia_successful', expect.any(String), true);
|
||||
});
|
||||
test('should not call pushEventToGA for PIA when payment.isPayInAdvance is false', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.payment.isPayInAdvance = false;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
const paymentPageCalls = mixin.methods.pushEventToGA.mock.calls.filter(call => call[0] === 'payment_page');
|
||||
expect(paymentPageCalls.length).toBe(0);
|
||||
});
|
||||
test('should call pushEventToGA for service package when submittedOrder.servicePackage exists', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.servicePackage = packageNames.TIER_ONE;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('service_package', 'package_purchased', expect.any(String), true);
|
||||
});
|
||||
test('should not call pushEventToGA for service package when submittedOrder.servicePackage is null', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.servicePackage = null;
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
const servicePackageCalls = mixin.methods.pushEventToGA.mock.calls.filter(call => call[0] === 'service_package');
|
||||
expect(servicePackageCalls.length).toBe(0);
|
||||
});
|
||||
test('should call pushEventToGA for total price when isFirstLoad is true and cart total greater than 0', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
const expectedTotal = 100;
|
||||
order.lineItems.glassParts = [{ partType: 'WINDSHIELD', sellingPrice: expectedTotal }];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// Act
|
||||
wrapper.vm.handleAnalyticsEvents(true);
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('total_price', expectedTotal.toString(), expect.any(String), true);
|
||||
});
|
||||
test('should not call pushEventToGA for total price when isFirstLoad is false', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
const expectedTotal = 100;
|
||||
order.lineItems.glassParts = [{ partType: 'WINDSHIELD', sellingPrice: expectedTotal }];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
useMainStore().pageData = jest.fn().mockReturnValue({ isFirstLoad: false });
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
const totalPriceCalls = mixin.methods.pushEventToGA.mock.calls.filter(call => call[0] === 'total_price');
|
||||
expect(totalPriceCalls.length).toBe(0);
|
||||
});
|
||||
test('should not call pushEventToGA for total price when cart total is 0', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
const expectedTotal = 0;
|
||||
order.lineItems.glassParts = [{ partType: 'WINDSHIELD', sellingPrice: 0 }];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
const totalPriceCalls = mixin.methods.pushEventToGA.mock.calls.filter(call => call[0] === 'total_price');
|
||||
expect(totalPriceCalls.length).toBe(0);
|
||||
});
|
||||
test('should call pushEventToGA for rain defense purchased when hasRainRepel is true', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.lineItems.vaps = [{ partType: partTypeStrings.RAIN_DEFENSE }];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('rain_defense', 'purchased', expect.any(String), true);
|
||||
});
|
||||
test('should call pushEventToGA for rain defense no_purchase when hasRainRepel is false', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.lineItems.vaps = [];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('rain_defense', 'no_purchase', expect.any(String), true);
|
||||
});
|
||||
test('should call pushEventToGA for visitor_info_confirmation with ClientSite referring_site', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('visitor_info_confirmation', 'referring_site', 'ClientSite', true);
|
||||
});
|
||||
test('should call pushEventToGA for visitor_info_confirmation with client_name', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('visitor_info_confirmation', 'client_name', expect.any(String), true);
|
||||
});
|
||||
test('should call pushEventToGA for wipers purchased when hasWipers is true', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.lineItems.vaps = [{ partType: partTypeStrings.FRONT_WIPER }];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const mixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn().mockReturnValue([{ Text: 'Front Beam' }]),
|
||||
setCmsContent: jest.fn(),
|
||||
savePageDataToStore: jest.fn(),
|
||||
pushEventToGA: jest.fn()
|
||||
}
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('wipers', 'purchased', expect.any(String), true);
|
||||
});
|
||||
test('should call pushEventToGA for wipers no_purchase when hasWipers is false', () => {
|
||||
// Arrange
|
||||
const order = deepClone(sessionStorage);
|
||||
order.lineItems.vaps = [];
|
||||
const mockStoreActions = () => {
|
||||
useMainStore().getSubmittedOrder = jest.fn().mockImplementation(() => order);
|
||||
};
|
||||
const { wrapper } = getMountedComponent({}, {}, mockStoreActions, mixin);
|
||||
|
||||
// handleAnalyticsEvents is called on mount, no need to act
|
||||
|
||||
// Assert
|
||||
expect(mixin.methods.pushEventToGA).toHaveBeenCalledWith('wipers', 'no_purchase', 'none_none', true);
|
||||
});
|
||||
});;
|
||||
describe('formatDate', () => {
|
||||
test.each([
|
||||
['Wednesday, April 22, 2020', '2020-04-22'],
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ export default {
|
|||
handleAnalyticsEvents(isFirstLoad) {
|
||||
const mobileOrInshop = this.submittedOrder.isMobileAppointment ? 'mobile' : 'in_shop';
|
||||
const verifiedOrNotVerified = this.submittedOrder.isVerified ? 'verified' : 'not_verified';
|
||||
const repairOrReplace = this.submittedOrder.isRepair ? 'repair' : 'replace';
|
||||
const repairOrReplace = this.submittedOrder.isRepair ? 'repair' : 'replace';
|
||||
this.pushEventToGA('confirmation', 'safelite', `${mobileOrInshop}_${repairOrReplace}_${verifiedOrNotVerified}`, true);
|
||||
|
||||
if (this.payment.isPayInAdvance) {
|
||||
|
|
@ -651,7 +651,7 @@ export default {
|
|||
} else {
|
||||
coverageType = 'unverified';
|
||||
}
|
||||
const recalibrationType = this.submittedOrder.lineItems.glassParts.find((part) => part.requiresRecalibration).recalibrationType;
|
||||
const recalibrationType = this.submittedOrder.lineItems.glassParts?.find((part) => part.requiresRecalibration)?.recalibrationType;
|
||||
this.pushEventToGA(`recalibration_scheduled_${coverageType}`, this.vehicle.carId, `recal_type_${recalibrationType}`.replace(/ /g, '_').toLowerCase(), true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ export default {
|
|||
await global.$logger.logError(stringToLog);
|
||||
|
||||
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.piaType);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, true, true, null, 0);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, 'true', true, null, 0);
|
||||
this.pushEventToGA('payment_page', 'pia_failed', paymentMethodForAnalytics, true, null, result?.resultCode);
|
||||
|
||||
this.hasPaymentFailureError = true;
|
||||
|
|
@ -567,7 +567,7 @@ export default {
|
|||
|
||||
await global.$logger.logError(stringToLog);
|
||||
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.piaType);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, true, true, null, 0);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, 'true', true, null, 0);
|
||||
this.pushEventToGA('payment_page', 'pia_error', paymentMethodForAnalytics, true, null, error?.name);
|
||||
|
||||
this.hasPaymentFailureError = true;
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ export default {
|
|||
global.$logger.logError(stringToLog);
|
||||
|
||||
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.piaType);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, true, true, null, 0);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, 'true', true, null, 0);
|
||||
this.pushEventToGA('payment_page', 'pia_failed', paymentMethodForAnalytics, true, null, result?.resultCode);
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ export default {
|
|||
global.$logger.logError(stringToLog);
|
||||
|
||||
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.piaType);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, true, true, null, 0);
|
||||
this.pushEventToGA('transaction_declined_displayed', `${paymentMethodForAnalytics}_declined`, 'true', true, null, 0);
|
||||
this.pushEventToGA('payment_page', 'pia_error', paymentMethodForAnalytics, true, null, error?.name);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue