Skip to content

test: buy_confirm + sell_converter cubits (+14 tests)#338

Merged
TaprootFreak merged 1 commit into
developfrom
test/buy-confirm-sell-converter
May 15, 2026
Merged

test: buy_confirm + sell_converter cubits (+14 tests)#338
TaprootFreak merged 1 commit into
developfrom
test/buy-confirm-sell-converter

Conversation

@TaprootFreak
Copy link
Copy Markdown
Contributor

Summary

Stage 14 of the coverage push. Adds 14 unit tests for the two confirm/converter cubits where the source files are not on PR #321's or #332's path.

Cubit Test file Cases
`buy/cubits/buy_confirm/buy_confirm_cubit.dart` `test/screens/buy/cubits/buy_confirm_cubit_test.dart` 5
`sell/cubits/sell_converter/sell_converter_cubit.dart` `test/screens/sell/cubits/sell_converter_cubit_test.dart` 9

What each file covers

  • buy_confirm_cubit: initial `BuyConfirmInitial`; happy path emits `BuyConfirmSuccess(reference)`; `ApiException(statusCode: 503)` → `BuyConfirmFailure(BuyConfirmError.aktionariat)` (pins the Aktionariat-down branch); other `ApiException` → `BuyConfirmFailure(BuyConfirmError.unknown)`; generic exception → `unknown`.
  • sell_converter_cubit: initial empty + CHF; `onFiatChanged` debounces (100ms) and writes shares from `getSellShares`; respects an explicit `currency` argument; debounce keeps only the last value (pins the per-keystroke contract); state stable on service error; `onSharesChanged` writes `estimatedAmount` with matching fractional digits (`'10.000'` → 3 digits, `'10'` → 2 digits); `onCurrencyChanged` calls `getBuyPrice` — NOT `getSellPrice` — with the current `sharesText` (pins the intentional buy-side estimation on currency switch); currency still flips even when `getBuyPrice` throws; `close()` cancels pending debounce timers so no service call after close.

Notes

  • The `sell_converter` "currency switch uses BUY price" pin documents a non-obvious behaviour in the production code — leaving it untested would let a future refactor silently switch to `getSellPrice` and lose the no-fee preview.

Excluded (still deferred)

Test plan

  • `flutter analyze` on the two new files — clean
  • `flutter test` — 14 / 14 passing locally
  • CI green

Stage 14 of the coverage push.

- buy_confirm_cubit (5): initial Initial; happy path emits Success
  with the reference; ApiException(503) → Failure(aktionariat);
  other ApiException → Failure(unknown); generic exception →
  Failure(unknown)
- sell_converter_cubit (9): initial empty + CHF; onFiatChanged
  debounces and writes shares from getSellShares; respects explicit
  currency argument; debounce keeps only the last value; state
  stable on service error; onSharesChanged writes estimatedAmount
  with matching fractional digits (and defaults to 2 without a
  dot); onCurrencyChanged calls getBuyPrice (not getSellPrice)
  with current shares; currency flips on getBuyPrice throw; close()
  cancels pending debounce timers
@TaprootFreak TaprootFreak marked this pull request as ready for review May 15, 2026 11:47
@TaprootFreak TaprootFreak merged commit e8ecce9 into develop May 15, 2026
1 check passed
@TaprootFreak TaprootFreak deleted the test/buy-confirm-sell-converter branch May 15, 2026 11:47
TaprootFreak added a commit that referenced this pull request May 23, 2026
Tier-1 integration tests stitching SellBitboxCubit → FakeBitboxCredentials
boundary → real RealUnitSellPaymentInfoService → MockClient. The cubit and
the service are both real production code; only the BitBox transport and
the HTTP wire are stubbed. This pins:

* happy path — full swap+deposit ceremony emits two BitBox signs and the
  correct broadcast order/wire-shape (unsignedTx + r/s/v padding). Regression
  class: silently double-signing on the device or swapping leg order.

* cancel mid-swap — FakeBitboxBehavior.cancel propagates as
  SigningCancelledException all the way to SellBitboxError instead of
  being silently accepted as a successful sign (PR #322 bug class).

* disconnect — BitboxNotConnectedException is caught EXPLICITLY by the
  cubit's typed catch and emits SellBitboxBitboxRequired, not a generic
  Error state. Regression class: re-pair screen replaced by raw error
  string (PR #341).

* malformed signature — FormatException from a frame-desync hits the
  generic catch and surfaces as SellBitboxError, NOT mis-classified as a
  BitBox disconnect (would mask sig bugs as UX disconnect prompts).

* deposit-retry — transient 5xx on the deposit broadcast lands the cubit
  in SellBitboxDepositRetry with both signed envelopes preserved; the
  user does not have to re-sign on the device. Regression class:
  funds-at-risk loss of the already-signed swap (PR #338).
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.

1 participant