diff --git a/indexer/packages/postgres/__tests__/stores/pnl-ticks-table.test.ts b/indexer/packages/postgres/__tests__/stores/pnl-ticks-table.test.ts index 8a6fc98db8..76776ee4b2 100644 --- a/indexer/packages/postgres/__tests__/stores/pnl-ticks-table.test.ts +++ b/indexer/packages/postgres/__tests__/stores/pnl-ticks-table.test.ts @@ -112,6 +112,66 @@ describe('PnlTicks store', () => { expect(pnlTicks.length).toEqual(2); }); + it('Successfully finds PnlTicks using pagination', async () => { + const blockTime: IsoString = '2023-01-01T00:00:00.000Z'; + await Promise.all([ + PnlTicksTable.create(defaultPnlTick), + PnlTicksTable.create({ + ...defaultPnlTick, + createdAt: '2020-01-01T00:00:00.000Z', + blockHeight: '1000', + blockTime, + }), + ]); + + const responsePageOne = await PnlTicksTable.findAll({ + page: 1, + limit: 1, + }, [], { + orderBy: [[PnlTicksColumns.blockHeight, Ordering.DESC]], + }); + + expect(responsePageOne.results.length).toEqual(1); + expect(responsePageOne.results[0]).toEqual(expect.objectContaining({ + ...defaultPnlTick, + createdAt: '2020-01-01T00:00:00.000Z', + blockHeight: '1000', + blockTime, + })); + expect(responsePageOne.offset).toEqual(0); + expect(responsePageOne.total).toEqual(2); + + const responsePageTwo = await PnlTicksTable.findAll({ + page: 2, + limit: 1, + }, [], { + orderBy: [[PnlTicksColumns.blockHeight, Ordering.DESC]], + }); + + expect(responsePageTwo.results.length).toEqual(1); + expect(responsePageTwo.results[0]).toEqual(expect.objectContaining(defaultPnlTick)); + expect(responsePageTwo.offset).toEqual(1); + expect(responsePageTwo.total).toEqual(2); + + const responsePageAllPages = await PnlTicksTable.findAll({ + page: 1, + limit: 2, + }, [], { + orderBy: [[PnlTicksColumns.blockHeight, Ordering.DESC]], + }); + + expect(responsePageAllPages.results.length).toEqual(2); + expect(responsePageAllPages.results[0]).toEqual(expect.objectContaining({ + ...defaultPnlTick, + createdAt: '2020-01-01T00:00:00.000Z', + blockHeight: '1000', + blockTime, + })); + expect(responsePageAllPages.results[1]).toEqual(expect.objectContaining(defaultPnlTick)); + expect(responsePageAllPages.offset).toEqual(0); + expect(responsePageAllPages.total).toEqual(2); + }); + it('Successfully finds latest block time', async () => { const blockTime: IsoString = '2023-01-01T00:00:00.000Z'; await Promise.all([ diff --git a/indexer/services/comlink/__tests__/controllers/api/v4/historical-pnl-controller.test.ts b/indexer/services/comlink/__tests__/controllers/api/v4/historical-pnl-controller.test.ts index 6436dae861..9ff5c2468c 100644 --- a/indexer/services/comlink/__tests__/controllers/api/v4/historical-pnl-controller.test.ts +++ b/indexer/services/comlink/__tests__/controllers/api/v4/historical-pnl-controller.test.ts @@ -73,6 +73,75 @@ describe('pnlTicks-controller#V4', () => { ); }); + it('Get /historical-pnl respects pagination', async () => { + await testMocks.seedData(); + const createdAt: string = '2000-05-25T00:00:00.000Z'; + const blockHeight: string = '1'; + const pnlTick2: PnlTicksCreateObject = { + ...testConstants.defaultPnlTick, + createdAt, + blockHeight, + }; + await Promise.all([ + PnlTicksTable.create(testConstants.defaultPnlTick), + PnlTicksTable.create(pnlTick2), + ]); + + const responsePage1: request.Response = await sendRequest({ + type: RequestMethod.GET, + path: `/v4/historical-pnl?address=${testConstants.defaultAddress}` + + `&subaccountNumber=${testConstants.defaultSubaccount.subaccountNumber}&page=1&limit=1`, + }); + + const responsePage2: request.Response = await sendRequest({ + type: RequestMethod.GET, + path: `/v4/historical-pnl?address=${testConstants.defaultAddress}` + + `&subaccountNumber=${testConstants.defaultSubaccount.subaccountNumber}&page=2&limit=1`, + }); + + const expectedPnlTickResponse: PnlTicksResponseObject = { + ...testConstants.defaultPnlTick, + id: PnlTicksTable.uuid( + testConstants.defaultPnlTick.subaccountId, + testConstants.defaultPnlTick.createdAt, + ), + }; + + const expectedPnlTick2Response: PnlTicksResponseObject = { + ...testConstants.defaultPnlTick, + createdAt, + blockHeight, + id: PnlTicksTable.uuid( + testConstants.defaultPnlTick.subaccountId, + createdAt, + ), + }; + + expect(responsePage1.body.pageSize).toStrictEqual(1); + expect(responsePage1.body.offset).toStrictEqual(0); + expect(responsePage1.body.totalResults).toStrictEqual(2); + expect(responsePage1.body.historicalPnl).toHaveLength(1); + expect(responsePage1.body.historicalPnl).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + ...expectedPnlTickResponse, + }), + ]), + ); + + expect(responsePage2.body.pageSize).toStrictEqual(1); + expect(responsePage2.body.offset).toStrictEqual(1); + expect(responsePage2.body.totalResults).toStrictEqual(2); + expect(responsePage2.body.historicalPnl).toHaveLength(1); + expect(responsePage2.body.historicalPnl).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + ...expectedPnlTick2Response, + }), + ]), + ); + }); + it('Get /historical-pnl respects createdBeforeOrAt and createdBeforeOrAtHeight field', async () => { await testMocks.seedData(); const createdAt: string = '2000-05-25T00:00:00.000Z'; diff --git a/indexer/services/comlink/src/controllers/api/v4/historical-pnl-controller.ts b/indexer/services/comlink/src/controllers/api/v4/historical-pnl-controller.ts index 8b9cc052dd..a6559b05a7 100644 --- a/indexer/services/comlink/src/controllers/api/v4/historical-pnl-controller.ts +++ b/indexer/services/comlink/src/controllers/api/v4/historical-pnl-controller.ts @@ -211,6 +211,7 @@ router.get( createdBeforeOrAt, createdOnOrAfterHeight, createdOnOrAfter, + page, }: PnlTicksRequest = matchedData(req) as PnlTicksRequest; try { @@ -223,6 +224,7 @@ router.get( createdBeforeOrAt, createdOnOrAfterHeight, createdOnOrAfter, + page, ); return res.send(response); diff --git a/indexer/services/comlink/src/types.ts b/indexer/services/comlink/src/types.ts index b99414f8bb..5a3a5b505a 100644 --- a/indexer/services/comlink/src/types.ts +++ b/indexer/services/comlink/src/types.ts @@ -425,7 +425,8 @@ export interface TradeRequest extends LimitAndCreatedBeforeRequest, PaginationRe export interface PerpetualMarketRequest extends LimitRequest, TickerRequest {} -export interface PnlTicksRequest extends SubaccountRequest, LimitAndCreatedBeforeAndAfterRequest {} +export interface PnlTicksRequest + extends SubaccountRequest, LimitAndCreatedBeforeAndAfterRequest, PaginationRequest {} export interface ParentSubaccountPnlTicksRequest extends ParentSubaccountRequest, LimitAndCreatedBeforeAndAfterRequest {