@noves/noves-sdk
Version:
Noves Developer Kit
109 lines (92 loc) • 4.66 kB
text/typescript
/**
* 1.5.0 Release Test — Pagination & Async Iteration (regression)
*
* Validates pagination features built over multiple releases:
* - TransactionsPage forward navigation (next) — mutates in-place, returns boolean
* - TransactionsPage backward navigation (previous) — mutates in-place, returns boolean
* - Async iteration (for await ... of)
* - Cursor-based pagination (getCursorInfo, getNextCursor, fromCursor)
*/
import { Translate, TransactionsPage } from '../dist/index';
import { section, pass, fail, runTest, skip } from './helpers';
const API_KEY = process.env.NOVES_API_KEY!;
export async function testCorePagination() {
section('CORE: Pagination & Cursors (Regression)');
const translate = Translate.evm(API_KEY);
const chain = 'eth';
const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'; // vitalik.eth
// 1. Basic pagination
let page: any = null;
let page1FirstHash: string | null = null;
await runTest('Pagination: first page', async () => {
page = await translate.getTransactions(chain, address, { pageSize: 3 });
const txs = page.getTransactions();
if (!txs || txs.length === 0) throw new Error('No transactions on page 1');
page1FirstHash = txs[0]?.rawTransactionData?.transactionHash || null;
pass('Pagination: first page', `${txs.length} transactions`);
});
// 2. Next page — next() mutates in-place and returns boolean
let navigatedToPage2 = false;
if (page && page.hasNext()) {
await runTest('Pagination: next()', async () => {
const hasNext = await page.next(); // returns boolean, mutates page
if (!hasNext) throw new Error('next() returned false');
const txs = page.getTransactions();
if (!txs || txs.length === 0) throw new Error('Page 2 has no transactions');
// Verify different transactions
const p2Hash = txs[0]?.rawTransactionData?.transactionHash;
if (page1FirstHash && p2Hash && page1FirstHash === p2Hash) {
throw new Error('Page 1 and Page 2 have the same first transaction!');
}
pass('Pagination: next()', `Page 2: ${txs.length} txs, different from page 1`);
navigatedToPage2 = true;
});
} else {
skip('Pagination: next()', 'No next page available');
}
// 3. Previous page
if (navigatedToPage2 && page && page.hasPrevious()) {
await runTest('Pagination: previous()', async () => {
const hasPrev = await page.previous(); // returns boolean, mutates page
if (!hasPrev) throw new Error('previous() returned false');
const txs = page.getTransactions();
if (!txs || txs.length === 0) throw new Error('Previous page has no transactions');
pass('Pagination: previous()', `Previous page: ${txs.length} txs`);
});
} else {
skip('Pagination: previous()', 'No previous page available');
}
// 4. Cursor-based pagination (get a fresh page)
await runTest('Pagination: cursor roundtrip', async () => {
const freshPage = await translate.getTransactions(chain, address, { pageSize: 3 });
const cursorInfo = freshPage.getCursorInfo();
if (!cursorInfo) throw new Error('getCursorInfo() returned null');
pass('Pagination: getCursorInfo()', `hasNext=${cursorInfo.hasNextPage}, hasPrevious=${cursorInfo.hasPreviousPage}`);
if (freshPage.hasNext()) {
const nextCursor = freshPage.getNextCursor();
if (!nextCursor) throw new Error('getNextCursor() returned null');
// Decode the cursor
const decoded = TransactionsPage.decodeCursor(nextCursor);
if (!decoded) throw new Error('decodeCursor() returned null');
pass('Pagination: cursor encode/decode', `Cursor encoded/decoded successfully`);
// Reconstruct page from cursor
const restoredPage = await TransactionsPage.fromCursor(translate, chain, address, nextCursor);
if (!restoredPage) throw new Error('fromCursor() returned null');
const txs = restoredPage.getTransactions();
if (!txs || txs.length === 0) throw new Error('Restored page has no transactions');
pass('Pagination: fromCursor()', `Restored page: ${txs.length} txs`);
}
});
// 5. Async iteration (limited to 6 transactions to avoid timeout)
await runTest('Pagination: async iteration', async () => {
const iterPage = await translate.getTransactions(chain, address, { pageSize: 2 });
let count = 0;
const maxTxs = 6;
for await (const tx of iterPage) {
count++;
if (count >= maxTxs) break;
}
if (count === 0) throw new Error('Async iteration yielded 0 transactions');
pass('Pagination: async iteration', `Iterated over ${count} transactions (limit ${maxTxs})`);
});
}