Skip to content

Commit

Permalink
feat(FN-3691): cron job to delete old record correction transient for…
Browse files Browse the repository at this point in the history
…m data (#4168)
  • Loading branch information
Zainzzkk authored Jan 27, 2025
1 parent 942afea commit fe2faaf
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ UTILISATION_REPORT_CREATION_FAILURE_EMAIL_ADDRESS=

DEAL_CANCELLATION_SCHEDULE='* 2 * * *'

RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE='0 2 * * *'

# STORAGE
AZURE_PORTAL_STORAGE_ACCOUNT=
AZURE_PORTAL_STORAGE_ACCESS_KEY=
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ env:
ENTRA_ID_CLIENT_SECRET: ${{ vars.ENTRA_ID_CLIENT_SECRET }}
ENTRA_ID_REDIRECT_URL: ${{ vars.ENTRA_ID_REDIRECT_URL }}
DEAL_CANCELLATION_SCHEDULE: ${{ vars.DEAL_CANCELLATION_SCHEDULE }}
RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE: ${{ vars.RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE }}

jobs:
# 1. Setup test infrastructure
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ services:
- FF_TFM_DEAL_CANCELLATION_ENABLED
- DEAL_CANCELLATION_SCHEDULE
- FF_PORTAL_FACILITY_AMENDMENTS_ENABLED
- RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE

trade-finance-manager-ui:
build:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { LessThan } from 'typeorm';
import { deleteCorrectionRequestTransientFormData, deleteCorrectionRequestTransientFormDataJob } from '.';
import { FeeRecordCorrectionRequestTransientFormDataRepo } from '../../repositories/fee-record-correction-request-transient-form-data-repo/fee-record-correction-request-transient-form-data.repo';

describe('delete-record-correction-request-transient-form-data', () => {
jest.mock('typeorm', () => ({
LessThan: jest.fn(),
}));

const mockDelete = jest.fn();
console.error = jest.fn();

beforeAll(() => {
jest.useFakeTimers();
});

afterAll(() => {
jest.useRealTimers();
});

describe('deleteRecordCorrectionRequestTransientFormData', () => {
beforeEach(() => {
jest.resetAllMocks();
FeeRecordCorrectionRequestTransientFormDataRepo.delete = mockDelete;
jest.useFakeTimers().setSystemTime(new Date('2025-01-02 12:10:00'));
});

it('should delete records older than one day', async () => {
await deleteCorrectionRequestTransientFormData();

expect(mockDelete).toHaveBeenCalledTimes(1);

expect(mockDelete).toHaveBeenCalledWith({
lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')),
});
});

it('should delete records older than one day if it is the first day of the month', async () => {
jest.useFakeTimers().setSystemTime(new Date('2025-01-01 12:10:00'));

await deleteCorrectionRequestTransientFormData();

expect(mockDelete).toHaveBeenCalledTimes(1);

expect(mockDelete).toHaveBeenCalledWith({
lastUpdatedAt: LessThan(new Date('2024-12-31:12:10:00')),
});
});

it('should throw an error if deletion fails', async () => {
const errorMessage = 'This is an error';
const error = new Error(errorMessage);
jest.mocked(mockDelete).mockRejectedValue(error);

await deleteCorrectionRequestTransientFormData();

expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith(
'Error deleting old transient record correction requests - deleteCorrectionRequestTransientFormDataJob CRON job: %o',
error,
);
});
});

describe('deleteRecordCorrectionRequestTransientFormDataJob', () => {
beforeEach(() => {
jest.resetAllMocks();
FeeRecordCorrectionRequestTransientFormDataRepo.delete = mockDelete;
jest.useFakeTimers().setSystemTime(new Date('2025-01-02 12:10:00'));
});

it('should be scheduled to run', () => {
expect(deleteCorrectionRequestTransientFormDataJob.cronExpression).toEqual(process.env.RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE);
});

it('should have the correct description', () => {
expect(deleteCorrectionRequestTransientFormDataJob.description).toEqual('Delete record correction transient form data older than 1 day');
});

it('should call FeeRecordCorrectionRequestTransientFormDataRepo.delete', async () => {
// Act
await deleteCorrectionRequestTransientFormDataJob.task('manual');

// Assert
expect(mockDelete).toHaveBeenCalledTimes(1);

expect(mockDelete).toHaveBeenCalledWith({
lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')),
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { asString, CronSchedulerJob } from '@ukef/dtfs2-common';
import { FeeRecordCorrectionRequestTransientFormDataRepo } from '../../repositories/fee-record-correction-request-transient-form-data-repo';

const { RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE } = process.env;

/**
* Deletes record correction request transient form data more than 1 day old
*/
export const deleteCorrectionRequestTransientFormData = async (): Promise<void> => {
try {
console.info('Getting and deleting old transient record correction requests - deleteCorrectionRequestTransientFormDataJob CRON job');

await FeeRecordCorrectionRequestTransientFormDataRepo.deleteByLastUpdatedOlderThanOneDayAgo();
} catch (error) {
console.error('Error deleting old transient record correction requests - deleteCorrectionRequestTransientFormDataJob CRON job: %o', error);
}
};

export const deleteCorrectionRequestTransientFormDataJob: CronSchedulerJob = {
cronExpression: asString(RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE, 'RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE'),
description: 'Delete record correction transient form data older than 1 day',
task: deleteCorrectionRequestTransientFormData,
};
8 changes: 7 additions & 1 deletion dtfs-central-api/src/cron-scheduler-jobs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@ import { CronSchedulerJob } from '@ukef/dtfs2-common';
import { createUtilisationReportForBanksJob } from './create-utilisation-reports';
import { deleteCompleteAcbsDurableFunctionLogsJob } from './delete-acbs-durable-function-logs';
import { cancelDealJob } from './deal-cancellation/cancel-deal-job';
import { deleteCorrectionRequestTransientFormDataJob } from './delete-correction-request-transient-form-data';

export const cronSchedulerJobs: CronSchedulerJob[] = [createUtilisationReportForBanksJob, deleteCompleteAcbsDurableFunctionLogsJob, cancelDealJob];
export const cronSchedulerJobs: CronSchedulerJob[] = [
createUtilisationReportForBanksJob,
deleteCompleteAcbsDurableFunctionLogsJob,
cancelDealJob,
deleteCorrectionRequestTransientFormDataJob,
];
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SqlDbDataSource } from '@ukef/dtfs2-common/sql-db-connection';
import { FeeRecordCorrectionRequestTransientFormDataEntity } from '@ukef/dtfs2-common';
import { EntityManager } from 'typeorm';
import { EntityManager, LessThan } from 'typeorm';

/**
* Repository for managing fee record correction request transient form data.
Expand Down Expand Up @@ -34,6 +34,18 @@ export const FeeRecordCorrectionRequestTransientFormDataRepo = SqlDbDataSource.g
});
},

/**
* deletes the transient form data which is older than a day old
*/
async deleteByLastUpdatedOlderThanOneDayAgo(): Promise<void> {
const today = new Date();
const oneDayAgo = today.setDate(today.getDate() - 1);

await this.delete({
lastUpdatedAt: LessThan(new Date(oneDayAgo)),
});
},

withTransaction(transactionEntityManager: EntityManager) {
const transactionRepository = transactionEntityManager.getRepository(FeeRecordCorrectionRequestTransientFormDataEntity);

Expand Down

0 comments on commit fe2faaf

Please sign in to comment.