From 7c3002da2fa36704a34011e2e9de072bc5f3ed27 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Wed, 30 Sep 2026 16:46:26 -0400 Subject: [PATCH] test(amount-entry): cover hint freeze while sending AmountEntryDelegate.config keeps the last idle config while the host is loading or has succeeded, so the "$X available" hint doesn't jump to the post-send balance and turn red before the sheet dismisses. The existing tests only checked that loadingState passes through to the action; nothing asserted the freeze. The new test enters 99 against a max of 100.77, drops the max to 1.78 during loading, and checks the Info hint holds through loading and success, then turns into the over-max Error once loadingState is idle. --- .../amountentry/AmountEntryDelegateTest.kt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/apps/flipcash/shared/amount-entry/src/test/kotlin/com/flipcash/shared/amountentry/AmountEntryDelegateTest.kt b/apps/flipcash/shared/amount-entry/src/test/kotlin/com/flipcash/shared/amountentry/AmountEntryDelegateTest.kt index 607f3464c0..6444265a46 100644 --- a/apps/flipcash/shared/amount-entry/src/test/kotlin/com/flipcash/shared/amountentry/AmountEntryDelegateTest.kt +++ b/apps/flipcash/shared/amount-entry/src/test/kotlin/com/flipcash/shared/amountentry/AmountEntryDelegateTest.kt @@ -516,6 +516,47 @@ class AmountEntryDelegateTest { assertTrue(delegate.config.value.action.loadingState.success) } + @Test + fun `hint stays frozen while sending and after success, then goes live on idle`() = runTest { + val loading = MutableStateFlow(LoadingSuccessState()) + val max = MutableStateFlow(Fiat(100.77, CurrencyCode.USD)) + val delegate = createDelegate( + style = AmountEntryStyle( + actionLabel = AmountEntryLabel.Plain("Send"), + infoHint = { "$it available" }, + overMaxHint = { "Only $it available" }, + ), + loadingState = loading, + maxAmount = max, + ) + delegate.onCurrencyChanged(usd) + delegate.onNumber(9) + delegate.onNumber(9) + + val idleHint = delegate.config.value.hint + assertIs(idleHint) + + // The send debits the balance while the action is still loading. + loading.value = LoadingSuccessState(loading = true) + max.value = Fiat(1.78, CurrencyCode.USD) + + assertEquals(idleHint, delegate.config.value.hint) + assertTrue(delegate.config.value.action.loadingState.loading) + + // Success holds the frozen hint until the sheet dismisses. + loading.value = LoadingSuccessState(success = true) + + assertEquals(idleHint, delegate.config.value.hint) + assertTrue(delegate.config.value.action.loadingState.success) + + // Back to idle, the hint reflects the post-send balance again. + loading.value = LoadingSuccessState() + + val liveHint = delegate.config.value.hint + assertIs(liveHint) + assertTrue(liveHint.text.startsWith("Only")) + } + // --------------------------------------------------------------- // Config derivation — reactive style updates // ---------------------------------------------------------------