testing library
Test-support library for hosts embedding the wallet UI: the fakes needed
to pump wallet surfaces in widget tests without the native library —
FakeWalletSession (a scripted WalletSession) and the fake onboarding
seams (provisioner / store / screen-security). DELIBERATELY free of any
flutter_test import, so depending on it never constrains a consumer's
test-framework solve; import it from test code only.
Classes
- FakeOnboardingStore
- An in-memory OnboardingStore. Backs the backup-confirmed flag; can be made to throw on persist to exercise the gate-stays-closed path. Seedable so a "previous launch" state (a confirmed or unconfirmed prior wallet) is set up.
- FakeRevealAuthorizer
-
A recording WalletRevealAuthorizer for host-VM tests — proves the reveal
re-auth seam from the outside: the backup screen must route every reveal
through authorizeReveal and MUST NOT read the recovery words when re-auth
is denied or faults (pair with FakeWalletProvisioner's
revealCount). - FakeScreenSecurity
- A host-VM fake ScreenSecurity — counts the backup screen's protection requests so a widget test can assert it engages on show and releases on dispose. isScreenshotBlockSupported is configurable so a test can drive both the Android (block) and the elsewhere (advise-a-private-setting) copy.
- FakeSendAuthorizer
- A recording WalletSendAuthorizer for host-VM tests — proves the seam's contract from the outside: every money-committing action routes through authorizeSpend EXACTLY ONCE (see intents), and a denial (denyAll) reaches the controller BEFORE any bridge call (pair with the fake session's call counters).
- FakeWalletProvisioner
- A host-VM fake WalletProvisioner — no native library, no device. Drives the OnboardingController state machine deterministically: configure what is on disk, make any step succeed or throw a TYPED failure, and count calls.
- FakeWalletSession
-
A host-VM fake for WalletSession — no native library, no device. It
mirrors the real
watchSyncStatuscontract (CURRENT status emitted on subscribe) and gives tests direct handles to drive the live stream (push / error / complete) and to count subscribes, cancels, snapshots, and start/stop calls. - FakeWalletSettingsStore
- An in-memory WalletSettingsStore for tests — scripted reads (parkable via readGate to pin the loading-window rules) and recorded writes (so a test proves persist-then-publish and the failed-write honesty).
- TestLifecycleNotifier
-
A controllable appLifecycleProvider override for DETERMINISTIC lifecycle
tests. Overriding the provider bypasses the platform binding entirely — no
handleAppLifecycleStateChangedtransition-legality, no AppLifecycleListener coalescing across pump boundaries (both of which make binding-driven hides flaky and unable to distinguish "this state is not a trigger" from "the event never fired").emitdrives the state directly so aref.listenfires for exactly the state asked for. Subclasses the real AppLifecycleNotifier (so it matches the provider'soverrideWithtype) but overridesbuildto NOT register the platformAppLifecycleListener— the binding plays no part.
Properties
- defaultSendProposalBinding → Uint8List
-
The deterministic FR-17 spend-binding nonce sendProposalFixture (and via
it shieldProposalFixture) defaults to — distinct from
defaultSwapQuoteBinding so a test that mixes a proposal and a quote can
tell whose bytes reached a seam.
final
- defaultSwapQuoteBinding → Uint8List
-
The deterministic FR-17 spend-binding nonce swapQuoteFixture defaults to
— distinct from defaultSendProposalBinding so a test that mixes a
proposal and a quote can tell whose bytes reached a seam.
final
- testBip39Wordlist → Bip39Wordlist
-
A tiny BIP39 wordlist fixture for the restore widget tests — just the words
the tests use (sorted, lowercase, like the real bundled asset). The restore
field's live validity/autocomplete reads this; the SDK is still the real gate.
Restore harnesses override
bip39WordlistProviderwith this so validity is deterministic (every test word reads valid → the count-only gate applies).final
Functions
-
balanceFixture(
{int spendableZat = 0, int pendingIncomingZat = 0, int pendingChangeZat = 0, int transparentZat = 0, int totalZat = 0}) → BalanceSnapshot -
ephemeralSweepSummaryFixture(
{int scanned = 1, int swept = 1, int recoveredZat = 250000, int failed = 0, int truncated = 0}) → EphemeralSweepSummary -
A neutral
EphemeralSweepSummaryfor recovery-sheet tests (2e-2b-v-2). Defaults to a clean funded recovery (one address swept, nothing failed or truncated); override to model partial faults / a heavy-wallet truncation. -
inFlightSendFixture(
{int amountZat = 80000, int createdAt = 1700000000}) → InFlightSend - An in-flight two-step row (#309) — first leg broadcast, send not complete; drives the durable "on its way — don't send it again" cue.
-
parkedSendFixture(
{int id = 7, ParkedSendKind kind = ParkedSendKind.twoStep, int amountZat = 70000, int createdAt = 1700000000, bool paused = false, bool sending = false, Uint8List? binding, SigningBlock? signingBlock}) → ParkedSend -
A neutral
ParkedSendfor "saved & pending" surface tests (2e-2b-v-3) — amount-only, with an id + enqueue timestamp the cancel flow passes back. Defaults to the two-step (one-time-address) kind, the surface's original shape; passParkedSendKind.singleStepfor a plainly-queued offline send (#331 — the same surface carries both). -
sendProposalFixture(
{int proposalId = 1, int totalZat = 100500, int feeZat = 500, int changeZat = 0, bool hasTransparentRecipient = false, bool isShield = false, bool isTwoStepTex = false, List< ProposalStep> ? steps, LargeSendReason? largeSend, bool selfSend = false, int? singleRecipientZat = 100000, Uint8List? binding}) → SendProposal -
A neutral
SendProposalfor tests — override only what a case cares about. Defaults to a single shielded (Orchard) recipient (no de-shield disclosure). -
shieldProposalFixture(
{int proposalId = 42, int totalZat = 500000, int feeZat = 15000}) → SendProposal -
A neutral SHIELD
SendProposalfor Recv-3 tests —isShield == true, NO transparent recipient (privacy-positive), gross/fee/net consistent (changeZat == totalZat - feeZat), the lone output in the shielded pool. -
swapQuoteFixture(
{String id = 'swap-1', String depositAddress = 'tdeposit', String? depositMemo, int expiresAt = 2000000000, String amountIn = '0.5', String minAmountOut = '49.5', int zecSideZat = 50000000, String? refundTo, bool deshields = true, bool endsShielded = false, bool providerLegsTransparent = true, List< DisclosureItem> providerSees = const [DisclosureItem.amounts, DisclosureItem.destinationAddress], Uint8List? binding}) → SwapQuote -
A neutral
SwapQuotefor tests — override only what a case cares about. Defaults to an OutOfZec-shaped quote (a de-shielding deposit) so the disclosure carries the privacy-critical flags a swap review must render. -
swapRecordFixture(
{String id = 'swap-record-1', SwapRecordDirection direction = SwapRecordDirection.outOfZec, int createdAt = 1700000000, int? depositDeadline = 4100000000, int expiresAt = 4100172800, SwapOutcome? outcome}) → SwapRecord - A durable in-flight swap row (W-swap-5, #366) — drives the wallet-screen swap home + the guard-fault "view swap" re-attach. Defaults to OutOfZec (the armed-deposit shape the hardware photo showed invisible).
-
swapTokenListFixture(
{List< SwapToken> ? tokens, bool fresh = true}) → SwapTokenList -
A neutral
SwapTokenListfor IntoZec picker tests — two plausible source assets,freshby default. Overridefresh: falseto model serve-stale, ortokens: const [](fresh) to model the honest "no assets available" state. -
txSummaryFixture(
{String txidHex = 'aa00000000000000000000000000000000000000000000000000000000000000', int? minedHeight = 100, TxStatus status = const TxStatus.confirmed(depth: 5), int netAmountZat = 250000, int? feeZat, bool hasMemo = true, bool hasTransparentOutput = false, int? timestamp = 1700000000}) → TxSummary -
A neutral
TxSummaryhistory row for tests (FR-1) — override only what a case cares about. Defaults to a confirmed incoming tx with a memo. -
walletStateFixture(
{SyncStatus syncStatus = const SyncStatus.idle(), TorState tor = const TorState.off(), BalanceSnapshot? balance, int? tip, SyncStamp? lastSynced, bool everSynced = false, bool rescanRebuilding = false, int seq = 0}) → WalletState -
A complete, neutral
WalletStatefor tests — override only what a case cares about.PlatformInt64isinton the host VM (web is out of scope for this SDK), so plain int literals construct the money fields.