Skip to content

Commit

Permalink
test: add unit tests for validatorV2
Browse files Browse the repository at this point in the history
  • Loading branch information
tmrdlt committed Apr 22, 2024
1 parent 6ac6359 commit 1f82422
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/clients/mdw-http-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class MdwHttpClientService {
getAccountBalanceForContractAtMicroBlockHash(
contractAddress: ContractAddress,
accountAddress: AccountAddress,
microBlockHash: string,
microBlockHash: MicroBlockHash,
): Promise<AccountBalance> {
return this.get<AccountBalance>(
`/v2/aex9/${contractAddress}/balances/${accountAddress}?hash=${microBlockHash}&${this.defaultParams}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export class PairLiquidityInfoHistoryImporterService {
const pairBalances =
await this.mdwClient.getContractBalancesAtMicroBlockHash(
pairWithTokens.address as ContractAddress,
block.hash,
block.hash as MicroBlockHash,
);
const totalSupply = pairBalances
.map((contractBalance) => BigInt(contractBalance.amount))
Expand All @@ -235,7 +235,7 @@ export class PairLiquidityInfoHistoryImporterService {
await this.mdwClient.getAccountBalanceForContractAtMicroBlockHash(
pairWithTokens.token0.address as ContractAddress,
contractAddrToAccountAddr(pairWithTokens.address as ContractAddress),
block.hash,
block.hash as MicroBlockHash,
)
).amount;

Expand All @@ -244,7 +244,7 @@ export class PairLiquidityInfoHistoryImporterService {
await this.mdwClient.getAccountBalanceForContractAtMicroBlockHash(
pairWithTokens.token1.address as ContractAddress,
contractAddrToAccountAddr(pairWithTokens.address as ContractAddress),
block.hash,
block.hash as MicroBlockHash,
)
).amount;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
import { Test, TestingModule } from '@nestjs/testing';

import { MdwHttpClientService } from '@/clients/mdw-http-client.service';
import { SdkClientService } from '@/clients/sdk-client.service';
import { PairLiquidityInfoHistoryV2DbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-v2-db.service';
import { PairLiquidityInfoHistoryValidatorV2Service } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator-v2.service';
import {
historyEntry1,
historyEntry2,
historyEntry3,
historyEntry4,
pairWithTokens,
} from '@/test/mock-data/pair-liquidity-info-history-mock-data';
import resetAllMocks = jest.resetAllMocks;
import {
AccountAddress,
ContractAddress,
MicroBlockHash,
} from '@/clients/sdk-client.model';
import { PairDbService } from '@/database/pair/pair-db.service';

const mockPairLiquidityInfoHistoryV2Db = {
getWithinHeightSorted: jest.fn(),
deleteFromMicroBlockTime: jest.fn(),
};

const pairDbMock = {
get: jest.fn(),
};

const mockMdwClient = {
getAccountBalanceForContractAtMicroBlockHash: jest.fn(),
};

const mockSdkClient = {
getHeight: jest.fn(),
};

describe('PairLiquidityInfoHistoryValidatorV2Service', () => {
let service: PairLiquidityInfoHistoryValidatorV2Service;
let logSpy: jest.SpyInstance;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
PairLiquidityInfoHistoryValidatorV2Service,
SdkClientService,
{
provide: PairLiquidityInfoHistoryV2DbService,
useValue: mockPairLiquidityInfoHistoryV2Db,
},
{ provide: PairDbService, useValue: pairDbMock },
{ provide: MdwHttpClientService, useValue: mockMdwClient },
{ provide: SdkClientService, useValue: mockSdkClient },
],
}).compile();
service = module.get<PairLiquidityInfoHistoryValidatorV2Service>(
PairLiquidityInfoHistoryValidatorV2Service,
);
logSpy = jest.spyOn(service.logger, 'log');
resetAllMocks();
});

describe('validate', () => {
it('should not delete entries if the mdw data matches with the last element of a local micro block', async () => {
// Mock functions
mockSdkClient.getHeight.mockResolvedValue(90000);
mockPairLiquidityInfoHistoryV2Db.getWithinHeightSorted.mockResolvedValue([
historyEntry2,
historyEntry3,
historyEntry4,
]);

pairDbMock.get.mockResolvedValue(pairWithTokens);

mockMdwClient.getAccountBalanceForContractAtMicroBlockHash.mockImplementation(
(
contractAddress: ContractAddress,
accountAddress: AccountAddress,
microBlockHash: MicroBlockHash,
) => {
if (microBlockHash === historyEntry2.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
return {
amount: historyEntry2.reserve0,
};
} else {
return {
amount: historyEntry2.reserve1,
};
}
} else if (microBlockHash === historyEntry4.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
return {
amount: historyEntry4.reserve0,
};
} else {
return {
amount: historyEntry4.reserve1,
};
}
} else {
return {};
}
},
);

// Start validation
await service.validate();

// Assertions
expect(
mockPairLiquidityInfoHistoryV2Db.getWithinHeightSorted,
).toHaveBeenCalledWith(89980); // Current height - VALIDATION_WINDOW_BLOCKS
expect(pairDbMock.get).toHaveBeenCalledTimes(2);

expect(
mockMdwClient.getAccountBalanceForContractAtMicroBlockHash,
).toHaveBeenCalledTimes(4);

expect(
mockPairLiquidityInfoHistoryV2Db.deleteFromMicroBlockTime,
).toHaveBeenCalledTimes(0);
expect(logSpy.mock.calls).toEqual([
['Started validating pair liquidity info history.'],
['No problems in pair liquidity info history found.'],
['Finished validating pair liquidity info history.'],
]);
});

it("should delete entries if the mdw data doesn't match with the local data", async () => {
// Mock functions
mockSdkClient.getHeight.mockResolvedValue(90000);
mockPairLiquidityInfoHistoryV2Db.getWithinHeightSorted.mockResolvedValue([
historyEntry1,
historyEntry2,
historyEntry3,
historyEntry4,
]);

pairDbMock.get.mockResolvedValue(pairWithTokens);

mockMdwClient.getAccountBalanceForContractAtMicroBlockHash.mockImplementation(
(
contractAddress: ContractAddress,
accountAddress: AccountAddress,
microBlockHash: MicroBlockHash,
) => {
if (microBlockHash === historyEntry1.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
return {
amount: historyEntry1.reserve0,
};
} else {
return {
amount: historyEntry1.reserve1,
};
}
} else if (microBlockHash === historyEntry2.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
return {
amount: '123',
};
} else {
return {
amount: '123',
};
}
} else {
return {};
}
},
);

mockPairLiquidityInfoHistoryV2Db.deleteFromMicroBlockTime.mockResolvedValue(
{ count: 3 },
);

// Start validation
await service.validate();

// Assertions
expect(pairDbMock.get).toHaveBeenCalledTimes(2);

expect(
mockMdwClient.getAccountBalanceForContractAtMicroBlockHash,
).toHaveBeenCalledTimes(4);

expect(
mockPairLiquidityInfoHistoryV2Db.deleteFromMicroBlockTime,
).toHaveBeenCalledWith(historyEntry2.microBlockTime);
expect(logSpy.mock.calls).toEqual([
['Started validating pair liquidity info history.'],
[
'Found an inconsistency in pair liquidity info history. Deleted 3 entries.',
],
['Finished validating pair liquidity info history.'],
]);
});

it('should delete entries if mdw return an error', async () => {
// Mock functions
mockSdkClient.getHeight.mockResolvedValue(90000);
mockPairLiquidityInfoHistoryV2Db.getWithinHeightSorted.mockResolvedValue([
historyEntry1,
historyEntry2,
historyEntry3,
historyEntry4,
]);

pairDbMock.get.mockResolvedValue(pairWithTokens);

mockMdwClient.getAccountBalanceForContractAtMicroBlockHash.mockImplementation(
(
contractAddress: ContractAddress,
accountAddress: AccountAddress,
microBlockHash: MicroBlockHash,
) => {
if (microBlockHash === historyEntry1.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
return {
amount: historyEntry1.reserve0,
};
} else {
return {
amount: historyEntry1.reserve1,
};
}
} else if (microBlockHash === historyEntry2.microBlockHash) {
if (contractAddress === pairWithTokens.token0.address) {
throw new Error('mdw error');
}
}
},
);

mockPairLiquidityInfoHistoryV2Db.deleteFromMicroBlockTime.mockResolvedValue(
{ count: 3 },
);

// Start validation
await service.validate();

// Assertions
expect(pairDbMock.get).toHaveBeenCalledTimes(2);

expect(
mockMdwClient.getAccountBalanceForContractAtMicroBlockHash,
).toHaveBeenCalledTimes(3);

expect(
mockPairLiquidityInfoHistoryV2Db.deleteFromMicroBlockTime,
).toHaveBeenCalledWith(historyEntry2.microBlockTime);
expect(logSpy.mock.calls).toEqual([
['Started validating pair liquidity info history.'],
[
'Found an inconsistency in pair liquidity info history. Deleted 3 entries.',
],
['Finished validating pair liquidity info history.'],
]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { MdwHttpClientService } from '@/clients/mdw-http-client.service';
import {
ContractAddress,
contractAddrToAccountAddr,
MicroBlockHash,
} from '@/clients/sdk-client.model';
import { SdkClientService } from '@/clients/sdk-client.service';
import { PairDbService } from '@/database/pair/pair-db.service';
Expand Down Expand Up @@ -59,7 +60,7 @@ export class PairLiquidityInfoHistoryValidatorV2Service {
contractAddrToAccountAddr(
liquidityEntry.pair.address as ContractAddress,
),
liquidityEntry.microBlockHash,
liquidityEntry.microBlockHash as MicroBlockHash,
)
).amount,
);
Expand All @@ -72,7 +73,7 @@ export class PairLiquidityInfoHistoryValidatorV2Service {
contractAddrToAccountAddr(
liquidityEntry.pair.address as ContractAddress,
),
liquidityEntry.microBlockHash,
liquidityEntry.microBlockHash as MicroBlockHash,
)
).amount,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SdkClientService } from '@/clients/sdk-client.service';
import { PairLiquidityInfoHistoryDbService } from '@/database/pair-liquidity-info-history/pair-liquidity-info-history-db.service';
import { PairLiquidityInfoHistoryValidatorService } from '@/tasks/pair-liquidity-info-history-validator/pair-liquidity-info-history-validator.service';

const mockMdwClientService = {
const mockMdwClient = {
getKeyBlockMicroBlocks: jest.fn(),
};

Expand All @@ -22,7 +22,7 @@ describe('PairLiquidityInfoHistoryValidatorService', () => {
providers: [
PairLiquidityInfoHistoryValidatorService,
SdkClientService,
{ provide: MdwHttpClientService, useValue: mockMdwClientService },
{ provide: MdwHttpClientService, useValue: mockMdwClient },
{
provide: PairLiquidityInfoHistoryDbService,
useValue: mockPairLiquidityInfoHistoryDb,
Expand Down Expand Up @@ -69,7 +69,7 @@ describe('PairLiquidityInfoHistoryValidatorService', () => {
historyEntry3,
historyEntry4,
]);
mockMdwClientService.getKeyBlockMicroBlocks.mockImplementation(
mockMdwClient.getKeyBlockMicroBlocks.mockImplementation(
(height: number) => {
if (height === historyEntry1.height) {
return [
Expand All @@ -93,18 +93,18 @@ describe('PairLiquidityInfoHistoryValidatorService', () => {
await service.validate();

// Assertions
expect(mockMdwClientService.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
expect(mockMdwClient.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
historyEntry1.height,
);
expect(mockMdwClientService.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
expect(mockMdwClient.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
historyEntry3.height,
);
expect(mockMdwClientService.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
expect(mockMdwClient.getKeyBlockMicroBlocks).toHaveBeenCalledWith(
historyEntry4.height,
);
expect(
mockMdwClientService.getKeyBlockMicroBlocks,
).not.toHaveBeenCalledWith(historyEntry5.height);
expect(mockMdwClient.getKeyBlockMicroBlocks).not.toHaveBeenCalledWith(
historyEntry5.height,
);
expect(
mockPairLiquidityInfoHistoryDb.deleteFromMicroBlockTime,
).toHaveBeenCalledWith(historyEntry4.microBlockTime);
Expand Down
4 changes: 2 additions & 2 deletions test/mock-data/pair-liquidity-info-history-mock-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ export const historyEntry4: PairLiquidityInfoHistoryV2 = {
deltaReserve1: new Decimal(-50),
fiatPrice: new Decimal(0),
height: 300003,
microBlockHash: 'mh_entry4',
microBlockHash: 'mh_entry3',
microBlockTime: 3000000000003n,
transactionHash: 'th_entry4',
transactionHash: 'th_entry3',
transactionIndex: 300003n,
logIndex: 2,
createdAt: new Date(),
Expand Down

0 comments on commit 1f82422

Please sign in to comment.