diff --git a/jest.config.ts b/jest.config.ts index 2eefb58..2d276a2 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -4,6 +4,7 @@ const config: Config = { preset: 'ts-jest', testEnvironment: 'node', testMatch: ['**/?(*.)+(spec|test).ts'], + setupFilesAfterEnv: ['/jest.setup.ts'], }; export default config; diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 0000000..0b26ac7 --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1,5 @@ +import { closeQueue } from './src/queue/queue'; + +afterAll(async () => { + await closeQueue(); +}); diff --git a/src/db/migrations/20250916103026-rename-isLinked-to-areSplitsValid.ts b/src/db/migrations/20250916103026-rename-isLinked-to-areSplitsValid.ts new file mode 100644 index 0000000..15e5be9 --- /dev/null +++ b/src/db/migrations/20250916103026-rename-isLinked-to-areSplitsValid.ts @@ -0,0 +1,30 @@ +import type { QueryInterface } from 'sequelize'; +import getSchema from '../../utils/getSchema'; + +export async function up({ context: sequelize }: any): Promise { + const schema = getSchema(); + const qi: QueryInterface = sequelize.getQueryInterface(); + + await qi.renameColumn( + { + schema, + tableName: 'linked_identities', + }, + 'is_linked', + 'are_splits_valid', + ); +} + +export async function down({ context: sequelize }: any): Promise { + const schema = getSchema(); + const qi: QueryInterface = sequelize.getQueryInterface(); + + await qi.renameColumn( + { + schema, + tableName: 'linked_identities', + }, + 'are_splits_valid', + 'is_linked', + ); +} diff --git a/src/eventHandlers/OwnerUpdatedEventHandler.ts b/src/eventHandlers/OwnerUpdatedEventHandler.ts index bb9872a..4e503a3 100644 --- a/src/eventHandlers/OwnerUpdatedEventHandler.ts +++ b/src/eventHandlers/OwnerUpdatedEventHandler.ts @@ -173,7 +173,10 @@ export default class OwnerUpdatedEventHandler extends EventHandlerBase<'OwnerUpd identityType: 'orcid', ownerAddress: owner, ownerAccountId, - isLinked: await validateLinkedIdentity(accountId, ownerAccountId), + areSplitsValid: await validateLinkedIdentity( + accountId, + ownerAccountId, + ), lastProcessedVersion: makeVersion(blockNumber, logIndex).toString(), }, }, @@ -189,7 +192,7 @@ export default class OwnerUpdatedEventHandler extends EventHandlerBase<'OwnerUpd // Update existing linked identity linkedIdentity.ownerAddress = owner; linkedIdentity.ownerAccountId = ownerAccountId; - linkedIdentity.isLinked = await validateLinkedIdentity( + linkedIdentity.areSplitsValid = await validateLinkedIdentity( accountId, linkedIdentity.ownerAccountId, ); diff --git a/src/eventHandlers/SplitsSetEvent/processLinkedIdentitySplits.ts b/src/eventHandlers/SplitsSetEvent/processLinkedIdentitySplits.ts index 71c3a5c..6d46a0e 100644 --- a/src/eventHandlers/SplitsSetEvent/processLinkedIdentitySplits.ts +++ b/src/eventHandlers/SplitsSetEvent/processLinkedIdentitySplits.ts @@ -46,7 +46,7 @@ export async function processLinkedIdentitySplits( `ORCID account ${accountId} has no owner set yet. Skipping validation and splits creation.`, ); - linkedIdentity.isLinked = false; + linkedIdentity.areSplitsValid = false; scopedLogger.bufferUpdate({ type: LinkedIdentityModel, @@ -105,7 +105,7 @@ export async function processLinkedIdentitySplits( ); } - linkedIdentity.isLinked = isLinked; + linkedIdentity.areSplitsValid = isLinked; scopedLogger.bufferUpdate({ type: LinkedIdentityModel, diff --git a/src/models/LinkedIdentityModel.ts b/src/models/LinkedIdentityModel.ts index aa09ac1..a16a93f 100644 --- a/src/models/LinkedIdentityModel.ts +++ b/src/models/LinkedIdentityModel.ts @@ -24,7 +24,7 @@ export default class LinkedIdentityModel extends Model< public declare identityType: LinkedIdentityType; public declare ownerAddress: Address | null; public declare ownerAccountId: AddressDriverId | null; - public declare isLinked: boolean; + public declare areSplitsValid: boolean; public declare lastProcessedVersion: string; public declare createdAt: CreationOptional; public declare updatedAt: CreationOptional; @@ -48,7 +48,7 @@ export default class LinkedIdentityModel extends Model< allowNull: true, type: DataTypes.STRING, }, - isLinked: { + areSplitsValid: { allowNull: false, type: DataTypes.BOOLEAN, defaultValue: false, diff --git a/src/queue/queue.ts b/src/queue/queue.ts index d250adf..d2e9784 100644 --- a/src/queue/queue.ts +++ b/src/queue/queue.ts @@ -45,4 +45,9 @@ eventProcessingQueue.on('job retrying', (job, err) => { logger.info(`♻️ [${job}] failed (will be retried): ${err.message}`); }); +export async function closeQueue(): Promise { + await eventProcessingQueue.close(); + redisClient.quit(); +} + export default eventProcessingQueue; diff --git a/src/utils/linkedIdentityUtils.ts b/src/utils/linkedIdentityUtils.ts index 929af4b..536bfcf 100644 --- a/src/utils/linkedIdentityUtils.ts +++ b/src/utils/linkedIdentityUtils.ts @@ -27,7 +27,7 @@ export async function ensureLinkedIdentityExists( identityType: 'orcid', ownerAddress: null, ownerAccountId: null, - isLinked: false, + areSplitsValid: false, lastProcessedVersion: makeVersion( ctx.blockNumber, ctx.logIndex, diff --git a/tests/eventHandlers/OwnerUpdatedEventHandler.test.ts b/tests/eventHandlers/OwnerUpdatedEventHandler.test.ts index d09df72..318f8d4 100644 --- a/tests/eventHandlers/OwnerUpdatedEventHandler.test.ts +++ b/tests/eventHandlers/OwnerUpdatedEventHandler.test.ts @@ -187,7 +187,7 @@ describe('OwnerUpdatedEventHandler', () => { identityType: 'orcid', ownerAddress: mockOwnerAddress, ownerAccountId: '123456789', - isLinked: false, + areSplitsValid: false, lastProcessedVersion: mockExpectedVersion, }, }); @@ -255,7 +255,7 @@ describe('OwnerUpdatedEventHandler', () => { // Assert expect(existingLinkedIdentity.ownerAddress).toBe(mockOwnerAddress); expect(existingLinkedIdentity.ownerAccountId).toBe('123456789'); - expect(existingLinkedIdentity.isLinked).toBe(true); // the mocked validateLinkedIdentity returns true. + expect(existingLinkedIdentity.areSplitsValid).toBe(true); // the mocked validateLinkedIdentity returns true. expect(existingLinkedIdentity.lastProcessedVersion).toBe( mockExpectedVersion, ); diff --git a/tests/eventHandlers/SplitsSetEvent/setLinkedIdentityFlag.test.ts b/tests/eventHandlers/SplitsSetEvent/setLinkedIdentityFlag.test.ts index 920bc33..06990a7 100644 --- a/tests/eventHandlers/SplitsSetEvent/setLinkedIdentityFlag.test.ts +++ b/tests/eventHandlers/SplitsSetEvent/setLinkedIdentityFlag.test.ts @@ -63,7 +63,7 @@ describe('processLinkedIdentitySplits', () => { jest.mocked(accountIdUtils.assertIsRepoDriverId); }); - it('should update isLinked flag when validation returns true and create splits record', async () => { + it('should update areSplitsValid flag when validation returns true and create splits record', async () => { (LinkedIdentityModel.findOne as jest.Mock).mockResolvedValue( mockLinkedIdentity, ); @@ -111,14 +111,14 @@ describe('processLinkedIdentitySplits', () => { }, }); - expect(mockLinkedIdentity.isLinked).toBe(true); + expect(mockLinkedIdentity.areSplitsValid).toBe(true); expect(mockLinkedIdentity.save).toHaveBeenCalledWith({ transaction: mockTransaction, }); }); - it('should update isLinked flag when validation returns false and NOT create splits', async () => { - mockLinkedIdentity.isLinked = true; + it('should update areSplitsValid flag when validation returns false and NOT create splits', async () => { + mockLinkedIdentity.areSplitsValid = true; (LinkedIdentityModel.findOne as jest.Mock).mockResolvedValue( mockLinkedIdentity, ); @@ -149,7 +149,7 @@ describe('processLinkedIdentitySplits', () => { expect(receiversRepository.createSplitReceiver).not.toHaveBeenCalled(); - expect(mockLinkedIdentity.isLinked).toBe(false); + expect(mockLinkedIdentity.areSplitsValid).toBe(false); expect(mockLinkedIdentity.save).toHaveBeenCalledWith({ transaction: mockTransaction, }); @@ -184,7 +184,7 @@ describe('processLinkedIdentitySplits', () => { ); }); - it('should always delete existing splits and recreate when isLinked is true', async () => { + it('should always delete existing splits and recreate when areSplitsValid is true', async () => { jest.mocked(SplitsReceiverModel.destroy).mockResolvedValue(1); (LinkedIdentityModel.findOne as jest.Mock).mockResolvedValue( @@ -210,7 +210,7 @@ describe('processLinkedIdentitySplits', () => { }); expect(receiversRepository.createSplitReceiver).toHaveBeenCalled(); - expect(mockLinkedIdentity.isLinked).toBe(true); + expect(mockLinkedIdentity.areSplitsValid).toBe(true); expect(mockLinkedIdentity.save).toHaveBeenCalledWith({ transaction: mockTransaction, }); diff --git a/tests/eventHandlers/SplitsSetEventHandler.test.ts b/tests/eventHandlers/SplitsSetEventHandler.test.ts index 2ff0f3f..21a6787 100644 --- a/tests/eventHandlers/SplitsSetEventHandler.test.ts +++ b/tests/eventHandlers/SplitsSetEventHandler.test.ts @@ -103,7 +103,7 @@ describe('SplitsSetEventHandler', () => { expect(setIsValidFlag).toHaveBeenCalled(); }); - test('should set isLinked flag for ORCID account', async () => { + test('should set areSplitsValid flag for ORCID account', async () => { // Arrange const orcidAccountId = '81320912658542974439730181977206773330805723773165208113981035642880'; // ORCID account