From 1a44811e16d3e0bb0650b2f9dbd8288c3f1e3313 Mon Sep 17 00:00:00 2001 From: Timo Erdelt Date: Tue, 16 Apr 2024 17:07:38 +0200 Subject: [PATCH 1/5] test: e2e tests for v2 dbs --- ...uidity-info-history-v2-error-db.service.ts | 2 +- ...uidity-info-history-importer-v2.service.ts | 6 +- ...ity-info-history-v2-db.service.e2e-spec.ts | 220 ++++++++++++++++++ ...fo-history-v2-error-db.service.e2e-spec.ts | 116 +++++++++ 4 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts create mode 100644 test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts diff --git a/src/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service.ts b/src/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service.ts index 18c7a88..eb76522 100644 --- a/src/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service.ts +++ b/src/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service.ts @@ -7,7 +7,7 @@ import { PrismaService } from '@/database/prisma.service'; export class PairLiquidityInfoHistoryV2ErrorDbService { constructor(private prisma: PrismaService) {} - getErrorByPairIdAndMicroBlockHashWithinHours( + getErrorWithinHours( pairId: number, microBlockHash: string, transactionHash: string, diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts index a773a07..3794516 100644 --- a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts @@ -11,7 +11,7 @@ import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-i import { PairLiquidityInfoHistoryV2ErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service'; import { bigIntToDecimal, decimalToBigInt } from '@/lib/utils'; -enum EventType { +export enum EventType { Sync = 'Sync', SwapTokens = 'SwapTokens', PairMint = 'PairMint', @@ -69,7 +69,7 @@ export class PairLiquidityInfoHistoryImporterV2Service { try { // If an error occurred for this pair recently, skip pair const error = - await this.pairLiquidityInfoHistoryErrorDb.getErrorByPairIdAndMicroBlockHashWithinHours( + await this.pairLiquidityInfoHistoryErrorDb.getErrorWithinHours( pairWithTokens.id, '', '', @@ -219,7 +219,7 @@ export class PairLiquidityInfoHistoryImporterV2Service { // If an error occurred for this log recently, skip block const error = - await this.pairLiquidityInfoHistoryErrorDb.getErrorByPairIdAndMicroBlockHashWithinHours( + await this.pairLiquidityInfoHistoryErrorDb.getErrorWithinHours( pairWithTokens.id, current.log.block_hash, current.log.call_tx_hash, diff --git a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts new file mode 100644 index 0000000..a258308 --- /dev/null +++ b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts @@ -0,0 +1,220 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { Pair, PairLiquidityInfoHistoryV2, Token } from '@prisma/client'; +import { Decimal } from '@prisma/client/runtime/library'; + +import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service'; +import { PrismaService } from '@/database/prisma.service'; +import { EventType } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; + +const token1: Token = { + id: 1, + address: 'ct_token1', + symbol: '1', + name: '1', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; +const token2: Token = { + id: 2, + address: 'ct_token2', + symbol: '2', + name: '2', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; +const token3: Token = { + id: 3, + address: 'ct_token3', + symbol: '3', + name: '3', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; +const pair1: Pair = { + id: 1, + address: 'ct_pair1', + t0: 1, + t1: 2, + synchronized: true, +}; +const pair2: Pair = { + id: 2, + address: 'ct_pair2', + t0: 2, + t1: 3, + synchronized: true, +}; +const pair3: Pair = { + id: 3, + address: 'ct_pair4', + t0: 2, + t1: 3, + synchronized: true, +}; +const historyEntry1: PairLiquidityInfoHistoryV2 = { + id: 1, + pairId: 1, + eventType: EventType.PairMint, + reserve0: new Decimal(1000), + reserve1: new Decimal(1000), + deltaReserve0: new Decimal(1000), + deltaReserve1: new Decimal(1000), + fiatPrice: new Decimal(0), + height: 100001, + microBlockHash: 'mh_entry1', + microBlockTime: 1000000000001n, + transactionHash: 'th_entry1', + transactionIndex: 100001n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; +const historyEntry2: PairLiquidityInfoHistoryV2 = { + id: 2, + pairId: 1, + eventType: EventType.SwapTokens, + reserve0: new Decimal(1050), + reserve1: new Decimal(950), + deltaReserve0: new Decimal(50), + deltaReserve1: new Decimal(-50), + fiatPrice: new Decimal(0), + height: 200002, + microBlockHash: 'mh_entry2', + microBlockTime: 2000000000002n, + transactionHash: 'th_entry2', + transactionIndex: 200002n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; +const historyEntry3: PairLiquidityInfoHistoryV2 = { + id: 3, + pairId: 2, + eventType: EventType.PairMint, + reserve0: new Decimal(1000), + reserve1: new Decimal(1000), + deltaReserve0: new Decimal(1000), + deltaReserve1: new Decimal(1000), + fiatPrice: new Decimal(0), + height: 300003, + microBlockHash: 'mh_entry3', + microBlockTime: 3000000000003n, + transactionHash: 'th_entry3', + transactionIndex: 300003n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; +const historyEntry4: PairLiquidityInfoHistoryV2 = { + id: 4, + pairId: 2, + eventType: EventType.SwapTokens, + reserve0: new Decimal(1050), + reserve1: new Decimal(950), + deltaReserve0: new Decimal(50), + deltaReserve1: new Decimal(-50), + fiatPrice: new Decimal(0), + height: 300003, + microBlockHash: 'mh_entry4', + microBlockTime: 3000000000003n, + transactionHash: 'th_entry4', + transactionIndex: 300003n, + logIndex: 2, + createdAt: new Date(), + updatedAt: new Date(), +}; + +describe('PairLiquidityInfoHistoryV2DbService', () => { + let service: PairLiquidityInfoHistoryV2DbService; + let prismaService: PrismaService; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PairLiquidityInfoHistoryV2DbService, PrismaService], + }).compile(); + + service = module.get( + PairLiquidityInfoHistoryV2DbService, + ); + prismaService = module.get(PrismaService); + }); + + beforeEach(async () => { + await prismaService.token.createMany({ data: [token1, token2, token3] }); + await prismaService.pair.createMany({ data: [pair1, pair2, pair3] }); + await prismaService.pairLiquidityInfoHistoryV2.createMany({ + data: [historyEntry1, historyEntry2, historyEntry3, historyEntry4], + }); + }); + + afterEach(async () => { + await prismaService.pairLiquidityInfoHistoryV2.deleteMany(); + await prismaService.pair.deleteMany(); + await prismaService.token.deleteMany(); + }); + + afterAll(async () => { + await prismaService.$disconnect(); + }); + + describe('upsert', () => { + it('should correctly upsert an existing entry', async () => { + const updatedEntry = { + pairId: 1, + eventType: EventType.PairBurn, + reserve0: new Decimal(500), + reserve1: new Decimal(500), + deltaReserve0: new Decimal(-500), + deltaReserve1: new Decimal(-500), + fiatPrice: new Decimal(0), + height: 200002, + microBlockHash: 'mh_entry2', + microBlockTime: 2000000000002n, + transactionHash: 'th_entry2', + transactionIndex: 200002n, + logIndex: 1, + }; + await service.upsert(updatedEntry); + const entry = await prismaService.pairLiquidityInfoHistoryV2.findFirst({ + where: { id: 2 }, + }); + expect(entry?.reserve0).toEqual(new Decimal(500)); + }); + + it('should correctly insert an new entry', async () => { + const newEntry = { + pairId: 1, + eventType: EventType.PairBurn, + reserve0: new Decimal(500), + reserve1: new Decimal(500), + deltaReserve0: new Decimal(-500), + deltaReserve1: new Decimal(-500), + fiatPrice: new Decimal(0), + height: 500005, + microBlockHash: 'mh_entry5', + microBlockTime: 5000000000005n, + transactionHash: 'th_entry5', + transactionIndex: 500005n, + logIndex: 1, + }; + await service.upsert(newEntry); + const entry = await service.getLastlySyncedLogByPairId(1); + expect(entry?.microBlockHash).toEqual('mh_entry5'); + }); + }); + + describe('getLastlySyncedLogByPairId', () => { + it('should correctly return the last synced log for a given pairId', async () => { + const result1 = await service.getLastlySyncedLogByPairId(1); + const result2 = await service.getLastlySyncedLogByPairId(2); + expect(result1?.id).toEqual(2); + expect(result2?.id).toEqual(4); + }); + }); +}); diff --git a/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts new file mode 100644 index 0000000..67a8a7b --- /dev/null +++ b/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts @@ -0,0 +1,116 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { Pair, PairLiquidityInfoHistoryV2Error, Token } from '@prisma/client'; + +import { PrismaService } from '@/database/prisma.service'; +import { PairLiquidityInfoHistoryV2ErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service'; + +const token1: Token = { + id: 1, + address: 'ct_token1', + symbol: '1', + name: '1', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; +const token2: Token = { + id: 2, + address: 'ct_token2', + symbol: '2', + name: '2', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; +const pair1: Pair = { + id: 1, + address: 'ct_pair1', + t0: 1, + t1: 2, + synchronized: true, +}; +const pair2: Pair = { + id: 2, + address: 'ct_pair2', + t0: 1, + t1: 2, + synchronized: true, +}; +const errorEntry1: PairLiquidityInfoHistoryV2Error = { + id: 1, + pairId: 1, + microBlockHash: '', + transactionHash: '', + logIndex: -1, + error: 'error_1', + timesOccurred: 1, + createdAt: new Date('2024-01-01 12:00:00.000'), + updatedAt: new Date('2024-01-01 12:00:00.000'), +}; +const errorEntry2: PairLiquidityInfoHistoryV2Error = { + id: 2, + pairId: 1, + microBlockHash: 'mh_1', + transactionHash: 'th_1', + logIndex: 1, + error: 'error_2', + timesOccurred: 1, + createdAt: new Date('2024-01-01 12:00:00.000'), + updatedAt: new Date('2024-01-01 12:00:00.000'), +}; + +describe('PairLiquidityInfoHistoryV2ErrorDbService', () => { + let service: PairLiquidityInfoHistoryV2ErrorDbService; + let prismaService: PrismaService; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PairLiquidityInfoHistoryV2ErrorDbService, PrismaService], + }).compile(); + + service = module.get( + PairLiquidityInfoHistoryV2ErrorDbService, + ); + prismaService = module.get(PrismaService); + }); + + beforeEach(async () => { + await prismaService.token.createMany({ data: [token1, token2] }); + await prismaService.pair.createMany({ data: [pair1, pair2] }); + await prismaService.pairLiquidityInfoHistoryV2Error.createMany({ + data: [errorEntry1, errorEntry2], + }); + jest.useFakeTimers().setSystemTime(new Date('2024-01-01 17:59:00.000')); + }); + + afterEach(async () => { + await prismaService.pairLiquidityInfoHistoryV2Error.deleteMany(); + await prismaService.pair.deleteMany(); + await prismaService.token.deleteMany(); + jest.useRealTimers(); + }); + + afterAll(async () => { + await prismaService.$disconnect(); + }); + + describe('getErrorWithinHours', () => { + it('should correctly return an error within a recent given time window in hours on pair basis', async () => { + jest.useFakeTimers().setSystemTime(new Date('2024-01-01 17:59:00.000')); + const result = await service.getErrorWithinHours(1, '', '', -1, 6); + expect(result?.id).toEqual(1); + }); + + it('should correctly return an error within a recent given time window in hours on log basis', async () => { + const result = await service.getErrorWithinHours(1, 'mh_1', 'th_1', 1, 6); + expect(result?.id).toEqual(2); + }); + + it('should not return errors older than the given time window in hours', async () => { + const result = await service.getErrorWithinHours(1, '', '', -1, 5); + expect(result).toBe(null); + }); + }); +}); From 7411148f1e53b039dd3cd6c5ed7774b6965f57ec Mon Sep 17 00:00:00 2001 From: Timo Erdelt Date: Wed, 17 Apr 2024 13:14:04 +0200 Subject: [PATCH 2/5] fix: db v2 e2e test --- ...ity-info-history-v2-db.service.e2e-spec.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts index a258308..0d827fe 100644 --- a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts +++ b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts @@ -58,7 +58,7 @@ const pair3: Pair = { synchronized: true, }; const historyEntry1: PairLiquidityInfoHistoryV2 = { - id: 1, + id: 111, pairId: 1, eventType: EventType.PairMint, reserve0: new Decimal(1000), @@ -76,7 +76,7 @@ const historyEntry1: PairLiquidityInfoHistoryV2 = { updatedAt: new Date(), }; const historyEntry2: PairLiquidityInfoHistoryV2 = { - id: 2, + id: 222, pairId: 1, eventType: EventType.SwapTokens, reserve0: new Decimal(1050), @@ -94,7 +94,7 @@ const historyEntry2: PairLiquidityInfoHistoryV2 = { updatedAt: new Date(), }; const historyEntry3: PairLiquidityInfoHistoryV2 = { - id: 3, + id: 333, pairId: 2, eventType: EventType.PairMint, reserve0: new Decimal(1000), @@ -112,7 +112,7 @@ const historyEntry3: PairLiquidityInfoHistoryV2 = { updatedAt: new Date(), }; const historyEntry4: PairLiquidityInfoHistoryV2 = { - id: 4, + id: 444, pairId: 2, eventType: EventType.SwapTokens, reserve0: new Decimal(1050), @@ -166,7 +166,7 @@ describe('PairLiquidityInfoHistoryV2DbService', () => { describe('upsert', () => { it('should correctly upsert an existing entry', async () => { const updatedEntry = { - pairId: 1, + pairId: historyEntry2.pairId, eventType: EventType.PairBurn, reserve0: new Decimal(500), reserve1: new Decimal(500), @@ -174,15 +174,15 @@ describe('PairLiquidityInfoHistoryV2DbService', () => { deltaReserve1: new Decimal(-500), fiatPrice: new Decimal(0), height: 200002, - microBlockHash: 'mh_entry2', + microBlockHash: historyEntry2.microBlockHash, microBlockTime: 2000000000002n, - transactionHash: 'th_entry2', + transactionHash: historyEntry2.transactionHash, transactionIndex: 200002n, - logIndex: 1, + logIndex: historyEntry2.logIndex, }; await service.upsert(updatedEntry); const entry = await prismaService.pairLiquidityInfoHistoryV2.findFirst({ - where: { id: 2 }, + where: { id: historyEntry2.id }, }); expect(entry?.reserve0).toEqual(new Decimal(500)); }); @@ -213,8 +213,8 @@ describe('PairLiquidityInfoHistoryV2DbService', () => { it('should correctly return the last synced log for a given pairId', async () => { const result1 = await service.getLastlySyncedLogByPairId(1); const result2 = await service.getLastlySyncedLogByPairId(2); - expect(result1?.id).toEqual(2); - expect(result2?.id).toEqual(4); + expect(result1?.id).toEqual(historyEntry2.id); + expect(result2?.id).toEqual(historyEntry4.id); }); }); }); From 3ada12156d1014ea24701686ac2f5b613ff0fa15 Mon Sep 17 00:00:00 2001 From: Timo Erdelt Date: Wed, 17 Apr 2024 15:55:54 +0200 Subject: [PATCH 3/5] test: unit tests for importerV2 --- ...y-info-history-importer-v2.service.spec.ts | 527 ++++++++++++++++++ ...uidity-info-history-importer-v2.service.ts | 4 +- ...fo-history-v2-error-db.service.e2e-spec.ts | 2 +- 3 files changed, 530 insertions(+), 3 deletions(-) create mode 100644 src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts new file mode 100644 index 0000000..8c03a64 --- /dev/null +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts @@ -0,0 +1,527 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { Contract } from '@/clients/mdw-http-client.model'; +import { MdwHttpClientService } from '@/clients/mdw-http-client.service'; +import { ContractAddress } from '@/clients/sdk-client.model'; +import { SdkClientService } from '@/clients/sdk-client.service'; +import { PairDbService } from '@/database/pair/pair-db.service'; +import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service'; +import { PairLiquidityInfoHistoryV2ErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service'; +import { bigIntToDecimal } from '@/lib/utils'; +import { + EventType, + PairLiquidityInfoHistoryImporterV2Service, +} from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; +import resetAllMocks = jest.resetAllMocks; + +// Mock data +const pair = { + id: 1, + address: 'ct_pair' as ContractAddress, + token0: { address: 'ct_token0' }, + token1: { address: 'ct_token1' }, +}; +const pairContract: Contract = { + aexn_type: '', + block_hash: 'mh_hash0', + contract: pair.address, + source_tx_hash: 'th_', + source_tx_type: '', + create_tx: {}, +}; +const initialMicroBlock = { + hash: pairContract.block_hash, + height: '10000', + time: '1000000000000', +}; +const contractLog1 = { + args: ['100', '100'], + block_hash: 'mh_hash1', + block_time: '1000000000001', + call_tx_hash: 'th_hash1', + call_txi: '10000001', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '10001', + log_idx: '1', +}; +const contractLog2 = { + args: ['123', '100', '100'], + block_hash: 'mh_hash1', + block_time: '1000000000001', + call_tx_hash: 'th_hash1', + call_txi: '10000001', + data: '', + event_hash: 'L2BEDU7I5T8OSEUPB61900P8FJR637OE4MC4A9875C390RMQHSN0====', // PairMint + height: '10001', + log_idx: '2', +}; +const contractLog3 = { + args: ['200', '200'], + block_hash: 'mh_hash2', + block_time: '2000000000002', + call_tx_hash: 'th_hash2', + call_txi: '20000002', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '20002', + log_idx: '1', +}; +const contractLog4 = { + args: ['201', '199'], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash3', + call_txi: '30000003', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '30003', + log_idx: '1', +}; +const contractLog5 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash3', + call_txi: '30000003', + data: '1|0|0|1', + event_hash: 'K39AB2I57LEUOUQ04LTEOMSJPJC3G9VGFRKVNJ5QLRMVCMDOPIMG====', // SwapTokens + height: '30003', + log_idx: '2', +}; +const contractLog6 = { + args: ['100', '100'], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '30003', + log_idx: '1', +}; +const contractLog7 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '101|99', + event_hash: 'OIS2ALGSJ03MTP2BR5RBFL1GOUGESRVPGE58LGM0MVG9K3VAFKUG====', // PairBurn + height: '30003', + log_idx: '2', +}; +const contractLog8 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '', + event_hash: 'non_relevant_event_hash', // Something else + height: '30003', + log_idx: '3', +}; + +const mockMdwClientService = { + getContract: jest.fn(), + getMicroBlock: jest.fn(), + getContractLogsUntilCondition: jest.fn(), +}; + +const mockPairDb = { getAll: jest.fn() }; + +const mockPairLiquidityInfoHistoryDb = { + getLastlySyncedLogByPairId: jest.fn(), + upsert: jest.fn(), +}; + +const mockPairLiquidityInfoHistoryErrorDb = { + getErrorWithinHours: jest.fn(), + upsert: jest.fn(), +}; + +describe('PairLiquidityInfoHistoryImporterV2Service', () => { + let service: PairLiquidityInfoHistoryImporterV2Service; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + PairLiquidityInfoHistoryImporterV2Service, + { provide: MdwHttpClientService, useValue: mockMdwClientService }, + { provide: PairDbService, useValue: mockPairDb }, + { + provide: PairLiquidityInfoHistoryV2DbService, + useValue: mockPairLiquidityInfoHistoryDb, + }, + { + provide: PairLiquidityInfoHistoryV2ErrorDbService, + useValue: mockPairLiquidityInfoHistoryErrorDb, + }, + SdkClientService, + ], + }).compile(); + service = module.get( + PairLiquidityInfoHistoryImporterV2Service, + ); + resetAllMocks(); + }); + + describe('import', () => { + it('should import liquidity correctly', async () => { + // Mock functions + mockPairDb.getAll.mockResolvedValue([pair]); + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + undefined, + ); + mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId + .mockResolvedValueOnce(undefined) + .mockResolvedValueOnce({ + reserve0: bigIntToDecimal(100n), + reserve1: bigIntToDecimal(100n), + }); + mockMdwClientService.getContract.mockResolvedValue(pairContract); + mockMdwClientService.getMicroBlock.mockResolvedValue(initialMicroBlock); + mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); + mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + contractLog1, + contractLog2, + contractLog3, + contractLog4, + contractLog5, + contractLog6, + contractLog7, + contractLog8, + ]); + + // Spies + const logSpy = jest.spyOn(service.logger, 'log'); + + // Start import + await service.import(); + + // Assertions + expect( + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours, + ).toHaveBeenCalledTimes(5); // Once for pair and 4 times for each inserted event + + expect(logSpy.mock.calls).toEqual([ + ['Started syncing pair liquidity info history.'], + ['Syncing liquidity info history for 1 pairs.'], + [`Inserted initial liquidity for pair ${pair.id} ${pair.address}.`], + [ + `Completed sync for pair ${pair.id} ${pair.address}. Synced 4 log(s).`, + ], + ['Finished liquidity info history sync for all pairs.'], + ]); + + expect(mockPairLiquidityInfoHistoryDb.upsert).toHaveBeenCalledTimes(5); + expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + [ + { + pairId: pair.id, + eventType: 'CreatePair', + reserve0: bigIntToDecimal(0n), + reserve1: bigIntToDecimal(0n), + deltaReserve0: bigIntToDecimal(0n), + deltaReserve1: bigIntToDecimal(0n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(initialMicroBlock.height), + microBlockHash: initialMicroBlock.hash, + microBlockTime: BigInt(initialMicroBlock.time), + transactionHash: pairContract.source_tx_hash, + transactionIndex: 0n, + logIndex: 0, + }, + ], + [ + { + pairId: pair.id, + eventType: EventType.PairMint, + reserve0: bigIntToDecimal(100n), + reserve1: bigIntToDecimal(100n), + deltaReserve0: bigIntToDecimal(100n), + deltaReserve1: bigIntToDecimal(100n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog2.height), + microBlockHash: contractLog2.block_hash, + microBlockTime: BigInt(contractLog2.block_time), + transactionHash: contractLog2.call_tx_hash, + transactionIndex: BigInt(contractLog2.call_txi), + logIndex: parseInt(contractLog2.log_idx), + }, + ], + [ + { + pairId: pair.id, + eventType: EventType.Sync, + reserve0: bigIntToDecimal(200n), + reserve1: bigIntToDecimal(200n), + deltaReserve0: bigIntToDecimal(100n), + deltaReserve1: bigIntToDecimal(100n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog3.height), + microBlockHash: contractLog3.block_hash, + microBlockTime: BigInt(contractLog3.block_time), + transactionHash: contractLog3.call_tx_hash, + transactionIndex: BigInt(contractLog3.call_txi), + logIndex: parseInt(contractLog3.log_idx), + }, + ], + [ + { + pairId: pair.id, + eventType: EventType.SwapTokens, + reserve0: bigIntToDecimal(201n), + reserve1: bigIntToDecimal(199n), + deltaReserve0: bigIntToDecimal(1n), + deltaReserve1: bigIntToDecimal(-1n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog5.height), + microBlockHash: contractLog5.block_hash, + microBlockTime: BigInt(contractLog5.block_time), + transactionHash: contractLog5.call_tx_hash, + transactionIndex: BigInt(contractLog5.call_txi), + logIndex: parseInt(contractLog5.log_idx), + }, + ], + [ + { + pairId: pair.id, + eventType: EventType.PairBurn, + reserve0: bigIntToDecimal(100n), + reserve1: bigIntToDecimal(100n), + deltaReserve0: bigIntToDecimal(-101n), + deltaReserve1: bigIntToDecimal(-99n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog7.height), + microBlockHash: contractLog7.block_hash, + microBlockTime: BigInt(contractLog7.block_time), + transactionHash: contractLog7.call_tx_hash, + transactionIndex: BigInt(contractLog7.call_txi), + logIndex: parseInt(contractLog5.log_idx), + }, + ], + ]); + }); + + it('should skip a pair if there was a recent error', async () => { + // Mock functions + mockPairDb.getAll.mockResolvedValue([pair]); + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + { + id: 1, + pairId: 1, + microBlockHash: '', + transactionHash: '', + logIndex: -1, + error: 'error', + timesOccurred: 1, + createdAt: Date.now(), + updatedAt: Date.now(), + }, + ); + + // Spies + const logSpy = jest.spyOn(service.logger, 'log'); + + // Start import + await service.import(); + + // Assertions + expect(logSpy.mock.calls).toEqual([ + ['Started syncing pair liquidity info history.'], + ['Syncing liquidity info history for 1 pairs.'], + [`Skipped pair ${pair.id} due to recent error.`], + ['Finished liquidity info history sync for all pairs.'], + ]); + }); + + it('should skip a log if there was a recent error', async () => { + // Mock functions + mockPairDb.getAll.mockResolvedValue([pair]); + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours + .mockResolvedValueOnce(undefined) + .mockResolvedValueOnce({ + id: 1, + pairId: 1, + microBlockHash: contractLog1.block_hash, + transactionHash: contractLog1.call_tx_hash, + logIndex: contractLog1.log_idx, + error: 'error', + timesOccurred: 1, + createdAt: Date.now(), + updatedAt: Date.now(), + }) + .mockResolvedValueOnce(undefined); + mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId.mockResolvedValue( + {}, + ); + mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); + mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + contractLog1, + contractLog2, + contractLog4, + contractLog5, + ]); + + // Spies + const logSpy = jest.spyOn(service.logger, 'log'); + + // Start import + await service.import(); + + // Assertions + expect( + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours, + ).toHaveBeenCalledTimes(3); // Once for pair and 2 times for each event + + expect(logSpy.mock.calls).toEqual([ + ['Started syncing pair liquidity info history.'], + ['Syncing liquidity info history for 1 pairs.'], + [ + `Skipped log with block hash ${contractLog1.block_hash} tx hash ${contractLog1.call_tx_hash} and log index ${contractLog1.log_idx} due to recent error.`, + ], + [ + `Completed sync for pair ${pair.id} ${pair.address}. Synced 1 log(s).`, + ], + ['Finished liquidity info history sync for all pairs.'], + ]); + + expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + [ + { + pairId: pair.id, + eventType: EventType.SwapTokens, + reserve0: bigIntToDecimal(201n), + reserve1: bigIntToDecimal(199n), + deltaReserve0: bigIntToDecimal(1n), + deltaReserve1: bigIntToDecimal(-1n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog5.height), + microBlockHash: contractLog5.block_hash, + microBlockTime: BigInt(contractLog5.block_time), + transactionHash: contractLog5.call_tx_hash, + transactionIndex: BigInt(contractLog5.call_txi), + logIndex: parseInt(contractLog5.log_idx), + }, + ], + ]); + }); + + it('should catch and insert an error on pair level', async () => { + const error = { + pairId: pair.id, + microBlockHash: '', + transactionHash: '', + logIndex: -1, + error: 'Error: error', + }; + + // Mock functions + mockPairDb.getAll.mockResolvedValue([pair]); + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + undefined, + ); + mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId.mockResolvedValue( + {}, + ); + mockMdwClientService.getContractLogsUntilCondition.mockRejectedValue( + new Error('error'), + ); + mockPairLiquidityInfoHistoryErrorDb.upsert.mockResolvedValue(null); + + // Spies + const logSpy = jest.spyOn(service.logger, 'log'); + const errorSpy = jest.spyOn(service.logger, 'error'); + + // Start import + await service.import(); + + // Assertions + expect(mockPairLiquidityInfoHistoryErrorDb.upsert).toHaveBeenCalledWith( + error, + ); + + expect(logSpy.mock.calls).toEqual([ + ['Started syncing pair liquidity info history.'], + ['Syncing liquidity info history for 1 pairs.'], + ['Finished liquidity info history sync for all pairs.'], + ]); + + expect(errorSpy.mock.calls).toEqual([ + [`Skipped pair. ${JSON.stringify(error)}`], + ]); + }); + + it('should catch and insert an error on log level', async () => { + const error = { + pairId: pair.id, + microBlockHash: contractLog3.block_hash, + transactionHash: contractLog3.call_tx_hash, + logIndex: parseInt(contractLog3.log_idx), + error: 'Error: error', + }; + + // Mock functions + mockPairDb.getAll.mockResolvedValue([pair]); + mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + undefined, + ); + mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId + .mockResolvedValueOnce({}) + .mockRejectedValueOnce(new Error('error')) + .mockRejectedValueOnce(undefined); + mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + contractLog3, + contractLog4, + contractLog5, + ]); + mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); + mockPairLiquidityInfoHistoryErrorDb.upsert.mockResolvedValue(null); + const logSpy = jest.spyOn(service.logger, 'log'); + const errorSpy = jest.spyOn(service.logger, 'error'); + + // Start import + await service.import(); + + // Assertions + expect(mockPairLiquidityInfoHistoryErrorDb.upsert).toHaveBeenCalledWith( + error, + ); + + expect(logSpy.mock.calls).toEqual([ + ['Started syncing pair liquidity info history.'], + ['Syncing liquidity info history for 1 pairs.'], + [ + `Completed sync for pair ${pair.id} ${pair.address}. Synced 1 log(s).`, + ], + ['Finished liquidity info history sync for all pairs.'], + ]); + + expect(errorSpy.mock.calls).toEqual([ + [`Skipped log. ${JSON.stringify(error)}`], + ]); + + expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + [ + { + pairId: pair.id, + eventType: EventType.SwapTokens, + reserve0: bigIntToDecimal(201n), + reserve1: bigIntToDecimal(199n), + deltaReserve0: bigIntToDecimal(1n), + deltaReserve1: bigIntToDecimal(-1n), + fiatPrice: bigIntToDecimal(0n), + height: parseInt(contractLog5.height), + microBlockHash: contractLog5.block_hash, + microBlockTime: BigInt(contractLog5.block_time), + transactionHash: contractLog5.call_tx_hash, + transactionIndex: BigInt(contractLog5.call_txi), + logIndex: parseInt(contractLog5.log_idx), + }, + ], + ]); + }); + }); +}); diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts index 3794516..e1a87cd 100644 --- a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.ts @@ -57,7 +57,7 @@ export class PairLiquidityInfoHistoryImporterV2Service { 'L2BEDU7I5T8OSEUPB61900P8FJR637OE4MC4A9875C390RMQHSN0===='; async import() { - this.logger.log(`Started syncing pair liquidity info history.`); + this.logger.log('Started syncing pair liquidity info history.'); // Fetch all pairs from DB const pairsWithTokens = await this.pairDb.getAll(); @@ -228,7 +228,7 @@ export class PairLiquidityInfoHistoryImporterV2Service { ); if (error) { this.logger.log( - `Skipped log with block hash ${current.log.block_hash} and log index ${current.log.log_idx} due to recent error.`, + `Skipped log with block hash ${current.log.block_hash} tx hash ${current.log.call_tx_hash} and log index ${current.log.log_idx} due to recent error.`, ); continue; } diff --git a/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts index 67a8a7b..c261278 100644 --- a/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts +++ b/test/e2e/pair-liquidity-info-history-v2-error-db.service.e2e-spec.ts @@ -1,8 +1,8 @@ import { Test, TestingModule } from '@nestjs/testing'; import { Pair, PairLiquidityInfoHistoryV2Error, Token } from '@prisma/client'; -import { PrismaService } from '@/database/prisma.service'; import { PairLiquidityInfoHistoryV2ErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service'; +import { PrismaService } from '@/database/prisma.service'; const token1: Token = { id: 1, From 13cc31e3608656b62e8a73fdb2156cbba0b36c67 Mon Sep 17 00:00:00 2001 From: Timo Erdelt Date: Thu, 18 Apr 2024 13:54:51 +0200 Subject: [PATCH 4/5] test: re-organize mock data and utils --- src/clients/mdw-ws-client.service.spec.ts | 2 +- ...y-info-history-importer-v2.service.spec.ts | 234 +++++----------- ...dity-info-history-importer.service.spec.ts | 19 +- src/tasks/pair-sync/pair-sync.service.spec.ts | 8 +- ...ity-info-history-v2-db.service.e2e-spec.ts | 137 +--------- test/e2e/pair-sync.service.e2e-spec.ts | 6 +- test/e2e/pairs.e2e-spec.ts | 8 +- test/e2e/tokens.e2e-spec.ts | 8 +- .../context-mock-data.ts | 2 +- .../pair-liquidity-info-history-mock-data.ts | 257 ++++++++++++++++++ .../subscription-event-mock-data.ts | 0 .../context-mock.spec.ts | 4 +- test/{test-utils => utils}/context-mock.ts | 0 test/{test-utils => utils}/db-helper.ts | 0 test/{test-utils => utils}/env-mock.ts | 0 test/{test-utils => utils}/utils.ts | 0 16 files changed, 367 insertions(+), 318 deletions(-) rename test/{test-utils => mock-data}/context-mock-data.ts (96%) create mode 100644 test/mock-data/pair-liquidity-info-history-mock-data.ts rename test/{test-utils => mock-data}/subscription-event-mock-data.ts (100%) rename test/{test-utils => utils}/context-mock.spec.ts (96%) rename test/{test-utils => utils}/context-mock.ts (100%) rename test/{test-utils => utils}/db-helper.ts (100%) rename test/{test-utils => utils}/env-mock.ts (100%) rename test/{test-utils => utils}/utils.ts (100%) diff --git a/src/clients/mdw-ws-client.service.spec.ts b/src/clients/mdw-ws-client.service.spec.ts index e661989..7de93db 100644 --- a/src/clients/mdw-ws-client.service.spec.ts +++ b/src/clients/mdw-ws-client.service.spec.ts @@ -7,7 +7,7 @@ import { Callbacks, MdwWsClientService } from '@/clients/mdw-ws-client.service'; import { objSubEv, txSubEv, -} from '@/test/test-utils/subscription-event-mock-data'; +} from '@/test/mock-data/subscription-event-mock-data'; describe('MdwWsClientService', () => { let service: MdwWsClientService; diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts index 8c03a64..53ea315 100644 --- a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts @@ -1,8 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { Contract } from '@/clients/mdw-http-client.model'; import { MdwHttpClientService } from '@/clients/mdw-http-client.service'; -import { ContractAddress } from '@/clients/sdk-client.model'; import { SdkClientService } from '@/clients/sdk-client.service'; import { PairDbService } from '@/database/pair/pair-db.service'; import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service'; @@ -13,117 +11,21 @@ import { PairLiquidityInfoHistoryImporterV2Service, } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; import resetAllMocks = jest.resetAllMocks; - -// Mock data -const pair = { - id: 1, - address: 'ct_pair' as ContractAddress, - token0: { address: 'ct_token0' }, - token1: { address: 'ct_token1' }, -}; -const pairContract: Contract = { - aexn_type: '', - block_hash: 'mh_hash0', - contract: pair.address, - source_tx_hash: 'th_', - source_tx_type: '', - create_tx: {}, -}; -const initialMicroBlock = { - hash: pairContract.block_hash, - height: '10000', - time: '1000000000000', -}; -const contractLog1 = { - args: ['100', '100'], - block_hash: 'mh_hash1', - block_time: '1000000000001', - call_tx_hash: 'th_hash1', - call_txi: '10000001', - data: '', - event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync - height: '10001', - log_idx: '1', -}; -const contractLog2 = { - args: ['123', '100', '100'], - block_hash: 'mh_hash1', - block_time: '1000000000001', - call_tx_hash: 'th_hash1', - call_txi: '10000001', - data: '', - event_hash: 'L2BEDU7I5T8OSEUPB61900P8FJR637OE4MC4A9875C390RMQHSN0====', // PairMint - height: '10001', - log_idx: '2', -}; -const contractLog3 = { - args: ['200', '200'], - block_hash: 'mh_hash2', - block_time: '2000000000002', - call_tx_hash: 'th_hash2', - call_txi: '20000002', - data: '', - event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync - height: '20002', - log_idx: '1', -}; -const contractLog4 = { - args: ['201', '199'], - block_hash: 'mh_hash3', - block_time: '3000000000003', - call_tx_hash: 'th_hash3', - call_txi: '30000003', - data: '', - event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync - height: '30003', - log_idx: '1', -}; -const contractLog5 = { - args: [], - block_hash: 'mh_hash3', - block_time: '3000000000003', - call_tx_hash: 'th_hash3', - call_txi: '30000003', - data: '1|0|0|1', - event_hash: 'K39AB2I57LEUOUQ04LTEOMSJPJC3G9VGFRKVNJ5QLRMVCMDOPIMG====', // SwapTokens - height: '30003', - log_idx: '2', -}; -const contractLog6 = { - args: ['100', '100'], - block_hash: 'mh_hash3', - block_time: '3000000000003', - call_tx_hash: 'th_hash4', - call_txi: '40000004', - data: '', - event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync - height: '30003', - log_idx: '1', -}; -const contractLog7 = { - args: [], - block_hash: 'mh_hash3', - block_time: '3000000000003', - call_tx_hash: 'th_hash4', - call_txi: '40000004', - data: '101|99', - event_hash: 'OIS2ALGSJ03MTP2BR5RBFL1GOUGESRVPGE58LGM0MVG9K3VAFKUG====', // PairBurn - height: '30003', - log_idx: '2', -}; -const contractLog8 = { - args: [], - block_hash: 'mh_hash3', - block_time: '3000000000003', - call_tx_hash: 'th_hash4', - call_txi: '40000004', - data: '', - event_hash: 'non_relevant_event_hash', // Something else - height: '30003', - log_idx: '3', -}; - -const mockMdwClientService = { +import { + contractLog1, + contractLog2, + contractLog3, + contractLog4, + contractLog5, + contractLog6, + contractLog7, + contractLog8, + initialMicroBlock, + pairContract, + pairWithTokens, +} from '@/test/mock-data/pair-liquidity-info-history-mock-data'; + +const mockMdwClient = { getContract: jest.fn(), getMicroBlock: jest.fn(), getContractLogsUntilCondition: jest.fn(), @@ -131,12 +33,12 @@ const mockMdwClientService = { const mockPairDb = { getAll: jest.fn() }; -const mockPairLiquidityInfoHistoryDb = { +const mockPairLiquidityInfoHistoryV2Db = { getLastlySyncedLogByPairId: jest.fn(), upsert: jest.fn(), }; -const mockPairLiquidityInfoHistoryErrorDb = { +const mockPairLiquidityInfoHistoryV2ErrorDb = { getErrorWithinHours: jest.fn(), upsert: jest.fn(), }; @@ -148,15 +50,15 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { const module: TestingModule = await Test.createTestingModule({ providers: [ PairLiquidityInfoHistoryImporterV2Service, - { provide: MdwHttpClientService, useValue: mockMdwClientService }, + { provide: MdwHttpClientService, useValue: mockMdwClient }, { provide: PairDbService, useValue: mockPairDb }, { provide: PairLiquidityInfoHistoryV2DbService, - useValue: mockPairLiquidityInfoHistoryDb, + useValue: mockPairLiquidityInfoHistoryV2Db, }, { provide: PairLiquidityInfoHistoryV2ErrorDbService, - useValue: mockPairLiquidityInfoHistoryErrorDb, + useValue: mockPairLiquidityInfoHistoryV2ErrorDb, }, SdkClientService, ], @@ -170,20 +72,20 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { describe('import', () => { it('should import liquidity correctly', async () => { // Mock functions - mockPairDb.getAll.mockResolvedValue([pair]); - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + mockPairDb.getAll.mockResolvedValue([pairWithTokens]); + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours.mockResolvedValue( undefined, ); - mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId + mockPairLiquidityInfoHistoryV2Db.getLastlySyncedLogByPairId .mockResolvedValueOnce(undefined) .mockResolvedValueOnce({ reserve0: bigIntToDecimal(100n), reserve1: bigIntToDecimal(100n), }); - mockMdwClientService.getContract.mockResolvedValue(pairContract); - mockMdwClientService.getMicroBlock.mockResolvedValue(initialMicroBlock); - mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); - mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + mockMdwClient.getContract.mockResolvedValue(pairContract); + mockMdwClient.getMicroBlock.mockResolvedValue(initialMicroBlock); + mockPairLiquidityInfoHistoryV2Db.upsert.mockResolvedValue(null); + mockMdwClient.getContractLogsUntilCondition.mockResolvedValue([ contractLog1, contractLog2, contractLog3, @@ -202,24 +104,26 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { // Assertions expect( - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours, + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours, ).toHaveBeenCalledTimes(5); // Once for pair and 4 times for each inserted event expect(logSpy.mock.calls).toEqual([ ['Started syncing pair liquidity info history.'], ['Syncing liquidity info history for 1 pairs.'], - [`Inserted initial liquidity for pair ${pair.id} ${pair.address}.`], [ - `Completed sync for pair ${pair.id} ${pair.address}. Synced 4 log(s).`, + `Inserted initial liquidity for pair ${pairWithTokens.id} ${pairWithTokens.address}.`, + ], + [ + `Completed sync for pair ${pairWithTokens.id} ${pairWithTokens.address}. Synced 4 log(s).`, ], ['Finished liquidity info history sync for all pairs.'], ]); - expect(mockPairLiquidityInfoHistoryDb.upsert).toHaveBeenCalledTimes(5); - expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + expect(mockPairLiquidityInfoHistoryV2Db.upsert).toHaveBeenCalledTimes(5); + expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: 'CreatePair', reserve0: bigIntToDecimal(0n), reserve1: bigIntToDecimal(0n), @@ -236,7 +140,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ], [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.PairMint, reserve0: bigIntToDecimal(100n), reserve1: bigIntToDecimal(100n), @@ -253,7 +157,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ], [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.Sync, reserve0: bigIntToDecimal(200n), reserve1: bigIntToDecimal(200n), @@ -270,7 +174,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ], [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.SwapTokens, reserve0: bigIntToDecimal(201n), reserve1: bigIntToDecimal(199n), @@ -287,7 +191,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ], [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.PairBurn, reserve0: bigIntToDecimal(100n), reserve1: bigIntToDecimal(100n), @@ -307,8 +211,8 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { it('should skip a pair if there was a recent error', async () => { // Mock functions - mockPairDb.getAll.mockResolvedValue([pair]); - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + mockPairDb.getAll.mockResolvedValue([pairWithTokens]); + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours.mockResolvedValue( { id: 1, pairId: 1, @@ -332,15 +236,15 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { expect(logSpy.mock.calls).toEqual([ ['Started syncing pair liquidity info history.'], ['Syncing liquidity info history for 1 pairs.'], - [`Skipped pair ${pair.id} due to recent error.`], + [`Skipped pair ${pairWithTokens.id} due to recent error.`], ['Finished liquidity info history sync for all pairs.'], ]); }); it('should skip a log if there was a recent error', async () => { // Mock functions - mockPairDb.getAll.mockResolvedValue([pair]); - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours + mockPairDb.getAll.mockResolvedValue([pairWithTokens]); + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours .mockResolvedValueOnce(undefined) .mockResolvedValueOnce({ id: 1, @@ -354,11 +258,11 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { updatedAt: Date.now(), }) .mockResolvedValueOnce(undefined); - mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId.mockResolvedValue( + mockPairLiquidityInfoHistoryV2Db.getLastlySyncedLogByPairId.mockResolvedValue( {}, ); - mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); - mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + mockPairLiquidityInfoHistoryV2Db.upsert.mockResolvedValue(null); + mockMdwClient.getContractLogsUntilCondition.mockResolvedValue([ contractLog1, contractLog2, contractLog4, @@ -373,7 +277,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { // Assertions expect( - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours, + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours, ).toHaveBeenCalledTimes(3); // Once for pair and 2 times for each event expect(logSpy.mock.calls).toEqual([ @@ -383,15 +287,15 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { `Skipped log with block hash ${contractLog1.block_hash} tx hash ${contractLog1.call_tx_hash} and log index ${contractLog1.log_idx} due to recent error.`, ], [ - `Completed sync for pair ${pair.id} ${pair.address}. Synced 1 log(s).`, + `Completed sync for pair ${pairWithTokens.id} ${pairWithTokens.address}. Synced 1 log(s).`, ], ['Finished liquidity info history sync for all pairs.'], ]); - expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.SwapTokens, reserve0: bigIntToDecimal(201n), reserve1: bigIntToDecimal(199n), @@ -411,7 +315,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { it('should catch and insert an error on pair level', async () => { const error = { - pairId: pair.id, + pairId: pairWithTokens.id, microBlockHash: '', transactionHash: '', logIndex: -1, @@ -419,17 +323,17 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { }; // Mock functions - mockPairDb.getAll.mockResolvedValue([pair]); - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + mockPairDb.getAll.mockResolvedValue([pairWithTokens]); + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours.mockResolvedValue( undefined, ); - mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId.mockResolvedValue( + mockPairLiquidityInfoHistoryV2Db.getLastlySyncedLogByPairId.mockResolvedValue( {}, ); - mockMdwClientService.getContractLogsUntilCondition.mockRejectedValue( + mockMdwClient.getContractLogsUntilCondition.mockRejectedValue( new Error('error'), ); - mockPairLiquidityInfoHistoryErrorDb.upsert.mockResolvedValue(null); + mockPairLiquidityInfoHistoryV2ErrorDb.upsert.mockResolvedValue(null); // Spies const logSpy = jest.spyOn(service.logger, 'log'); @@ -439,7 +343,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { await service.import(); // Assertions - expect(mockPairLiquidityInfoHistoryErrorDb.upsert).toHaveBeenCalledWith( + expect(mockPairLiquidityInfoHistoryV2ErrorDb.upsert).toHaveBeenCalledWith( error, ); @@ -456,7 +360,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { it('should catch and insert an error on log level', async () => { const error = { - pairId: pair.id, + pairId: pairWithTokens.id, microBlockHash: contractLog3.block_hash, transactionHash: contractLog3.call_tx_hash, logIndex: parseInt(contractLog3.log_idx), @@ -464,21 +368,21 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { }; // Mock functions - mockPairDb.getAll.mockResolvedValue([pair]); - mockPairLiquidityInfoHistoryErrorDb.getErrorWithinHours.mockResolvedValue( + mockPairDb.getAll.mockResolvedValue([pairWithTokens]); + mockPairLiquidityInfoHistoryV2ErrorDb.getErrorWithinHours.mockResolvedValue( undefined, ); - mockPairLiquidityInfoHistoryDb.getLastlySyncedLogByPairId + mockPairLiquidityInfoHistoryV2Db.getLastlySyncedLogByPairId .mockResolvedValueOnce({}) .mockRejectedValueOnce(new Error('error')) .mockRejectedValueOnce(undefined); - mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + mockMdwClient.getContractLogsUntilCondition.mockResolvedValue([ contractLog3, contractLog4, contractLog5, ]); - mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); - mockPairLiquidityInfoHistoryErrorDb.upsert.mockResolvedValue(null); + mockPairLiquidityInfoHistoryV2Db.upsert.mockResolvedValue(null); + mockPairLiquidityInfoHistoryV2ErrorDb.upsert.mockResolvedValue(null); const logSpy = jest.spyOn(service.logger, 'log'); const errorSpy = jest.spyOn(service.logger, 'error'); @@ -486,7 +390,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { await service.import(); // Assertions - expect(mockPairLiquidityInfoHistoryErrorDb.upsert).toHaveBeenCalledWith( + expect(mockPairLiquidityInfoHistoryV2ErrorDb.upsert).toHaveBeenCalledWith( error, ); @@ -494,7 +398,7 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ['Started syncing pair liquidity info history.'], ['Syncing liquidity info history for 1 pairs.'], [ - `Completed sync for pair ${pair.id} ${pair.address}. Synced 1 log(s).`, + `Completed sync for pair ${pairWithTokens.id} ${pairWithTokens.address}. Synced 1 log(s).`, ], ['Finished liquidity info history sync for all pairs.'], ]); @@ -503,10 +407,10 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { [`Skipped log. ${JSON.stringify(error)}`], ]); - expect(mockPairLiquidityInfoHistoryDb.upsert.mock.calls).toEqual([ + expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ [ { - pairId: pair.id, + pairId: pairWithTokens.id, eventType: EventType.SwapTokens, reserve0: bigIntToDecimal(201n), reserve1: bigIntToDecimal(199n), diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service.spec.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service.spec.ts index 6be13f4..1d4a976 100644 --- a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service.spec.ts +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service.spec.ts @@ -9,7 +9,7 @@ import { PairLiquidityInfoHistoryDbService } from '@/database/pair-liquidity-inf import { PairLiquidityInfoHistoryErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-error-db.service'; import { PairLiquidityInfoHistoryImporterService } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer.service'; -const mockMdwClientService = { +const mockMdwClient = { getContract: jest.fn(), getMicroBlock: jest.fn(), getContractLogsUntilCondition: jest.fn(), @@ -38,7 +38,7 @@ describe('PairLiquidityInfoHistoryImporterService', () => { providers: [ PairLiquidityInfoHistoryImporterService, SdkClientService, - { provide: MdwHttpClientService, useValue: mockMdwClientService }, + { provide: MdwHttpClientService, useValue: mockMdwClient }, { provide: PairDbService, useValue: mockPairDb }, { provide: PairLiquidityInfoHistoryDbService, @@ -96,17 +96,18 @@ describe('PairLiquidityInfoHistoryImporterService', () => { mockPairLiquidityInfoHistoryDb.getLastlySyncedBlockByPairId.mockReturnValue( undefined, ); - mockMdwClientService.getContract.mockResolvedValue(pair1Contract); - mockMdwClientService.getMicroBlock.mockResolvedValue(initialMicroBlock); + mockMdwClient.getContract.mockResolvedValue(pair1Contract); + mockMdwClient.getMicroBlock.mockResolvedValue(initialMicroBlock); mockPairLiquidityInfoHistoryDb.upsert.mockResolvedValue(null); - mockMdwClientService.getContractLogsUntilCondition.mockResolvedValue([ + mockMdwClient.getContractLogsUntilCondition.mockResolvedValue([ pairContractLog1, pairContractLog2, ]); - mockMdwClientService.getContractBalancesAtMicroBlockHash.mockResolvedValue( - [{ amount: '1' }, { amount: '1' }], - ); - mockMdwClientService.getAccountBalanceForContractAtMicroBlockHash.mockResolvedValue( + mockMdwClient.getContractBalancesAtMicroBlockHash.mockResolvedValue([ + { amount: '1' }, + { amount: '1' }, + ]); + mockMdwClient.getAccountBalanceForContractAtMicroBlockHash.mockResolvedValue( { amount: '1' }, ); jest.spyOn(service.logger, 'log'); diff --git a/src/tasks/pair-sync/pair-sync.service.spec.ts b/src/tasks/pair-sync/pair-sync.service.spec.ts index 0a41108..7b82b23 100644 --- a/src/tasks/pair-sync/pair-sync.service.spec.ts +++ b/src/tasks/pair-sync/pair-sync.service.spec.ts @@ -9,14 +9,14 @@ import { PairDbService } from '@/database/pair/pair-db.service'; import { TokenDbService } from '@/database/token/token-db.service'; import { Context } from '@/tasks/pair-sync/pair-sync.model'; import { PairSyncService } from '@/tasks/pair-sync/pair-sync.service'; -import { mockContext } from '@/test/test-utils/context-mock'; -import * as data from '@/test/test-utils/context-mock-data'; -import { mockupEnvVars, TEST_NET_VARS } from '@/test/test-utils/env-mock'; +import { mockContext } from '@/test/utils/context-mock'; +import * as data from '@/test/mock-data/context-mock-data'; +import { mockupEnvVars, TEST_NET_VARS } from '@/test/utils/env-mock'; import { objSubEv, swapEvent, swapTxInfo, -} from '@/test/test-utils/subscription-event-mock-data'; +} from '@/test/mock-data/subscription-event-mock-data'; describe('PairSyncService', () => { let service: PairSyncService; diff --git a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts index 0d827fe..70a6c50 100644 --- a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts +++ b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts @@ -1,134 +1,21 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { Pair, PairLiquidityInfoHistoryV2, Token } from '@prisma/client'; import { Decimal } from '@prisma/client/runtime/library'; import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service'; import { PrismaService } from '@/database/prisma.service'; import { EventType } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; - -const token1: Token = { - id: 1, - address: 'ct_token1', - symbol: '1', - name: '1', - decimals: 18, - malformed: false, - noContract: false, - listed: false, -}; -const token2: Token = { - id: 2, - address: 'ct_token2', - symbol: '2', - name: '2', - decimals: 18, - malformed: false, - noContract: false, - listed: false, -}; -const token3: Token = { - id: 3, - address: 'ct_token3', - symbol: '3', - name: '3', - decimals: 18, - malformed: false, - noContract: false, - listed: false, -}; -const pair1: Pair = { - id: 1, - address: 'ct_pair1', - t0: 1, - t1: 2, - synchronized: true, -}; -const pair2: Pair = { - id: 2, - address: 'ct_pair2', - t0: 2, - t1: 3, - synchronized: true, -}; -const pair3: Pair = { - id: 3, - address: 'ct_pair4', - t0: 2, - t1: 3, - synchronized: true, -}; -const historyEntry1: PairLiquidityInfoHistoryV2 = { - id: 111, - pairId: 1, - eventType: EventType.PairMint, - reserve0: new Decimal(1000), - reserve1: new Decimal(1000), - deltaReserve0: new Decimal(1000), - deltaReserve1: new Decimal(1000), - fiatPrice: new Decimal(0), - height: 100001, - microBlockHash: 'mh_entry1', - microBlockTime: 1000000000001n, - transactionHash: 'th_entry1', - transactionIndex: 100001n, - logIndex: 1, - createdAt: new Date(), - updatedAt: new Date(), -}; -const historyEntry2: PairLiquidityInfoHistoryV2 = { - id: 222, - pairId: 1, - eventType: EventType.SwapTokens, - reserve0: new Decimal(1050), - reserve1: new Decimal(950), - deltaReserve0: new Decimal(50), - deltaReserve1: new Decimal(-50), - fiatPrice: new Decimal(0), - height: 200002, - microBlockHash: 'mh_entry2', - microBlockTime: 2000000000002n, - transactionHash: 'th_entry2', - transactionIndex: 200002n, - logIndex: 1, - createdAt: new Date(), - updatedAt: new Date(), -}; -const historyEntry3: PairLiquidityInfoHistoryV2 = { - id: 333, - pairId: 2, - eventType: EventType.PairMint, - reserve0: new Decimal(1000), - reserve1: new Decimal(1000), - deltaReserve0: new Decimal(1000), - deltaReserve1: new Decimal(1000), - fiatPrice: new Decimal(0), - height: 300003, - microBlockHash: 'mh_entry3', - microBlockTime: 3000000000003n, - transactionHash: 'th_entry3', - transactionIndex: 300003n, - logIndex: 1, - createdAt: new Date(), - updatedAt: new Date(), -}; -const historyEntry4: PairLiquidityInfoHistoryV2 = { - id: 444, - pairId: 2, - eventType: EventType.SwapTokens, - reserve0: new Decimal(1050), - reserve1: new Decimal(950), - deltaReserve0: new Decimal(50), - deltaReserve1: new Decimal(-50), - fiatPrice: new Decimal(0), - height: 300003, - microBlockHash: 'mh_entry4', - microBlockTime: 3000000000003n, - transactionHash: 'th_entry4', - transactionIndex: 300003n, - logIndex: 2, - createdAt: new Date(), - updatedAt: new Date(), -}; +import { + historyEntry1, + historyEntry2, + historyEntry3, + historyEntry4, + pair1, + pair2, + pair3, + token1, + token2, + token3, +} from '@/test/mock-data/pair-liquidity-info-history-mock-data'; describe('PairLiquidityInfoHistoryV2DbService', () => { let service: PairLiquidityInfoHistoryV2DbService; diff --git a/test/e2e/pair-sync.service.e2e-spec.ts b/test/e2e/pair-sync.service.e2e-spec.ts index 6dc11be..b8cab20 100644 --- a/test/e2e/pair-sync.service.e2e-spec.ts +++ b/test/e2e/pair-sync.service.e2e-spec.ts @@ -7,9 +7,9 @@ import { PairDbService } from '@/database/pair/pair-db.service'; import { PrismaService } from '@/database/prisma.service'; import { TokenDbService } from '@/database/token/token-db.service'; import { PairSyncService } from '@/tasks/pair-sync/pair-sync.service'; -import { mockContext } from '@/test/test-utils/context-mock'; -import * as data from '@/test/test-utils/context-mock-data'; -import { cleanDb } from '@/test/test-utils/db-helper'; +import { mockContext } from '@/test/utils/context-mock'; +import * as data from '@/test/mock-data/context-mock-data'; +import { cleanDb } from '@/test/utils/db-helper'; // Testing method // 1. before all create a common context diff --git a/test/e2e/pairs.e2e-spec.ts b/test/e2e/pairs.e2e-spec.ts index a869e57..af92308 100644 --- a/test/e2e/pairs.e2e-spec.ts +++ b/test/e2e/pairs.e2e-spec.ts @@ -10,10 +10,10 @@ import { PairDbService } from '@/database/pair/pair-db.service'; import { PrismaService } from '@/database/prisma.service'; import { TokenDbService } from '@/database/token/token-db.service'; import { PairSyncService } from '@/tasks/pair-sync/pair-sync.service'; -import { mockContext } from '@/test/test-utils/context-mock'; -import * as data from '@/test/test-utils/context-mock-data'; -import { cleanDb, listToken } from '@/test/test-utils/db-helper'; -import { sortByAddress } from '@/test/test-utils/utils'; +import { mockContext } from '@/test/utils/context-mock'; +import * as data from '@/test/mock-data/context-mock-data'; +import { cleanDb, listToken } from '@/test/utils/db-helper'; +import { sortByAddress } from '@/test/utils/utils'; // Testing method // before all diff --git a/test/e2e/tokens.e2e-spec.ts b/test/e2e/tokens.e2e-spec.ts index 41bcc2d..c2a2e96 100644 --- a/test/e2e/tokens.e2e-spec.ts +++ b/test/e2e/tokens.e2e-spec.ts @@ -12,10 +12,10 @@ import { PrismaService } from '@/database/prisma.service'; import { TokenDbService } from '@/database/token/token-db.service'; import { nonNullable } from '@/lib/utils'; import { PairSyncService } from '@/tasks/pair-sync/pair-sync.service'; -import { mockContext } from '@/test/test-utils/context-mock'; -import * as data from '@/test/test-utils/context-mock-data'; -import { cleanDb, listToken } from '@/test/test-utils/db-helper'; -import { sortByAddress } from '@/test/test-utils/utils'; +import { mockContext } from '@/test/utils/context-mock'; +import * as data from '@/test/mock-data/context-mock-data'; +import { cleanDb, listToken } from '@/test/utils/db-helper'; +import { sortByAddress } from '@/test/utils/utils'; // Testing method // before all diff --git a/test/test-utils/context-mock-data.ts b/test/mock-data/context-mock-data.ts similarity index 96% rename from test/test-utils/context-mock-data.ts rename to test/mock-data/context-mock-data.ts index f359764..e7da33b 100644 --- a/test/test-utils/context-mock-data.ts +++ b/test/mock-data/context-mock-data.ts @@ -1,5 +1,5 @@ import { ContractAddress } from '@/clients/sdk-client.model'; -import { ContextData } from '@/test/test-utils/context-mock'; +import { ContextData } from '@/test/utils/context-mock'; const tokens = [ { diff --git a/test/mock-data/pair-liquidity-info-history-mock-data.ts b/test/mock-data/pair-liquidity-info-history-mock-data.ts new file mode 100644 index 0000000..f9ebdee --- /dev/null +++ b/test/mock-data/pair-liquidity-info-history-mock-data.ts @@ -0,0 +1,257 @@ +import { Pair, PairLiquidityInfoHistoryV2, Token } from '@prisma/client'; +import { Decimal } from '@prisma/client/runtime/library'; + +import { Contract } from '@/clients/mdw-http-client.model'; +import { ContractAddress } from '@/clients/sdk-client.model'; +import { EventType } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; + +export const token1: Token = { + id: 1, + address: 'ct_token1', + symbol: '1', + name: '1', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; + +export const token2: Token = { + id: 2, + address: 'ct_token2', + symbol: '2', + name: '2', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; + +export const token3: Token = { + id: 3, + address: 'ct_token3', + symbol: '3', + name: '3', + decimals: 18, + malformed: false, + noContract: false, + listed: false, +}; + +export const pair1: Pair = { + id: 1, + address: 'ct_pair1', + t0: 1, + t1: 2, + synchronized: true, +}; + +export const pair2: Pair = { + id: 2, + address: 'ct_pair2', + t0: 2, + t1: 3, + synchronized: true, +}; + +export const pair3: Pair = { + id: 3, + address: 'ct_pair4', + t0: 2, + t1: 3, + synchronized: true, +}; + +export const historyEntry1: PairLiquidityInfoHistoryV2 = { + id: 111, + pairId: 1, + eventType: EventType.PairMint, + reserve0: new Decimal(1000), + reserve1: new Decimal(1000), + deltaReserve0: new Decimal(1000), + deltaReserve1: new Decimal(1000), + fiatPrice: new Decimal(0), + height: 100001, + microBlockHash: 'mh_entry1', + microBlockTime: 1000000000001n, + transactionHash: 'th_entry1', + transactionIndex: 100001n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; + +export const historyEntry2: PairLiquidityInfoHistoryV2 = { + id: 222, + pairId: 1, + eventType: EventType.SwapTokens, + reserve0: new Decimal(1050), + reserve1: new Decimal(950), + deltaReserve0: new Decimal(50), + deltaReserve1: new Decimal(-50), + fiatPrice: new Decimal(0), + height: 200002, + microBlockHash: 'mh_entry2', + microBlockTime: 2000000000002n, + transactionHash: 'th_entry2', + transactionIndex: 200002n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; + +export const historyEntry3: PairLiquidityInfoHistoryV2 = { + id: 333, + pairId: 2, + eventType: EventType.PairMint, + reserve0: new Decimal(1000), + reserve1: new Decimal(1000), + deltaReserve0: new Decimal(1000), + deltaReserve1: new Decimal(1000), + fiatPrice: new Decimal(0), + height: 300003, + microBlockHash: 'mh_entry3', + microBlockTime: 3000000000003n, + transactionHash: 'th_entry3', + transactionIndex: 300003n, + logIndex: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; + +export const historyEntry4: PairLiquidityInfoHistoryV2 = { + id: 444, + pairId: 2, + eventType: EventType.SwapTokens, + reserve0: new Decimal(1050), + reserve1: new Decimal(950), + deltaReserve0: new Decimal(50), + deltaReserve1: new Decimal(-50), + fiatPrice: new Decimal(0), + height: 300003, + microBlockHash: 'mh_entry4', + microBlockTime: 3000000000003n, + transactionHash: 'th_entry4', + transactionIndex: 300003n, + logIndex: 2, + createdAt: new Date(), + updatedAt: new Date(), +}; + +export const pairWithTokens = { + id: 1, + address: 'ct_pair' as ContractAddress, + token0: { address: 'ct_token0' }, + token1: { address: 'ct_token1' }, +}; + +export const pairContract: Contract = { + aexn_type: '', + block_hash: 'mh_hash0', + contract: pairWithTokens.address, + source_tx_hash: 'th_', + source_tx_type: '', + create_tx: {}, +}; + +export const initialMicroBlock = { + hash: pairContract.block_hash, + height: '10000', + time: '1000000000000', +}; + +export const contractLog1 = { + args: ['100', '100'], + block_hash: 'mh_hash1', + block_time: '1000000000001', + call_tx_hash: 'th_hash1', + call_txi: '10000001', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '10001', + log_idx: '1', +}; + +export const contractLog2 = { + args: ['123', '100', '100'], + block_hash: 'mh_hash1', + block_time: '1000000000001', + call_tx_hash: 'th_hash1', + call_txi: '10000001', + data: '', + event_hash: 'L2BEDU7I5T8OSEUPB61900P8FJR637OE4MC4A9875C390RMQHSN0====', // PairMint + height: '10001', + log_idx: '2', +}; + +export const contractLog3 = { + args: ['200', '200'], + block_hash: 'mh_hash2', + block_time: '2000000000002', + call_tx_hash: 'th_hash2', + call_txi: '20000002', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '20002', + log_idx: '1', +}; + +export const contractLog4 = { + args: ['201', '199'], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash3', + call_txi: '30000003', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '30003', + log_idx: '1', +}; + +export const contractLog5 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash3', + call_txi: '30000003', + data: '1|0|0|1', + event_hash: 'K39AB2I57LEUOUQ04LTEOMSJPJC3G9VGFRKVNJ5QLRMVCMDOPIMG====', // SwapTokens + height: '30003', + log_idx: '2', +}; + +export const contractLog6 = { + args: ['100', '100'], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '', + event_hash: '6O232NLB36RGK54HEJPVDFJVCSIVFV29KPORC07CSSDARM7LV4L0====', // Sync + height: '30003', + log_idx: '1', +}; + +export const contractLog7 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '101|99', + event_hash: 'OIS2ALGSJ03MTP2BR5RBFL1GOUGESRVPGE58LGM0MVG9K3VAFKUG====', // PairBurn + height: '30003', + log_idx: '2', +}; + +export const contractLog8 = { + args: [], + block_hash: 'mh_hash3', + block_time: '3000000000003', + call_tx_hash: 'th_hash4', + call_txi: '40000004', + data: '', + event_hash: 'non_relevant_event_hash', // Something else + height: '30003', + log_idx: '3', +}; diff --git a/test/test-utils/subscription-event-mock-data.ts b/test/mock-data/subscription-event-mock-data.ts similarity index 100% rename from test/test-utils/subscription-event-mock-data.ts rename to test/mock-data/subscription-event-mock-data.ts diff --git a/test/test-utils/context-mock.spec.ts b/test/utils/context-mock.spec.ts similarity index 96% rename from test/test-utils/context-mock.spec.ts rename to test/utils/context-mock.spec.ts index 828b9cb..dae0f5a 100644 --- a/test/test-utils/context-mock.spec.ts +++ b/test/utils/context-mock.spec.ts @@ -6,8 +6,8 @@ import { ContextData, mockContext, mockupContractMethod, -} from '@/test/test-utils/context-mock'; -import * as data from '@/test/test-utils/context-mock-data'; +} from '@/test/utils/context-mock'; +import * as data from '@/test/mock-data/context-mock-data'; describe('Context', () => { it('sample mockup', async () => { diff --git a/test/test-utils/context-mock.ts b/test/utils/context-mock.ts similarity index 100% rename from test/test-utils/context-mock.ts rename to test/utils/context-mock.ts diff --git a/test/test-utils/db-helper.ts b/test/utils/db-helper.ts similarity index 100% rename from test/test-utils/db-helper.ts rename to test/utils/db-helper.ts diff --git a/test/test-utils/env-mock.ts b/test/utils/env-mock.ts similarity index 100% rename from test/test-utils/env-mock.ts rename to test/utils/env-mock.ts diff --git a/test/test-utils/utils.ts b/test/utils/utils.ts similarity index 100% rename from test/test-utils/utils.ts rename to test/utils/utils.ts From 4a4db5d4e58e7e84a7a1c0b8c59cb107b0819264 Mon Sep 17 00:00:00 2001 From: Timo Erdelt Date: Thu, 18 Apr 2024 14:33:49 +0200 Subject: [PATCH 5/5] test: feedback: introduce jest snapshots --- ...o-history-importer-v2.service.spec.ts.snap | 135 +++++++++++++++ ...y-info-history-importer-v2.service.spec.ts | 158 ++---------------- ...nfo-history-v2-db.service.e2e-spec.ts.snap | 20 +++ ...ity-info-history-v2-db.service.e2e-spec.ts | 5 +- 4 files changed, 172 insertions(+), 146 deletions(-) create mode 100644 src/tasks/pair-liquidity-info-history-importer/__snapshots__/pair-liquidity-info-history-importer-v2.service.spec.ts.snap create mode 100644 test/e2e/__snapshots__/pair-liquidity-info-history-v2-db.service.e2e-spec.ts.snap diff --git a/src/tasks/pair-liquidity-info-history-importer/__snapshots__/pair-liquidity-info-history-importer-v2.service.spec.ts.snap b/src/tasks/pair-liquidity-info-history-importer/__snapshots__/pair-liquidity-info-history-importer-v2.service.spec.ts.snap new file mode 100644 index 0000000..73dc336 --- /dev/null +++ b/src/tasks/pair-liquidity-info-history-importer/__snapshots__/pair-liquidity-info-history-importer-v2.service.spec.ts.snap @@ -0,0 +1,135 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PairLiquidityInfoHistoryImporterV2Service import should import liquidity correctly 1`] = ` +[ + [ + { + "deltaReserve0": "0", + "deltaReserve1": "0", + "eventType": "CreatePair", + "fiatPrice": "0", + "height": 10000, + "logIndex": 0, + "microBlockHash": "mh_hash0", + "microBlockTime": 1000000000000n, + "pairId": 1, + "reserve0": "0", + "reserve1": "0", + "transactionHash": "th_", + "transactionIndex": 0n, + }, + ], + [ + { + "deltaReserve0": "100", + "deltaReserve1": "100", + "eventType": "PairMint", + "fiatPrice": "0", + "height": 10001, + "logIndex": 2, + "microBlockHash": "mh_hash1", + "microBlockTime": 1000000000001n, + "pairId": 1, + "reserve0": "100", + "reserve1": "100", + "transactionHash": "th_hash1", + "transactionIndex": 10000001n, + }, + ], + [ + { + "deltaReserve0": "100", + "deltaReserve1": "100", + "eventType": "Sync", + "fiatPrice": "0", + "height": 20002, + "logIndex": 1, + "microBlockHash": "mh_hash2", + "microBlockTime": 2000000000002n, + "pairId": 1, + "reserve0": "200", + "reserve1": "200", + "transactionHash": "th_hash2", + "transactionIndex": 20000002n, + }, + ], + [ + { + "deltaReserve0": "1", + "deltaReserve1": "-1", + "eventType": "SwapTokens", + "fiatPrice": "0", + "height": 30003, + "logIndex": 2, + "microBlockHash": "mh_hash3", + "microBlockTime": 3000000000003n, + "pairId": 1, + "reserve0": "201", + "reserve1": "199", + "transactionHash": "th_hash3", + "transactionIndex": 30000003n, + }, + ], + [ + { + "deltaReserve0": "-101", + "deltaReserve1": "-99", + "eventType": "PairBurn", + "fiatPrice": "0", + "height": 30003, + "logIndex": 2, + "microBlockHash": "mh_hash3", + "microBlockTime": 3000000000003n, + "pairId": 1, + "reserve0": "100", + "reserve1": "100", + "transactionHash": "th_hash4", + "transactionIndex": 40000004n, + }, + ], +] +`; + +exports[`PairLiquidityInfoHistoryImporterV2Service import should skip a log if there was a recent error 1`] = ` +[ + [ + { + "deltaReserve0": "1", + "deltaReserve1": "-1", + "eventType": "SwapTokens", + "fiatPrice": "0", + "height": 30003, + "logIndex": 2, + "microBlockHash": "mh_hash3", + "microBlockTime": 3000000000003n, + "pairId": 1, + "reserve0": "201", + "reserve1": "199", + "transactionHash": "th_hash3", + "transactionIndex": 30000003n, + }, + ], +] +`; + +exports[`PairLiquidityInfoHistoryImporterV2Service import should catch and insert an error on log level 1`] = ` +[ + [ + { + "deltaReserve0": "1", + "deltaReserve1": "-1", + "eventType": "SwapTokens", + "fiatPrice": "0", + "height": 30003, + "logIndex": 2, + "microBlockHash": "mh_hash3", + "microBlockTime": 3000000000003n, + "pairId": 1, + "reserve0": "201", + "reserve1": "199", + "transactionHash": "th_hash3", + "transactionIndex": 30000003n, + }, + ], +] +`; diff --git a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts index 53ea315..41ddf1c 100644 --- a/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts +++ b/src/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service.spec.ts @@ -6,10 +6,7 @@ import { PairDbService } from '@/database/pair/pair-db.service'; import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service'; import { PairLiquidityInfoHistoryV2ErrorDbService } from '@/database/pair-liquidity-info-history-error/pair-liquidity-info-history-v2-error-db.service'; import { bigIntToDecimal } from '@/lib/utils'; -import { - EventType, - PairLiquidityInfoHistoryImporterV2Service, -} from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; +import { PairLiquidityInfoHistoryImporterV2Service } from '@/tasks/pair-liquidity-info-history-importer/pair-liquidity-info-history-importer-v2.service'; import resetAllMocks = jest.resetAllMocks; import { contractLog1, @@ -45,6 +42,8 @@ const mockPairLiquidityInfoHistoryV2ErrorDb = { describe('PairLiquidityInfoHistoryImporterV2Service', () => { let service: PairLiquidityInfoHistoryImporterV2Service; + let logSpy: jest.SpyInstance; + let errorSpy: jest.SpyInstance; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -66,6 +65,8 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { service = module.get( PairLiquidityInfoHistoryImporterV2Service, ); + logSpy = jest.spyOn(service.logger, 'log'); + errorSpy = jest.spyOn(service.logger, 'error'); resetAllMocks(); }); @@ -96,9 +97,6 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { contractLog8, ]); - // Spies - const logSpy = jest.spyOn(service.logger, 'log'); - // Start import await service.import(); @@ -120,93 +118,9 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ]); expect(mockPairLiquidityInfoHistoryV2Db.upsert).toHaveBeenCalledTimes(5); - expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ - [ - { - pairId: pairWithTokens.id, - eventType: 'CreatePair', - reserve0: bigIntToDecimal(0n), - reserve1: bigIntToDecimal(0n), - deltaReserve0: bigIntToDecimal(0n), - deltaReserve1: bigIntToDecimal(0n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(initialMicroBlock.height), - microBlockHash: initialMicroBlock.hash, - microBlockTime: BigInt(initialMicroBlock.time), - transactionHash: pairContract.source_tx_hash, - transactionIndex: 0n, - logIndex: 0, - }, - ], - [ - { - pairId: pairWithTokens.id, - eventType: EventType.PairMint, - reserve0: bigIntToDecimal(100n), - reserve1: bigIntToDecimal(100n), - deltaReserve0: bigIntToDecimal(100n), - deltaReserve1: bigIntToDecimal(100n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog2.height), - microBlockHash: contractLog2.block_hash, - microBlockTime: BigInt(contractLog2.block_time), - transactionHash: contractLog2.call_tx_hash, - transactionIndex: BigInt(contractLog2.call_txi), - logIndex: parseInt(contractLog2.log_idx), - }, - ], - [ - { - pairId: pairWithTokens.id, - eventType: EventType.Sync, - reserve0: bigIntToDecimal(200n), - reserve1: bigIntToDecimal(200n), - deltaReserve0: bigIntToDecimal(100n), - deltaReserve1: bigIntToDecimal(100n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog3.height), - microBlockHash: contractLog3.block_hash, - microBlockTime: BigInt(contractLog3.block_time), - transactionHash: contractLog3.call_tx_hash, - transactionIndex: BigInt(contractLog3.call_txi), - logIndex: parseInt(contractLog3.log_idx), - }, - ], - [ - { - pairId: pairWithTokens.id, - eventType: EventType.SwapTokens, - reserve0: bigIntToDecimal(201n), - reserve1: bigIntToDecimal(199n), - deltaReserve0: bigIntToDecimal(1n), - deltaReserve1: bigIntToDecimal(-1n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog5.height), - microBlockHash: contractLog5.block_hash, - microBlockTime: BigInt(contractLog5.block_time), - transactionHash: contractLog5.call_tx_hash, - transactionIndex: BigInt(contractLog5.call_txi), - logIndex: parseInt(contractLog5.log_idx), - }, - ], - [ - { - pairId: pairWithTokens.id, - eventType: EventType.PairBurn, - reserve0: bigIntToDecimal(100n), - reserve1: bigIntToDecimal(100n), - deltaReserve0: bigIntToDecimal(-101n), - deltaReserve1: bigIntToDecimal(-99n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog7.height), - microBlockHash: contractLog7.block_hash, - microBlockTime: BigInt(contractLog7.block_time), - transactionHash: contractLog7.call_tx_hash, - transactionIndex: BigInt(contractLog7.call_txi), - logIndex: parseInt(contractLog5.log_idx), - }, - ], - ]); + expect( + mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls, + ).toMatchSnapshot(); }); it('should skip a pair if there was a recent error', async () => { @@ -226,9 +140,6 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { }, ); - // Spies - const logSpy = jest.spyOn(service.logger, 'log'); - // Start import await service.import(); @@ -269,9 +180,6 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { contractLog5, ]); - // Spies - const logSpy = jest.spyOn(service.logger, 'log'); - // Start import await service.import(); @@ -292,25 +200,9 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ['Finished liquidity info history sync for all pairs.'], ]); - expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ - [ - { - pairId: pairWithTokens.id, - eventType: EventType.SwapTokens, - reserve0: bigIntToDecimal(201n), - reserve1: bigIntToDecimal(199n), - deltaReserve0: bigIntToDecimal(1n), - deltaReserve1: bigIntToDecimal(-1n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog5.height), - microBlockHash: contractLog5.block_hash, - microBlockTime: BigInt(contractLog5.block_time), - transactionHash: contractLog5.call_tx_hash, - transactionIndex: BigInt(contractLog5.call_txi), - logIndex: parseInt(contractLog5.log_idx), - }, - ], - ]); + expect( + mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls, + ).toMatchSnapshot(); }); it('should catch and insert an error on pair level', async () => { @@ -335,10 +227,6 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ); mockPairLiquidityInfoHistoryV2ErrorDb.upsert.mockResolvedValue(null); - // Spies - const logSpy = jest.spyOn(service.logger, 'log'); - const errorSpy = jest.spyOn(service.logger, 'error'); - // Start import await service.import(); @@ -383,8 +271,6 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { ]); mockPairLiquidityInfoHistoryV2Db.upsert.mockResolvedValue(null); mockPairLiquidityInfoHistoryV2ErrorDb.upsert.mockResolvedValue(null); - const logSpy = jest.spyOn(service.logger, 'log'); - const errorSpy = jest.spyOn(service.logger, 'error'); // Start import await service.import(); @@ -407,25 +293,9 @@ describe('PairLiquidityInfoHistoryImporterV2Service', () => { [`Skipped log. ${JSON.stringify(error)}`], ]); - expect(mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls).toEqual([ - [ - { - pairId: pairWithTokens.id, - eventType: EventType.SwapTokens, - reserve0: bigIntToDecimal(201n), - reserve1: bigIntToDecimal(199n), - deltaReserve0: bigIntToDecimal(1n), - deltaReserve1: bigIntToDecimal(-1n), - fiatPrice: bigIntToDecimal(0n), - height: parseInt(contractLog5.height), - microBlockHash: contractLog5.block_hash, - microBlockTime: BigInt(contractLog5.block_time), - transactionHash: contractLog5.call_tx_hash, - transactionIndex: BigInt(contractLog5.call_txi), - logIndex: parseInt(contractLog5.log_idx), - }, - ], - ]); + expect( + mockPairLiquidityInfoHistoryV2Db.upsert.mock.calls, + ).toMatchSnapshot(); }); }); }); diff --git a/test/e2e/__snapshots__/pair-liquidity-info-history-v2-db.service.e2e-spec.ts.snap b/test/e2e/__snapshots__/pair-liquidity-info-history-v2-db.service.e2e-spec.ts.snap new file mode 100644 index 0000000..1e1ded3 --- /dev/null +++ b/test/e2e/__snapshots__/pair-liquidity-info-history-v2-db.service.e2e-spec.ts.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PairLiquidityInfoHistoryV2DbService upsert should correctly upsert an existing entry 1`] = ` +{ + "deltaReserve0": "-500", + "deltaReserve1": "-500", + "eventType": "PairBurn", + "fiatPrice": "0", + "height": 200002, + "id": 222, + "logIndex": 1, + "microBlockHash": "mh_entry2", + "microBlockTime": 2000000000002n, + "pairId": 1, + "reserve0": "500", + "reserve1": "500", + "transactionHash": "th_entry2", + "transactionIndex": 200002n, +} +`; diff --git a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts index 70a6c50..86a282b 100644 --- a/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts +++ b/test/e2e/pair-liquidity-info-history-v2-db.service.e2e-spec.ts @@ -16,6 +16,7 @@ import { token2, token3, } from '@/test/mock-data/pair-liquidity-info-history-mock-data'; +import { omit } from 'lodash'; describe('PairLiquidityInfoHistoryV2DbService', () => { let service: PairLiquidityInfoHistoryV2DbService; @@ -68,10 +69,10 @@ describe('PairLiquidityInfoHistoryV2DbService', () => { logIndex: historyEntry2.logIndex, }; await service.upsert(updatedEntry); - const entry = await prismaService.pairLiquidityInfoHistoryV2.findFirst({ + const entry = await prismaService.pairLiquidityInfoHistoryV2.findUnique({ where: { id: historyEntry2.id }, }); - expect(entry?.reserve0).toEqual(new Decimal(500)); + expect(omit(entry, ['createdAt', 'updatedAt'])).toMatchSnapshot(); }); it('should correctly insert an new entry', async () => {