Skip to content

Commit

Permalink
Merge branch 'main' into feat/DTFS2-7781/add-effective-from-date-e2e-…
Browse files Browse the repository at this point in the history
…tests
  • Loading branch information
MarRobSoftwire authored Feb 3, 2025
2 parents a590b7d + 42fc3ea commit 43b9222
Show file tree
Hide file tree
Showing 100 changed files with 3,320 additions and 498 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { HttpStatusCode } from 'axios';
import {
Bank,
FEE_RECORD_STATUS,
FeeRecordCorrectionEntityMockBuilder,
FeeRecordEntityMockBuilder,
RECONCILIATION_IN_PROGRESS,
RECORD_CORRECTION_REASON,
UtilisationReportEntityMockBuilder,
} from '@ukef/dtfs2-common';
import { testApi } from '../../../test-api';
import { SqlDbHelper } from '../../../sql-db-helper';
import { aBank } from '../../../../test-helpers';
import { mongoDbClient } from '../../../../src/drivers/db-client';
import { wipe } from '../../../wipeDB';
import { replaceUrlParameterPlaceholders } from '../../../../test-helpers/replace-url-parameter-placeholders';

console.error = jest.fn();

const BASE_URL = '/v1/bank/:bankId/utilisation-reports/completed-corrections';

