forked from aeternity/dex-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add unit tests for validatorV2
- Loading branch information
Showing
6 changed files
with
281 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
263 changes: 263 additions & 0 deletions
263
...liquidity-info-history-validator/pair-liquidity-info-history-validator-v2.service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.'], | ||
]); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters