Skip to content

Test: Component: Transaction History (Table View) Export Flow - #530

Open
Deb-Auth wants to merge 1 commit into
SwiftChainn:mainfrom
Deb-Auth:test-comp-tx-history-table
Open

Test: Component: Transaction History (Table View) Export Flow#530
Deb-Auth wants to merge 1 commit into
SwiftChainn:mainfrom
Deb-Auth:test-comp-tx-history-table

Conversation

@Deb-Auth

Copy link
Copy Markdown

closes #507

Summary

Adds automated tests verifying that the Transaction History table's "Export to CSV" button downloads the current table data, together with the table view and export pipeline those tests exercise.

There was no transaction history table in the repository at the time of writing — components/settings/ExportData.tsx covers a different flow (a GDPR account export as JSON) — so there was no export button to test. This PR adds the table and its CSV export following the project's Component -> Hook -> Service layering, and tests each layer.

What was added

lib/csvExport.ts — CSV serialisation and download primitives.

  • escapeCsvValue implements RFC 4180 escaping: values containing a comma, a quote or a newline are quoted, embedded quotes are doubled, and nullish values become empty cells.
  • toCsv always writes the header row, so even an empty export is a well-formed file.
  • downloadCsv creates a text/csv blob, clicks a hidden anchor and revokes the object URL in a finally, so a blocked or throwing click cannot leak a blob or leave an orphan anchor in the document. The payload is prefixed with a UTF-8 BOM so spreadsheet applications do not mangle non-ASCII characters.

services/transactionHistoryService.ts — reads the authenticated user's transaction history, with a TransactionRecord shape reusing the existing TransactionStatus from types/transaction.ts. Transport failures are converted into an unsuccessful response rather than thrown, matching the convention in exportDataService.

hooks/useTransactionExport.ts — turns the rows the table currently holds into a download.

  • The rows are passed in rather than refetched, so the file always matches what the user is looking at, filters and sorting included. This is the specific behaviour the issue asks to verify.
  • Refuses to export an empty table, exposes isExporting / error / didExport, and clears a previous error on the next attempt.
  • The column layout mirrors the on-screen table plus the counterparty and delivery id, and the filename is date-stamped (swiftchain-transactions-YYYY-MM-DD.csv).

components/transactions/TransactionHistoryTable.tsx — the table with the export button, a row count, a success confirmation, a dismissible export error, and loading, error and empty states. The export button is disabled when there is nothing to export.

Test coverage

components/transactions/__tests__/TransactionHistoryTable.test.tsx (16 tests)

  • Export flow (happy path): clicking Export to CSV produces one download with a date-stamped filename and one line per visible row; the export carries the untruncated hash rather than the abbreviated string shown in the cell; the export reflects exactly the rows currently rendered after the table's data changes; a success confirmation appears; repeated exports work.
  • Export errors: a failing download surfaces an alert instead of the success message, the alert is dismissible, and a retry recovers.
  • Rendering: one row per transaction, long hashes truncated while short ones are left intact, a correctly pluralised row count, and a placeholder for an unparseable date.
  • Edge cases: the empty state renders, the export button is disabled and clicking it triggers nothing; loading and error states render in place of the table and hide the export control, with loading taking precedence.

hooks/__tests__/useTransactionExport.test.ts (14 tests)

Filename stamping, column layout, serialised content including the header and one line per transaction, empty cells for absent optional fields, escaping of a counterparty containing a comma, success flagging, refusal to export an empty table, downloader failure and non-Error failure handling, error clearing on retry and on demand, and the guarantee that only the supplied rows are exported.

__tests__/lib/csvExport.test.ts (14 tests)

Escaping of plain, nullish, comma-bearing, quote-bearing and newline-bearing values; header-only output for an empty dataset; header escaping; blob type, anchor click, filename, href and URL revocation; the UTF-8 BOM; content round-tripping; and cleanup when the click throws.

services/__tests__/transactionHistoryService.test.ts (4 tests)

Endpoint, success payload passthrough, and both transport-failure paths.

Mocking of external dependencies

@/lib/api (the shared axios instance) is mocked in the service tests. downloadCsv is mocked in the hook and component tests so the assertions can inspect the exact CSV payload and filename without depending on jsdom's download behaviour, while __tests__/lib/csvExport.test.ts tests the real implementation directly against a stubbed URL.createObjectURL and an anchor-click spy. jest.useFakeTimers().setSystemTime(...) pins the date so filename assertions cannot drift. No real HTTP, wallet or WebSocket call is made anywhere in the suite.

Verification

  • npx jest __tests__/lib/csvExport.test.ts hooks/__tests__/useTransactionExport.test.ts components/transactions/__tests__/TransactionHistoryTable.test.tsx services/__tests__/transactionHistoryService.test.ts — 48 tests pass.
  • pnpm test — the full suite goes from 921 to 969 tests with no change to the set of pre-existing failures.
  • npx eslint on every changed file — no errors.
  • pnpm run type-check — no new errors.

Note for the maintainer

CI on main is currently red before any of this, and these changes do not fix or worsen it:

  1. components/mobile/MobileFooter.tsx has lost every quote character in the file (line 1 reads ​`use client and line 3 import React from react). This is a hard parse error that fails pnpm run lint, pnpm run type-check and pnpm run build on main today.
  2. 21 test suites already fail on main, largely around the wallet/Freighter mocks (useWallet, useTheme, WalletConnect, MultiSigApprovals and related).

Both look like they need a maintainer decision rather than a drive-by fix from a test PR, so I have deliberately left them untouched to keep this diff scoped to the issue.

@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@Deb-Auth Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Test] Component: Transaction History (Table View) Export Flow

1 participant