describe(`GET ${BASE_URL}`, () => {
const bankId = '123';
const bank: Bank = {
...aBank(),
id: bankId,
};

const report = UtilisationReportEntityMockBuilder.forStatus(RECONCILIATION_IN_PROGRESS).withBankId(bankId).build();
const feeRecord = FeeRecordEntityMockBuilder.forReport(report).withExporter('An exporter').withStatus(FEE_RECORD_STATUS.TO_DO_AMENDED).build();
report.feeRecords = [feeRecord];

beforeAll(async () => {
await SqlDbHelper.initialize();
await SqlDbHelper.deleteAllEntries('UtilisationReport');
await wipe(['banks']);

const banksCollection = await mongoDbClient.getCollection('banks');
await banksCollection.insertOne(bank);

await SqlDbHelper.saveNewEntries('UtilisationReport', [report]);
});

afterEach(async () => {
await SqlDbHelper.deleteAllEntries('FeeRecordCorrection');
});

afterAll(async () => {
await SqlDbHelper.deleteAllEntries('UtilisationReport');
await wipe(['banks']);
});

it(`should return '${HttpStatusCode.Ok}' and the completed fee record corrections response`, async () => {
// Arrange
const dateCorrectionReceived = new Date('2024-01-01');
const oldFacilityId = feeRecord.facilityId;
const newFacilityId = '12345678';

const feeRecordCorrection = FeeRecordCorrectionEntityMockBuilder.forFeeRecordAndIsCompleted(feeRecord, true)
.withId(1)
.withDateReceived(dateCorrectionReceived)
.withReasons([RECORD_CORRECTION_REASON.FACILITY_ID_INCORRECT, RECORD_CORRECTION_REASON.OTHER])
.withPreviousValues({
facilityId: oldFacilityId,
})
.withCorrectedValues({
facilityId: newFacilityId,
})
.withBankCommentary('Some bank commentary')
.build();

await SqlDbHelper.saveNewEntry('FeeRecordCorrection', feeRecordCorrection);

// Act
const response = await testApi.get(replaceUrlParameterPlaceholders(BASE_URL, { bankId }));

// Assert
expect(response.status).toEqual(HttpStatusCode.Ok);

const expectedMappedCompletedCorrections = [
{
id: feeRecordCorrection.id,
dateSent: dateCorrectionReceived.toISOString(),
exporter: feeRecord.exporter,
formattedReasons: 'Facility ID is incorrect, Other',
formattedPreviousValues: `${oldFacilityId}, -`,
formattedCorrectedValues: `${newFacilityId}, -`,
bankCommentary: feeRecordCorrection.bankCommentary,
},
];

expect(response.body).toEqual(expectedMappedCompletedCorrections);
});

it(`should return '${HttpStatusCode.Ok}' and an empty array when no completed fee record corrections with the supplied bank id can be found`, async () => {
// Arrange
const feeRecordCorrection = FeeRecordCorrectionEntityMockBuilder.forFeeRecordAndIsCompleted(feeRecord, true).build();

await SqlDbHelper.saveNewEntry('FeeRecordCorrection', feeRecordCorrection);

// Act
const response = await testApi.get(replaceUrlParameterPlaceholders(BASE_URL, { bankId: `${bankId}123` }));

// Assert
expect(response.status).toEqual(HttpStatusCode.Ok);

expect(response.body).toEqual([]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FeeRecordCorrectionEntityMockBuilder,
FeeRecordCorrectionTransientFormDataEntity,
FeeRecordCorrectionTransientFormDataEntityMockBuilder,
FeeRecordEntity,
FeeRecordEntityMockBuilder,
RECONCILIATION_IN_PROGRESS,
RECORD_CORRECTION_REASON,
Expand Down Expand Up @@ -165,6 +166,19 @@ describe(`PUT ${BASE_URL}`, () => {
expect(status).toEqual(HttpStatusCode.Ok);
});

it(`should update the fee record with corrected values and set status to ${FEE_RECORD_STATUS.TO_DO_AMENDED}`, async () => {
// Arrange
const requestBody = aValidRequestBody();

// Act
await testApi.put(requestBody).to(replaceUrlParameterPlaceholders(BASE_URL, { bankId, correctionId }));

// Assert
const feeRecord = await SqlDbHelper.manager.findOneBy(FeeRecordEntity, { id: feeRecordId });
expect(feeRecord?.facilityId).toEqual(correctFacilityId);
expect(feeRecord?.status).toEqual(FEE_RECORD_STATUS.TO_DO_AMENDED);
});

it('should save the previous and corrected values on the correction and complete it', async () => {
// Arrange
const requestBody = aValidRequestBody();
Expand Down
1 change: 1 addition & 0 deletions dtfs-central-api/src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export { calculateUkefShareOfUtilisation } from './calculate-ukef-share-of-utili
export { getKeyingSheetCalculationFacilityValues } from './get-keying-sheet-calculation-facility-values';
export { getCorrectionPreviousValuesFromFeeRecord } from './get-correction-previous-values-from-fee-record';
export { getCorrectionCorrectedValuesFromFormData } from './get-correction-corrected-values-from-form-data';
export { validateRequiredCorrectionField } from './validate-required-correction-field';
export * from './amendments';
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
import { RECORD_CORRECTION_REASON, CURRENCY, getFormattedMonetaryValue, RecordCorrectionReason, aRecordCorrectionValues } from '@ukef/dtfs2-common';
import { difference } from 'lodash';
import {
getFormattedCorrectionValueForCorrectionReason,
mapCorrectionReasonsAndValuesToFormattedValues,
} from './map-correction-reasons-and-values-to-formatted-values';

console.error = jest.fn();

describe('get-completed-fee-record-corrections.controller map-reasons-and-values-to-formatted-values helpers', () => {
describe('getFormattedCorrectionValueForCorrectionReason', () => {
const reasonsExcludingOther = difference(Object.values(RECORD_CORRECTION_REASON), [RECORD_CORRECTION_REASON.OTHER]);

it(`should return the correction values "facilityId" value for reason "${RECORD_CORRECTION_REASON.FACILITY_ID_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.FACILITY_ID_INCORRECT;
const facilityId = 'some-value';
const correctionValues = {
...aRecordCorrectionValues(),
facilityId,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(facilityId);
});

it(`should return the correction values "feesPaidToUkefForThePeriodCurrency" value for reason "${RECORD_CORRECTION_REASON.REPORTED_CURRENCY_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.REPORTED_CURRENCY_INCORRECT;
const feesPaidToUkefForThePeriodCurrency = CURRENCY.GBP;
const correctionValues = {
...aRecordCorrectionValues(),
feesPaidToUkefForThePeriodCurrency,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(feesPaidToUkefForThePeriodCurrency);
});

it(`should map correction values "feesPaidToUkefForThePeriod" value to formatted monetary amount for reason "${RECORD_CORRECTION_REASON.REPORTED_FEE_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.REPORTED_FEE_INCORRECT;
const feesPaidToUkefForThePeriod = 123.45;
const correctionValues = {
...aRecordCorrectionValues(),
feesPaidToUkefForThePeriod,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(getFormattedMonetaryValue(feesPaidToUkefForThePeriod));
});

it(`should map correction values "feesPaidToUkefForThePeriod" value of 0 to formatted monetary amount for reason "${RECORD_CORRECTION_REASON.REPORTED_FEE_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.REPORTED_FEE_INCORRECT;
const feesPaidToUkefForThePeriod = 0;
const correctionValues = {
...aRecordCorrectionValues(),
feesPaidToUkefForThePeriod,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(getFormattedMonetaryValue(feesPaidToUkefForThePeriod));
});

it(`should map correction values "facilityUtilisation" value to formatted monetary amount for reason "${RECORD_CORRECTION_REASON.UTILISATION_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.UTILISATION_INCORRECT;
const facilityUtilisation = 10000.23;
const correctionValues = {
...aRecordCorrectionValues(),
facilityUtilisation,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(getFormattedMonetaryValue(facilityUtilisation));
});

it(`should map correction values "facilityUtilisation" value of 0 to formatted monetary amount for reason "${RECORD_CORRECTION_REASON.UTILISATION_INCORRECT}"`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.UTILISATION_INCORRECT;
const facilityUtilisation = 0;
const correctionValues = {
...aRecordCorrectionValues(),
facilityUtilisation,
};

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual(getFormattedMonetaryValue(facilityUtilisation));
});

it(`should map reason "${RECORD_CORRECTION_REASON.OTHER}" to a hyphen character`, () => {
// Arrange
const reason = RECORD_CORRECTION_REASON.OTHER;
const correctionValues = aRecordCorrectionValues();

// Act
const formattedValue = getFormattedCorrectionValueForCorrectionReason(correctionValues, reason);

// Assert
expect(formattedValue).toEqual('-');
});

it.each(reasonsExcludingOther)('should throw error when required value for reason "%s" is set to "null" in the correction values', (reason) => {
// Arrange
const correctionValues = {
facilityId: null,
facilityUtilisation: null,
feesPaidToUkefForThePeriod: null,
feesPaidToUkefForThePeriodCurrency: null,
};

// Act & Assert
expect(() => getFormattedCorrectionValueForCorrectionReason(correctionValues, reason)).toThrow();
});
});

describe('mapCorrectionReasonsAndValuesToFormattedValues', () => {
it('should return an empty array if no reasons are provided', () => {
// Arrange
const reasons: RecordCorrectionReason[] = [];
const correctionValues = aRecordCorrectionValues();

// Act
const formattedValues = mapCorrectionReasonsAndValuesToFormattedValues(reasons, correctionValues);

// Assert
expect(formattedValues).toEqual([]);
});

it(`should return the expected array of formatted form data values when only one reason is provided`, () => {
// Arrange
const reasons = [RECORD_CORRECTION_REASON.UTILISATION_INCORRECT];

const facilityUtilisation = 10000.23;

const correctionValues = {
...aRecordCorrectionValues(),
facilityUtilisation,
};

// Act
const formattedValues = mapCorrectionReasonsAndValuesToFormattedValues(reasons, correctionValues);

// Assert
const expectedFormattedValues = [getFormattedMonetaryValue(facilityUtilisation)];

expect(formattedValues).toHaveLength(1);
expect(formattedValues).toEqual(expectedFormattedValues);
});

it(`should return the expected array of formatted form data values when some reasons are provided`, () => {
// Arrange
const reasons = [RECORD_CORRECTION_REASON.REPORTED_FEE_INCORRECT, RECORD_CORRECTION_REASON.FACILITY_ID_INCORRECT, RECORD_CORRECTION_REASON.OTHER];

const feesPaidToUkefForThePeriod = 10000.23;
const facilityId = '12345678';

const correctionValues = {
...aRecordCorrectionValues(),
feesPaidToUkefForThePeriod,
facilityId,
};

// Act
const formattedValues = mapCorrectionReasonsAndValuesToFormattedValues(reasons, correctionValues);

// Assert
const expectedFormattedValues = [getFormattedMonetaryValue(feesPaidToUkefForThePeriod), facilityId, '-'];

expect(formattedValues).toHaveLength(3);
expect(formattedValues).toEqual(expectedFormattedValues);
});

it(`should return the expected array of formatted form data values when all reasons are provided`, () => {
// Arrange
const reasons = Object.values(RECORD_CORRECTION_REASON);

const facilityId = '12345678';
const feesPaidToUkefForThePeriodCurrency = CURRENCY.EUR;
const feesPaidToUkefForThePeriod = 123.45;
const facilityUtilisation = 100000;

const correctionValues = {
facilityId,
feesPaidToUkefForThePeriodCurrency,
feesPaidToUkefForThePeriod,
facilityUtilisation,
};

// Act
const formattedValues = mapCorrectionReasonsAndValuesToFormattedValues(reasons, correctionValues);

// Assert
const expectedFormattedValues = [
facilityId,
feesPaidToUkefForThePeriodCurrency,
getFormattedMonetaryValue(feesPaidToUkefForThePeriod),
getFormattedMonetaryValue(facilityUtilisation),
'-',
];

expect(formattedValues).toHaveLength(5);
expect(formattedValues).toEqual(expectedFormattedValues);
});
});
});
Loading

0 comments on commit 43b9222

Please sign in to comment.