Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions src/lib/mock-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,50 @@ describe("mock-client", () => {
it("verifies getHistory respects the limit parameter", async () => {
const { createMockClient } = await import("./mock-client");
const client = createMockClient();

const limit = 3;
const res = await client.transaction.getHistory("address", 1, limit);

expect(res.data).toBeDefined();
expect(res.data?.length).toBe(limit);
expect(res.total).toBe(25);
});

it("verifies getHistory correctly paginates across multiple pages with page and limit", async () => {
const { createMockClient } = await import("./mock-client");
const client = createMockClient();

const pageSize = 10;
const page1 = await client.transaction.getHistory("address", 1, pageSize);
const page2 = await client.transaction.getHistory("address", 2, pageSize);
const page3 = await client.transaction.getHistory("address", 3, pageSize);
const page4 = await client.transaction.getHistory("address", 4, pageSize);

expect(page1.data).toHaveLength(10);
expect(page2.data).toHaveLength(10);
expect(page3.data).toHaveLength(5);
expect(page4.data).toHaveLength(0);

expect(page1.total).toBe(25);
expect(page2.total).toBe(25);
expect(page3.total).toBe(25);

// Verify page slices do not overlap
const page1Hashes = page1.data?.map((tx) => tx.hash);
const page2Hashes = page2.data?.map((tx) => tx.hash);
const page3Hashes = page3.data?.map((tx) => tx.hash);

expect(page1Hashes?.some((h) => page2Hashes?.includes(h))).toBe(false);
expect(page2Hashes?.some((h) => page3Hashes?.includes(h))).toBe(false);
});

it("verifies getHistory defaults to page 1 and all items when page/limit not provided", async () => {
const { createMockClient, MOCK_HISTORY } = await import("./mock-client");
const client = createMockClient();

const res = await client.transaction.getHistory("address");
expect(res.data).toHaveLength(MOCK_HISTORY.length);
expect(res.total).toBe(MOCK_HISTORY.length);
});

it("verifies getHistory returns distinct pages via the page parameter", async () => {
Expand Down
20 changes: 9 additions & 11 deletions src/lib/mock-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const MOCK_ADDRESS =
"GBRPYHIL2CI3WHGSUJGY6O7SROQOMJG7QBCACN4QPKUOQNXJDGONXHPA";

// Generate deterministic mock data (consistent across test runs)
export const MOCK_HISTORY = deterministicMock.generateMockHistory(5);
export const MOCK_HISTORY = deterministicMock.generateMockHistory(25);
export const MOCK_EVENTS = deterministicMock.generateMockEvents(3);

export const NETWORKS = {
Expand Down Expand Up @@ -285,19 +285,17 @@ export function createMockClient(
getStatus: async () => ({ data: "success" as TxStatus, error: null }),
getHistory: async (
_address: string,
page?: number,
page: number = 1,
limit?: number,
) => {
const pageSize = limit ?? MOCK_HISTORY.length;
const currentPage = page ?? 1;
const start = (currentPage - 1) * pageSize;
const safePage = Math.max(1, page || 1);
const pageSize =
limit !== undefined && limit > 0 ? limit : MOCK_HISTORY.length;
const total = MOCK_HISTORY.length;
const start = (safePage - 1) * pageSize;
const end = start + pageSize;
const data = MOCK_HISTORY.slice(start, end);
return {
data: data.length > 0 ? data : null,
error: null,
total: MOCK_HISTORY.length,
};
const history = MOCK_HISTORY.slice(start, end);
return { data: history, error: null, total };
},
estimateFee: async () => ({
data: { baseFee: "100", recommended: "1000" },
Expand Down
4 changes: 3 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { ErrorBoundary } from './components/ErrorBoundary'
import type { SorokitClient } from './lib/client.ts'
import { createMockClient } from './lib/mock-client'

// Initialize mock client for development
// Client Strategy: Using createMockClient() from mock-client.ts for local development and demo mode.
// This single authoritative mock provides realistic delays, pagination, deterministic state, and balances.
// To connect to a live Soroban/Stellar network adapter in production, replace this factory with a real ClientAdapter.
const createClient = (): SorokitClient => createMockClient() as SorokitClient

function Root() {
Expand Down
Loading