Skip to content

Commit 3a3b96d

Browse files
ovitrifclaude
andcommitted
test: add ToastQueue behavior tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 20be904 commit 3a3b96d

3 files changed

Lines changed: 151 additions & 2 deletions

File tree

app/src/main/java/to/bitkit/ui/Locals.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.runtime.compositionLocalOf
66
import androidx.compose.runtime.staticCompositionLocalOf
77
import to.bitkit.models.BalanceState
88
import to.bitkit.repositories.CurrencyState
9+
import to.bitkit.ui.shared.toast.Toaster
910
import to.bitkit.viewmodels.ActivityListViewModel
1011
import to.bitkit.viewmodels.AppViewModel
1112
import to.bitkit.viewmodels.BackupsViewModel
@@ -14,7 +15,6 @@ import to.bitkit.viewmodels.CurrencyViewModel
1415
import to.bitkit.viewmodels.SettingsViewModel
1516
import to.bitkit.viewmodels.TransferViewModel
1617
import to.bitkit.viewmodels.WalletViewModel
17-
import to.bitkit.ui.shared.toast.Toaster
1818

1919
// Locals
2020
val LocalBalances = compositionLocalOf { BalanceState() }

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.update
4747
import kotlinx.coroutines.launch
4848
import kotlinx.coroutines.withContext
4949
import kotlinx.coroutines.withTimeout
50-
import kotlin.time.Duration
5150
import org.lightningdevkit.ldknode.ChannelDataMigration
5251
import org.lightningdevkit.ldknode.Event
5352
import org.lightningdevkit.ldknode.PaymentId
@@ -120,6 +119,7 @@ import to.bitkit.utils.timedsheets.sheets.QuickPayTimedSheet
120119
import java.math.BigDecimal
121120
import javax.inject.Inject
122121
import kotlin.coroutines.cancellation.CancellationException
122+
import kotlin.time.Duration
123123
import kotlin.time.ExperimentalTime
124124

125125
@OptIn(ExperimentalTime::class)
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package to.bitkit.ui.shared.toast
2+
3+
import kotlinx.coroutines.ExperimentalCoroutinesApi
4+
import kotlinx.coroutines.test.StandardTestDispatcher
5+
import kotlinx.coroutines.test.advanceTimeBy
6+
import org.junit.Assert.assertEquals
7+
import org.junit.Assert.assertNull
8+
import org.junit.Before
9+
import org.junit.Test
10+
import to.bitkit.models.Toast
11+
import to.bitkit.models.ToastType
12+
import to.bitkit.test.BaseUnitTest
13+
import kotlin.time.Duration.Companion.seconds
14+
15+
@OptIn(ExperimentalCoroutinesApi::class)
16+
class ToastQueueTest : BaseUnitTest(StandardTestDispatcher()) {
17+
private lateinit var sut: ToastQueue
18+
19+
@Before
20+
fun setUp() {
21+
sut = ToastQueue(testDispatcher)
22+
}
23+
24+
@Test
25+
fun `enqueue shows toast immediately when queue empty`() = test {
26+
val toast = createToast()
27+
28+
sut.enqueue(toast)
29+
30+
assertEquals(toast, sut.currentToast.value)
31+
}
32+
33+
@Test
34+
fun `enqueue queues toast when another is displayed`() = test {
35+
val toast1 = createToast(title = "First")
36+
val toast2 = createToast(title = "Second")
37+
38+
sut.enqueue(toast1)
39+
sut.enqueue(toast2)
40+
41+
assertEquals("Second", sut.currentToast.value?.title)
42+
}
43+
44+
@Test
45+
fun `dismiss advances to next toast in queue`() = test {
46+
val toast1 = createToast(title = "First", autoHide = false)
47+
val toast2 = createToast(title = "Second", autoHide = false)
48+
49+
sut.enqueue(toast1)
50+
sut.enqueue(toast2)
51+
52+
assertEquals("Second", sut.currentToast.value?.title)
53+
54+
sut.dismissCurrentToast()
55+
56+
assertNull(sut.currentToast.value)
57+
}
58+
59+
@Test
60+
fun `auto-hide timer dismisses toast after duration`() = test {
61+
val toast = createToast(autoHide = true)
62+
63+
sut.enqueue(toast)
64+
65+
assertEquals(toast, sut.currentToast.value)
66+
67+
advanceTimeBy(3001)
68+
69+
assertNull(sut.currentToast.value)
70+
}
71+
72+
@Test
73+
fun `pause stops auto-hide timer`() = test {
74+
val toast = createToast(autoHide = true)
75+
76+
sut.enqueue(toast)
77+
advanceTimeBy(1000)
78+
sut.pauseCurrentToast()
79+
advanceTimeBy(5000)
80+
81+
assertEquals(toast, sut.currentToast.value)
82+
}
83+
84+
@Test
85+
fun `resume restarts auto-hide timer`() = test {
86+
val toast = createToast(autoHide = true)
87+
88+
sut.enqueue(toast)
89+
advanceTimeBy(1000)
90+
sut.pauseCurrentToast()
91+
advanceTimeBy(5000)
92+
sut.resumeCurrentToast()
93+
advanceTimeBy(2000)
94+
95+
assertEquals(toast, sut.currentToast.value)
96+
97+
advanceTimeBy(1001)
98+
99+
assertNull(sut.currentToast.value)
100+
}
101+
102+
@Test
103+
fun `max queue size drops oldest when exceeded`() = test {
104+
val toasts = (1..6).map { createToast(title = "Toast $it") }
105+
106+
toasts.forEach { sut.enqueue(it) }
107+
108+
assertEquals("Toast 6", sut.currentToast.value?.title)
109+
}
110+
111+
@Test
112+
fun `clear removes all toasts and hides current`() = test {
113+
val toast1 = createToast(title = "First", autoHide = false)
114+
val toast2 = createToast(title = "Second", autoHide = false)
115+
116+
sut.enqueue(toast1)
117+
sut.enqueue(toast2)
118+
sut.clear()
119+
120+
assertNull(sut.currentToast.value)
121+
}
122+
123+
@Test
124+
fun `non-auto-hide toast stays until dismissed`() = test {
125+
val toast = createToast(autoHide = false)
126+
127+
sut.enqueue(toast)
128+
advanceTimeBy(10_000)
129+
130+
assertEquals(toast, sut.currentToast.value)
131+
132+
sut.dismissCurrentToast()
133+
134+
assertNull(sut.currentToast.value)
135+
}
136+
137+
private fun createToast(
138+
title: String = "Test Toast",
139+
body: String? = null,
140+
type: ToastType = ToastType.INFO,
141+
autoHide: Boolean = true,
142+
) = Toast(
143+
type = type,
144+
title = title,
145+
body = body,
146+
autoHide = autoHide,
147+
duration = 3.seconds,
148+
)
149+
}

0 commit comments

Comments
 (0)