Skip to content

test(wallet): cover truncateAddress edge cases - #11

Merged
Miracle656 merged 2 commits into
Divinity-Labs:mainfrom
dxfareed:test/address-truncation-7
Sep 6, 2026
Merged

Miracle656 merged 2 commits into
Divinity-Labs:mainfrom
dxfareed:test/address-truncation-7

Conversation

@dxfareed

@dxfareed dxfareed commented Sep 5, 2026

Copy link
Copy Markdown

Closes #7

Two commits, readable separately: the tests, then a jest fix the acceptance criteria needed.

1. truncateAddress coverage

The helper is truncateAddress in frontend/wallet/lib/nfts.ts. It already had two tests covering a C-address, a short input and an empty string, so this fills in what was missing: the G-address case the issue names, plus the boundaries that were unpinned.

Added 8 tests (22 → 30 in that suite):

  • a G-address elides to GAAAAA…AAAWLT
  • both ends survive truncation, so the string a user compares against a pasted address stays checkable
  • two addresses sharing a 49-character prefix still render differently, so a head-only regression cannot pass
  • input exactly as long as the elision (12 === 6 + 6) is returned unchanged
  • one character past the boundary truncates, though the ellipsis means the result is no shorter than the input; pinned so the off-by-one stays deliberate
  • a nullish address reaches the || '' guard and returns '', which is what happens when an API payload omits the field
  • the 6/6 defaults, and custom head/tail lengths including the 5/5 the NFT list uses

Verified by mutation, since tests that only pass prove nothing. Breaking the helper four ways:

mutation tests that fail
drop the tail (head-only truncation) 7
<= → < at the boundary 1
remove the nullish guard 1
defaults 6,6 → 4,8 4

The two caught by exactly one test each are caught only by tests added here. lib/nfts.ts is byte-identical; no network calls, the suite already mocks fetch.

2. TextEncoder polyfill

npm test could not be green before this: lib/__tests__/feeBump.test.ts was failing to load with ReferenceError: TextEncoder is not defined, holding the suite at 20/21.

The suite does mock @stellar/stellar-sdk, but the failing import arrives through lib/fees → @veil/sdk → sdk/src/core.ts, which resolves a different physical copy of the package (sdk/node_modules, or the repo root when that is absent). Jest keys mocks by resolved path, so the mock covers the wallet's copy only, the real bundle loads, and it reaches for TextEncoder at module scope. jsdom does not define it.

Fixed with a 3-line jest.setup.js polyfilling TextEncoder/TextDecoder from node:util, wired through setupFiles (which runs before modules load, unlike the already-present empty setupFilesAfterEnv).

Deliberately not moduleNameMapper: the note at jest.config.js:18-22 records that forcing a single copy breaks jsdom's browser-field resolution.

How tested

  • npm test in frontend/wallet: 21/21 suites, 260 tests, up from 20/21 and 259.
  • Run both with and without sdk/node_modules present, since those two shapes resolve different copies of stellar-sdk. Green in both.
  • npm run typecheck in frontend/wallet clean.
  • Mutation results above.

Not tested: nothing on a device, and nothing in a browser. This change is test-only.

Notes

The wallet's jest suite does not run in CI. Parsing ci.yml, the only jobs invoking tests are sdk (npm test --if-present) and mobile (npm test). Both frontend/wallet jobs are typecheck/build and Lighthouse. That is presumably why a fully broken suite went unnoticed, and it means these tests will not be enforced on future PRs either. I left ci.yml alone since adding a job is your call on cost and scope, but happy to send that as a one-step follow-up if you want it.

Smaller thing, unrelated to this diff: the wallet UI truncates addresses inline as .slice(0, 6)….slice(-6) in about nine places (dashboard, send, agent, activity, token/[code], AppShell, TxPreviewCard) at three different widths, rather than calling this helper. Consolidating onto truncateAddress would make these tests cover the real UI rather than just the NFT page, but it touches far more files than this issue, so I have not done it here.

truncateAddress had two tests covering a C-address, a short input and an
empty string. Adds the G-address case the issue asks for plus the boundaries
that were unpinned: an input exactly as long as the elision, one character
past it, a nullish address reaching the `|| ''` guard, the 6/6 defaults, and
custom head/tail lengths.

Also asserts both ends survive truncation and that two addresses sharing a
49-character prefix still render differently, so a head-only regression
cannot pass.

Verified by mutation: dropping the tail fails 7 tests, changing `<=` to `<`
fails 1, removing the nullish guard fails 1, and altering the 6/6 defaults
fails 4. Tests only; lib/nfts.ts is unchanged.
lib/__tests__/feeBump.test.ts has been failing to load with "ReferenceError:
TextEncoder is not defined", taking the wallet suite to 20/21.

The suite mocks @stellar/stellar-sdk, but the failing import arrives through
lib/fees -> @veil/sdk -> sdk/src/core.ts, which resolves a different physical
copy of the package (sdk/node_modules, or the repo root when that is absent).
Jest keys mocks by resolved path, so the mock covers the wallet's copy only
and the real bundle loads, reaching for TextEncoder at module scope. jsdom
does not define it.

Polyfills TextEncoder/TextDecoder from node:util in setupFiles, which runs
before modules load. Not moduleNameMapper: the note at jest.config.js:18
records that forcing a single copy breaks jsdom's browser-field resolution.

Verified 21/21 suites and 260 tests both with and without sdk/node_modules
present, since the two shapes resolve different copies.
@dxfareed
dxfareed requested a review from Miracle656 as a code owner September 5, 2026 17:47
@Miracle656
Miracle656 merged commit 88e7807 into Divinity-Labs:main Sep 6, 2026
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.

Add unit tests for the address truncation helper

2 participants