Merge pull request #486 from Safelite/feature/SSR-669

call get-final-deductible endpoint, display final deductible
This commit is contained in:
katiekroell 2023-11-14 10:06:17 -05:00 committed by GitHub
commit fbdd66d5d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 258 additions and 22 deletions

View file

@ -170,6 +170,10 @@ const endpoints = Object.freeze({
// eslint-disable-next-line max-len
url: (accountNumber, policyNumber, phoneNumber) => `/order/api/v1/order/duplicate-check/${accountNumber}/${policyNumber}/${phoneNumber}`,
method: 'GET'
},
FinalDeductible: {
url: '/coverage/api/v1/coverage/final-deductible',
method: 'POST'
}
});

View file

@ -797,8 +797,8 @@ describe.skip('coverageStatement.vue', () => {
});
describe('coverageStatement.vue-working', () => {
describe('Navigation', () => {
test('Function called on any FORWARD navigation', () => {
describe('ITAC flag', () => {
test('ITAC flag updated once component is initialized', () => {
// Arrange
const mainInitialState = {
order: {
@ -810,7 +810,7 @@ describe('coverageStatement.vue-working', () => {
const { wrapper } = getMountedComponent(mainInitialState);
// Act
wrapper.vm.forwardButtonAction();
wrapper.vm.initializeComponent();
// Assert
expect(wrapper.vm.mainStore.updatePolicyITACFlag)

View file

@ -147,6 +147,7 @@ export default {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to?.query?.issPage);
const supportingItemsPromise = await useMainStore().getSupportingItems();
const finalDeductiblePromise = await useMainStore().getFinalDeductible();
// Settle promises and get results
const promiseResultMap = [
@ -157,6 +158,10 @@ export default {
{
resultKey: 'supportingItems',
promise: supportingItemsPromise
},
{
resultKey: 'finalDeductible',
promise: finalDeductiblePromise
}
];
@ -247,13 +252,8 @@ export default {
return damageString === 'match' ? '' : damageString;
},
vehicleDeductible() {
if (useMainStore().order.damage.isRepair) {
const repairDeductible = useMainStore().order.policy.deductible.repair;
return repairDeductible;
}
const replaceDeductible = useMainStore().order.policy.deductible.replace;
return replaceDeductible;
const deductible = useMainStore().order.currentDeductible;
return deductible;
},
formattedDeductible() {
return this.getDeductibleString(this.vehicleDeductible);
@ -341,6 +341,7 @@ export default {
return !!useMainStore().vehicle.carId;
},
async initializeComponent() {
useMainStore().updatePolicyITACFlag(this.verifiedITAC);
if (this.policyLookupSuccessful
&& useMainStore().isClaimRegistrationRequired
&& (this.coveredAndServicePriceAboveOrEqualDeductible || this.verifiedITAC)) {
@ -352,7 +353,6 @@ export default {
return this.navigateForward();
},
async navigateForward() {
useMainStore().updatePolicyITACFlag(this.verifiedITAC);
if (this.unverified || this.verifiedDeductible) {
this.mainStore.saveSupportingItems(this.supportingItems);
this.$router.navigate(

View file

@ -67,6 +67,8 @@ import settleAllPromises from '@/helpers/layout-helper';
import { Form } from 'vee-validate';
import BaseFormMixin from '@/mixins/base-form-mixin.js';
import globalRules from '@/constants/global-rules.js';
import endorsementOptions from '@/constants/endorsement-options.js';
import { useMainStore } from '@/store';
export default {
@ -126,10 +128,10 @@ export default {
return this.getCmsContent('ParkingLotQuestion', 'Answers');
},
educatorEndorsement() {
return useMainStore().order.policy.endorsements?.includes('Educator') ?? false;
return useMainStore().order.policy.endorsements?.includes(endorsementOptions.EDUCATOR) ?? false;
},
parkingGuardEndorsement() {
return useMainStore().order.policy.endorsements?.includes('Parking Guard') ?? false;
return useMainStore().order.policy.endorsements?.includes(endorsementOptions.PARKING_GUARD) ?? false;
}
},
methods:
@ -140,23 +142,21 @@ export default {
async forwardButtonAction() {
// TO DO: remove hard coding and update data format once service returns endorsement questions
if (this.educatorEndorsement) {
this.questionAnswersArray.push(
{
this.questionAnswersArray.push({
questionNum: 1,
endorsement: 'Educator',
endorsementName: endorsementOptions.EDUCATOR,
questionText: this.schoolPropertyQuestionText,
selectedAnswer: this.schoolPropertyAnswer
});
};
}
if (this.parkingGuardEndorsement) {
this.questionAnswersArray.push(
{
this.questionAnswersArray.push({
questionNum: 2,
endorsement: 'Parking Guard',
endorsementName: endorsementOptions.PARKING_GUARD,
questionText: this.parkingLotQuestionText,
selectedAnswer: this.parkingLotAnswer
});
};
}
// save answers to store as order.policy.endorsementQuestionAnswers
useMainStore().saveEndorsementQuestionAnswers(this.questionAnswersArray);

View file

@ -14,6 +14,7 @@ import coverageStatuses from '@/constants/coverage-statuses';
import { deepEqual } from '@/helpers/object-helper';
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants';
import getDateDifferenceInDays from '@/helpers/date-helper';
import endorsementOptions from '@/constants/endorsement-options';
const storeId = 'main';
@ -79,7 +80,8 @@ const getDefaultState = () => ({
isITAC: false,
vehicles: [],
endorsements: [],
endorsementQuestionAnswers: null,
endorsementQuestionAnswers: [],
status: null,
policyData: null
},
customer: {
@ -513,6 +515,45 @@ export const useMainStore = defineStore({
});
});
},
getFinalDeductible() {
const endorsementAnswersForPayload = [];
const endorsementAnswers = this.order.policy.endorsementQuestionAnswers;
if (endorsementAnswers) {
endorsementAnswers.forEach((endorsement) => {
if (endorsement.selectedAnswer === 'Yes') {
endorsementAnswersForPayload.push(endorsement.endorsementName);
}
});
}
const manualGlassNamesArray = [];
const glassInformation = this.order.damage.glassToReplace;
glassInformation?.forEach((glassPiece) => {
manualGlassNamesArray.push(glassPiece?.glassLocation?.toUpperCase());
});
return new Promise((resolve, reject) => {
globalMethods.callHttpClient({
method: endpoints.FinalDeductible.method,
endpoint: endpoints.FinalDeductible.url,
payload: {
referralCorrelationId: this.order.referralCorrelationId,
accountNumber: this.issConfig.parentAccountNumber?.toString() ?? '',
endorsements: endorsementAnswersForPayload,
manualGlassNames: manualGlassNamesArray,
policyState: this.order.customer.address.state,
status: this.order.policy.status,
currentDeductible: this.order.currentDeductible,
noCoverage: this.order.policy.noCoverage,
isRepair: this.order.damage.isRepair
}
}).then((r) => {
this.updateDeductible(r.data);
return resolve(r);
}).catch((error) => reject(error));
});
},
getDuplicateReferrals() {
return new Promise((resolve, reject) => {
globalMethods.callHttpClient({
@ -1560,6 +1601,11 @@ export const useMainStore = defineStore({
updateIsSafeliteProvider(isSafelite) {
this.order.serviceLocation.IsSafeliteProvider = isSafelite;
},
updateDeductible(finalDeductible) {
this.order.currentDeductible = finalDeductible;
},
savePartQuestionAnswers(partQuestionAnswersArray) {
// if part question answers have changed, reset subsequent question answers
const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue(this.order.damage.partQuestionAnswers, 'result');

View file

@ -1694,4 +1694,190 @@ describe('Store', () => {
expect(store.isDropOffAppointment).toBe(false);
});
});
describe('getFinalDeductible method', () => {
describe('successful method call', () => {
it('calls get final deductible api endpoint', () => {
// Arrange
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve({}));
store.order.damage.glassToReplace = [getRandomString(10, 15)];
// Act
store.getFinalDeductible();
// Assert
expect(globalMethods.callHttpClient).toHaveBeenCalledWith(expect.objectContaining({
method: endpoints.FinalDeductible.method,
endpoint: endpoints.FinalDeductible.url
}));
});
it('returns expected response object', async () => {
// Arrange
const response = { deductible: getRandomInt(0, 5000) };
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(response));
store.order.damage.glassToReplace = [getRandomString(10, 15)];
// Act
const result = store.getFinalDeductible();
// Assert
await expect(result).resolves.toBe(response);
});
it('calls api with expected payload', () => {
// Arrange
const location = getRandomString(10, 15).toUpperCase();
store.order.damage.glassToReplace = [
{
glassLocation: location
}
];
const referralCorrelationId = getRandomGuid();
const accountNumber = getRandomString(6, 6);
const endorsements = [];
const manualGlassNames = [location];
const policyState = getRandomString(2, 2);
const status = getRandomString(6, 8);
const currentDeductible = getRandomInt(0, 5000);
const noCoverage = getRandomBoolean();
const isRepair = getRandomBoolean();
store.order.referralCorrelationId = referralCorrelationId;
store.issConfig.parentAccountNumber = accountNumber;
store.order.currentDeductible = currentDeductible;
store.order.policy.noCoverage = noCoverage;
store.order.policy.status = status;
store.order.customer.address.state = policyState;
store.order.damage.isRepair = isRepair;
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve({}));
// Act
store.getFinalDeductible();
// Assert
expect(globalMethods.callHttpClient).toHaveBeenCalledWith(({
method: endpoints.FinalDeductible.method,
endpoint: endpoints.FinalDeductible.url,
payload: ({
referralCorrelationId,
accountNumber,
endorsements,
manualGlassNames,
policyState,
status,
currentDeductible,
noCoverage,
isRepair
})
}));
});
it('only "Yes" endorsement answers are added to payload', () => {
// Arrange
const location = getRandomString(10, 15).toUpperCase();
store.order.damage.glassToReplace = [
{
glassLocation: location
}
];
const referralCorrelationId = getRandomGuid();
const accountNumber = getRandomString(6, 6);
const manualGlassNames = [location];
const policyState = getRandomString(2, 2);
const status = getRandomString(6, 8);
const currentDeductible = getRandomInt(0, 5000);
const noCoverage = getRandomBoolean();
const isRepair = getRandomBoolean();
const endorsementAnswers = [
{
questionNum: getRandomInt(1, 10),
endorsementName: getRandomString(8, 20),
questionText: getRandomString(50, 100),
selectedAnswer: 'Yes'
},
{
questionNum: getRandomInt(1, 10),
endorsementName: getRandomString(8, 20),
questionText: getRandomString(50, 100),
selectedAnswer: 'Yes'
},
{
questionNum: getRandomInt(1, 10),
endorsementName: getRandomString(8, 20),
questionText: getRandomString(50, 100),
selectedAnswer: 'No'
}
];
store.order.referralCorrelationId = referralCorrelationId;
store.issConfig.parentAccountNumber = accountNumber;
store.order.currentDeductible = currentDeductible;
store.order.policy.noCoverage = noCoverage;
store.order.policy.status = status;
store.order.customer.address.state = policyState;
store.order.policy.endorsementQuestionAnswers = endorsementAnswers;
store.order.damage.isRepair = isRepair;
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve({}));
// Act
store.getFinalDeductible();
// Assert
const expected = [endorsementAnswers[0].endorsementName, endorsementAnswers[1].endorsementName];
expect(globalMethods.callHttpClient).toHaveBeenCalledWith(({
method: endpoints.FinalDeductible.method,
endpoint: endpoints.FinalDeductible.url,
payload: ({
referralCorrelationId,
accountNumber,
endorsements: expected,
manualGlassNames,
policyState,
status,
currentDeductible,
noCoverage,
isRepair
})
}));
});
});
describe('unsuccessful api call', () => {
it('api call throws exception', async () => {
// Arrange
expect.assertions(2);
const error = 'final deductible error';
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.reject(error));
// Act
await store.getFinalDeductible().catch((e) => {
expect(e).toEqual(error);
});
// Assert
expect(globalMethods.callHttpClient).toHaveBeenCalledWith(expect.objectContaining({
method: endpoints.FinalDeductible.method,
endpoint: endpoints.FinalDeductible.url
}));
});
});
});
describe('updateDeductible method', () => {
it('final deductible is saved as currentDeductible in store', () => {
// Arrange
const finalDeductible = getRandomInt(0, 5000);
// Act
store.updateDeductible(finalDeductible);
// Assert
expect(store.order.currentDeductible).toEqual(finalDeductible);
});
it('null final deductible => currentDeductible in store set to null', () => {
// Arrange
const finalDeductible = null;
// Act
store.updateDeductible(finalDeductible);
// Assert
expect(store.order.currentDeductible).toEqual(finalDeductible);
});
});
});