diff --git a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.test.ts b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.test.ts new file mode 100644 index 0000000000..2a589caa0f --- /dev/null +++ b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.test.ts @@ -0,0 +1,203 @@ +import { LessThan } from 'typeorm'; +import { deleteAllOldCorrectionTransientFormData, deleteAllOldCorrectionTransientFormDataJob } from '.'; +import { FeeRecordCorrectionRequestTransientFormDataRepo } from '../../repositories/fee-record-correction-request-transient-form-data-repo/fee-record-correction-request-transient-form-data.repo'; +import { FeeRecordCorrectionTransientFormDataRepo } from '../../repositories/fee-record-correction-transient-form-data-repo'; + +console.error = jest.fn(); + +describe('delete-correction-and-correction-request-transient-form-data', () => { + jest.mock('typeorm', () => ({ + LessThan: jest.fn(), + })); + + const mockCorrectionDelete = jest.fn(); + const mockCorrectionRequestDelete = jest.fn(); + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + describe('deleteAllOldCorrectionTransientFormData', () => { + beforeEach(() => { + jest.useFakeTimers().setSystemTime(new Date('2025-01-02 12:10:00')); + + FeeRecordCorrectionTransientFormDataRepo.delete = mockCorrectionDelete; + FeeRecordCorrectionRequestTransientFormDataRepo.delete = mockCorrectionRequestDelete; + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should delete "correction transient data" records older than one day', async () => { + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + const expectedDeletionCallArgs = { + lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')), + }; + + expect(mockCorrectionDelete).toHaveBeenCalledTimes(1); + expect(mockCorrectionDelete).toHaveBeenCalledWith(expectedDeletionCallArgs); + }); + + it('should delete "correction request transient data" records older than one day', async () => { + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + const expectedDeletionCallArgs = { + lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')), + }; + + expect(mockCorrectionRequestDelete).toHaveBeenCalledTimes(1); + expect(mockCorrectionRequestDelete).toHaveBeenCalledWith(expectedDeletionCallArgs); + }); + + it('should delete "correction transient data" records older than one day if it is the first day of the month', async () => { + // Arrange + jest.useFakeTimers().setSystemTime(new Date('2025-01-01 12:10:00')); + + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + const expectedDeletionCallArgs = { + lastUpdatedAt: LessThan(new Date('2024-12-31:12:10:00')), + }; + + expect(mockCorrectionDelete).toHaveBeenCalledTimes(1); + expect(mockCorrectionDelete).toHaveBeenCalledWith(expectedDeletionCallArgs); + }); + + it('should delete "correction request transient data" records older than one day if it is the first day of the month', async () => { + // Arrange + jest.useFakeTimers().setSystemTime(new Date('2025-01-01 12:10:00')); + + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + const expectedDeletionCallArgs = { + lastUpdatedAt: LessThan(new Date('2024-12-31:12:10:00')), + }; + + expect(mockCorrectionRequestDelete).toHaveBeenCalledTimes(1); + expect(mockCorrectionRequestDelete).toHaveBeenCalledWith(expectedDeletionCallArgs); + }); + + describe('when record correction transient data deletion fails', () => { + it('should throw an error', async () => { + // Arrange + const errorMessage = 'This is an error'; + const error = new Error(errorMessage); + + jest.mocked(mockCorrectionDelete).mockRejectedValue(error); + + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + expect(mockCorrectionDelete).toHaveBeenCalledTimes(1); + + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error).toHaveBeenCalledWith( + 'Error deleting old transient record correction form data - deleteCorrectionRequestTransientFormData CRON job: %o', + error, + ); + }); + + it('should still call record correction request transient data deletion', async () => { + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + expect(mockCorrectionRequestDelete).toHaveBeenCalledTimes(1); + }); + }); + + describe('when record correction request transient data deletion fails', () => { + it('should throw an error', async () => { + // Arrange + const errorMessage = 'This is an error'; + const error = new Error(errorMessage); + + jest.mocked(mockCorrectionRequestDelete).mockRejectedValue(error); + + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + expect(mockCorrectionRequestDelete).toHaveBeenCalledTimes(1); + + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error).toHaveBeenCalledWith( + 'Error deleting old transient record correction request form data - deleteCorrectionRequestTransientFormData CRON job: %o', + error, + ); + }); + + it('should still call record correction transient data deletion', async () => { + // Act + await deleteAllOldCorrectionTransientFormData(); + + // Assert + expect(mockCorrectionDelete).toHaveBeenCalledTimes(1); + }); + }); + }); + + describe('deleteRecordCorrectionRequestTransientFormDataJob', () => { + beforeEach(() => { + jest.useFakeTimers().setSystemTime(new Date('2025-01-02 12:10:00')); + + FeeRecordCorrectionTransientFormDataRepo.delete = mockCorrectionDelete; + FeeRecordCorrectionRequestTransientFormDataRepo.delete = mockCorrectionRequestDelete; + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should be scheduled to run', () => { + // Assert + expect(deleteAllOldCorrectionTransientFormDataJob.cronExpression).toEqual(process.env.RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE); + }); + + it('should have the correct description', () => { + // Assert + expect(deleteAllOldCorrectionTransientFormDataJob.description).toEqual( + 'Deletes record correction and record correction request transient form data older than 1 day', + ); + }); + + it('should call FeeRecordCorrectionTransientFormDataRepo.delete', async () => { + // Act + await deleteAllOldCorrectionTransientFormDataJob.task('manual'); + + // Assert + expect(mockCorrectionDelete).toHaveBeenCalledTimes(1); + + expect(mockCorrectionDelete).toHaveBeenCalledWith({ + lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')), + }); + }); + + it('should call FeeRecordCorrectionRequestTransientFormDataRepo.delete', async () => { + // Act + await deleteAllOldCorrectionTransientFormDataJob.task('manual'); + + // Assert + expect(mockCorrectionRequestDelete).toHaveBeenCalledTimes(1); + + expect(mockCorrectionRequestDelete).toHaveBeenCalledWith({ + lastUpdatedAt: LessThan(new Date('2025-01-01:12:10:00')), + }); + }); + }); +}); diff --git a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.ts b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.ts new file mode 100644 index 0000000000..6318693e37 --- /dev/null +++ b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-and-correction-request-transient-form-data/index.ts @@ -0,0 +1,30 @@ +import { asString, CronSchedulerJob } from '@ukef/dtfs2-common'; +import { FeeRecordCorrectionRequestTransientFormDataRepo } from '../../repositories/fee-record-correction-request-transient-form-data-repo'; +import { FeeRecordCorrectionTransientFormDataRepo } from '../../repositories/fee-record-correction-transient-form-data-repo'; + +const { RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE } = process.env; + +/** + * Deletes record correction and correction request transient form data more than 1 day old. + */ +export const deleteAllOldCorrectionTransientFormData = async (): Promise => { + console.info('Deleting old transient record corrections and correction requests - deleteCorrectionRequestTransientFormData CRON job'); + + try { + await FeeRecordCorrectionTransientFormDataRepo.deleteByLastUpdatedOlderThanOneDayAgo(); + } catch (error) { + console.error('Error deleting old transient record correction form data - deleteCorrectionRequestTransientFormData CRON job: %o', error); + } + + try { + await FeeRecordCorrectionRequestTransientFormDataRepo.deleteByLastUpdatedOlderThanOneDayAgo(); + } catch (error) { + console.error('Error deleting old transient record correction request form data - deleteCorrectionRequestTransientFormData CRON job: %o', error); + } +}; + +export const deleteAllOldCorrectionTransientFormDataJob: CronSchedulerJob = { + cronExpression: asString(RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE, 'RECORD_CORRECTION_TRANSIENT_FORM_DATA_DELETE_SCHEDULE'), + description: 'Deletes record correction and record correction request transient form data older than 1 day', + task: deleteAllOldCorrectionTransientFormData, +}; diff --git a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.test.ts b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.test.ts deleted file mode 100644 index 629cdb99dd..0000000000 --- a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -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')), - }); - }); - }); -}); diff --git a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.ts b/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.ts deleted file mode 100644 index 6eaf3234b6..0000000000 --- a/dtfs-central-api/src/cron-scheduler-jobs/delete-correction-request-transient-form-data/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -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 => { - 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, -}; diff --git a/dtfs-central-api/src/cron-scheduler-jobs/index.ts b/dtfs-central-api/src/cron-scheduler-jobs/index.ts index c6d9de4e43..1b4660ae25 100644 --- a/dtfs-central-api/src/cron-scheduler-jobs/index.ts +++ b/dtfs-central-api/src/cron-scheduler-jobs/index.ts @@ -2,11 +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'; +import { deleteAllOldCorrectionTransientFormDataJob } from './delete-correction-and-correction-request-transient-form-data'; export const cronSchedulerJobs: CronSchedulerJob[] = [ createUtilisationReportForBanksJob, deleteCompleteAcbsDurableFunctionLogsJob, cancelDealJob, - deleteCorrectionRequestTransientFormDataJob, + deleteAllOldCorrectionTransientFormDataJob, ]; diff --git a/dtfs-central-api/src/repositories/fee-record-correction-transient-form-data-repo/fee-record-correction-transient-form-data.repo.ts b/dtfs-central-api/src/repositories/fee-record-correction-transient-form-data-repo/fee-record-correction-transient-form-data.repo.ts index 58b6768674..ba75a5b7be 100644 --- a/dtfs-central-api/src/repositories/fee-record-correction-transient-form-data-repo/fee-record-correction-transient-form-data.repo.ts +++ b/dtfs-central-api/src/repositories/fee-record-correction-transient-form-data-repo/fee-record-correction-transient-form-data.repo.ts @@ -1,6 +1,6 @@ import { SqlDbDataSource } from '@ukef/dtfs2-common/sql-db-connection'; import { FeeRecordCorrectionTransientFormDataEntity } from '@ukef/dtfs2-common'; -import { EntityManager } from 'typeorm'; +import { EntityManager, LessThan } from 'typeorm'; /** * Repository for managing fee record correction transient form data. @@ -33,6 +33,18 @@ export const FeeRecordCorrectionTransientFormDataRepo = SqlDbDataSource.getRepos }); }, + /** + * Deletes transient fee record correction data that was last updated more than one day ago. + */ + async deleteByLastUpdatedOlderThanOneDayAgo(): Promise { + 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(FeeRecordCorrectionTransientFormDataEntity);