@@ -6,6 +6,7 @@ import com.synonym.bitkitcore.IBtChannel
66import com.synonym.bitkitcore.IBtOrder
77import kotlinx.coroutines.flow.MutableStateFlow
88import kotlinx.coroutines.flow.flowOf
9+ import kotlinx.datetime.Clock
910import org.junit.Before
1011import org.junit.Test
1112import org.lightningdevkit.ldknode.ChannelDetails
@@ -32,11 +33,12 @@ import kotlin.test.assertTrue
3233
3334class TransferRepoTest : BaseUnitTest () {
3435
36+ private lateinit var sut: TransferRepo
37+
3538 private val transferDao: TransferDao = mock()
3639 private val lightningRepo: LightningRepo = mock()
3740 private val blocktankRepo: BlocktankRepo = mock()
38-
39- private lateinit var sut: TransferRepo
41+ private val clock: Clock = mock()
4042
4143 private val testTransferId = " test-transfer-id"
4244 private val testChannelId = " test-channel-id"
@@ -52,14 +54,16 @@ class TransferRepoTest : BaseUnitTest() {
5254 lightningRepo = lightningRepo,
5355 blocktankRepo = blocktankRepo,
5456 transferDao = transferDao,
57+ clock = clock,
5558 )
5659 }
5760
5861 // createTransfer tests
5962
6063 @Test
6164 fun `createTransfer creates TO_SPENDING transfer - LSP flow with lspOrderId, no channelId yet` () = test {
62- wheneverBlocking { transferDao.insert(any()) }.thenReturn(Unit )
65+ setupClockNowMock()
66+ whenever(transferDao.insert(any())).thenReturn(Unit )
6367
6468 val result = sut.createTransfer(
6569 type = TransferType .TO_SPENDING ,
@@ -77,7 +81,8 @@ class TransferRepoTest : BaseUnitTest() {
7781
7882 @Test
7983 fun `createTransfer creates COOP_CLOSE transfer` () = test {
80- wheneverBlocking { transferDao.insert(any()) }.thenReturn(Unit )
84+ setupClockNowMock()
85+ whenever(transferDao.insert(any())).thenReturn(Unit )
8186
8287 val result = sut.createTransfer(
8388 type = TransferType .COOP_CLOSE ,
@@ -93,7 +98,8 @@ class TransferRepoTest : BaseUnitTest() {
9398
9499 @Test
95100 fun `createTransfer creates FORCE_CLOSE transfer` () = test {
96- wheneverBlocking { transferDao.insert(any()) }.thenReturn(Unit )
101+ setupClockNowMock()
102+ whenever(transferDao.insert(any())).thenReturn(Unit )
97103
98104 val result = sut.createTransfer(
99105 type = TransferType .FORCE_CLOSE ,
@@ -109,7 +115,8 @@ class TransferRepoTest : BaseUnitTest() {
109115
110116 @Test
111117 fun `createTransfer creates MANUAL_SETUP transfer - channelId and fundingTxId known immediately` () = test {
112- wheneverBlocking { transferDao.insert(any()) }.thenReturn(Unit )
118+ setupClockNowMock()
119+ whenever(transferDao.insert(any())).thenReturn(Unit )
113120
114121 val result = sut.createTransfer(
115122 type = TransferType .MANUAL_SETUP ,
@@ -125,6 +132,7 @@ class TransferRepoTest : BaseUnitTest() {
125132
126133 @Test
127134 fun `createTransfer handles database insertion failure` () = test {
135+ setupClockNowMock()
128136 val exception = Exception (" Database error" )
129137 whenever(transferDao.insert(any())).thenAnswer { throw exception }
130138
@@ -139,6 +147,7 @@ class TransferRepoTest : BaseUnitTest() {
139147
140148 @Test
141149 fun `createTransfer generates unique IDs for each transfer` () = test {
150+ setupClockNowMock()
142151 val capturedTransfers = mutableListOf<TransferEntity >()
143152 wheneverBlocking { transferDao.insert(any()) }.thenAnswer { invocation ->
144153 capturedTransfers.add(invocation.getArgument(0 ))
@@ -161,16 +170,18 @@ class TransferRepoTest : BaseUnitTest() {
161170
162171 @Test
163172 fun `markSettled successfully marks transfer as settled` () = test {
164- wheneverBlocking { transferDao.markSettled(any(), any()) }.thenReturn(Unit )
173+ val settledAt = setupClockNowMock()
174+ whenever(transferDao.markSettled(any(), any())).thenReturn(Unit )
165175
166176 val result = sut.markSettled(testTransferId)
167177
168178 assertTrue(result.isSuccess)
169- verify(transferDao).markSettled(eq(testTransferId), any( ))
179+ verify(transferDao).markSettled(eq(testTransferId), eq(settledAt ))
170180 }
171181
172182 @Test
173183 fun `markSettled handles database update failure` () = test {
184+ setupClockNowMock()
174185 val exception = Exception (" Database error" )
175186 whenever(transferDao.markSettled(any(), any())).thenAnswer { throw exception }
176187
@@ -194,6 +205,7 @@ class TransferRepoTest : BaseUnitTest() {
194205
195206 @Test
196207 fun `syncTransferStates settles TO_SPENDING transfer when channel is ready` () = test {
208+ val settledAt = setupClockNowMock()
197209 val transfer = TransferEntity (
198210 id = testTransferId,
199211 type = TransferType .TO_SPENDING ,
@@ -216,7 +228,7 @@ class TransferRepoTest : BaseUnitTest() {
216228 val result = sut.syncTransferStates()
217229
218230 assertTrue(result.isSuccess)
219- verify(transferDao).markSettled(eq(testTransferId), any( ))
231+ verify(transferDao).markSettled(eq(testTransferId), eq(settledAt ))
220232 }
221233
222234 @Test
@@ -268,6 +280,7 @@ class TransferRepoTest : BaseUnitTest() {
268280
269281 @Test
270282 fun `syncTransferStates settles TO_SAVINGS transfer when balance is swept` () = test {
283+ val settledAt = setupClockNowMock()
271284 val transfer = TransferEntity (
272285 id = testTransferId,
273286 type = TransferType .TO_SAVINGS ,
@@ -294,7 +307,7 @@ class TransferRepoTest : BaseUnitTest() {
294307 val result = sut.syncTransferStates()
295308
296309 assertTrue(result.isSuccess)
297- verify(transferDao).markSettled(eq(testTransferId), any( ))
310+ verify(transferDao).markSettled(eq(testTransferId), eq(settledAt ))
298311 }
299312
300313 @Test
@@ -340,6 +353,7 @@ class TransferRepoTest : BaseUnitTest() {
340353
341354 @Test
342355 fun `syncTransferStates settles TO_SAVINGS transfer when balances is null` () = test {
356+ val settledAt = setupClockNowMock()
343357 val transfer = TransferEntity (
344358 id = testTransferId,
345359 type = TransferType .TO_SAVINGS ,
@@ -357,11 +371,12 @@ class TransferRepoTest : BaseUnitTest() {
357371 val result = sut.syncTransferStates()
358372
359373 assertTrue(result.isSuccess)
360- verify(transferDao).markSettled(eq(testTransferId), any( ))
374+ verify(transferDao).markSettled(eq(testTransferId), eq(settledAt ))
361375 }
362376
363377 @Test
364378 fun `syncTransferStates handles mixed transfer types correctly` () = test {
379+ val settledAt = setupClockNowMock()
365380 val toSpendingTransfer = TransferEntity (
366381 id = " spending-transfer" ,
367382 type = TransferType .TO_SPENDING ,
@@ -404,8 +419,8 @@ class TransferRepoTest : BaseUnitTest() {
404419 val result = sut.syncTransferStates()
405420
406421 assertTrue(result.isSuccess)
407- verify(transferDao).markSettled(eq(" spending-transfer" ), any( ))
408- verify(transferDao).markSettled(eq(" savings-transfer" ), any( ))
422+ verify(transferDao).markSettled(eq(" spending-transfer" ), eq(settledAt ))
423+ verify(transferDao).markSettled(eq(" savings-transfer" ), eq(settledAt ))
409424 }
410425
411426 @Test
@@ -613,11 +628,16 @@ class TransferRepoTest : BaseUnitTest() {
613628 lightningRepo = lightningRepo,
614629 blocktankRepo = blocktankRepo,
615630 transferDao = transferDao,
631+ clock = clock,
616632 )
617633
618634 testSut.activeTransfers.test {
619635 assertEquals(transfers, awaitItem())
620636 cancelAndIgnoreRemainingEvents()
621637 }
622638 }
639+
640+ private fun setupClockNowMock (): Long = Clock .System .now()
641+ .also { whenever(clock.now()).thenReturn(it) }
642+ .epochSeconds
623643}
0 commit comments