@@ -9,9 +9,11 @@ import kotlinx.coroutines.flow.flowOf
99import kotlinx.coroutines.test.advanceUntilIdle
1010import org.junit.Before
1111import org.junit.Test
12+ import org.lightningdevkit.ldknode.Event
1213import org.mockito.kotlin.any
1314import org.mockito.kotlin.anyOrNull
1415import org.mockito.kotlin.mock
16+ import org.mockito.kotlin.verify
1517import org.mockito.kotlin.whenever
1618import to.bitkit.data.AppCacheData
1719import to.bitkit.data.CacheStore
@@ -31,6 +33,7 @@ import to.bitkit.repositories.HealthRepo
3133import to.bitkit.repositories.LightningRepo
3234import to.bitkit.repositories.LightningState
3335import to.bitkit.repositories.PendingPaymentRepo
36+ import to.bitkit.repositories.PendingPaymentResolution
3437import to.bitkit.repositories.PreActivityMetadataRepo
3538import to.bitkit.repositories.PubkyRepo
3639import to.bitkit.repositories.PublicPaykitRepo
@@ -79,18 +82,25 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
7982 private val formatMoneyValue = mock<FormatMoneyValue >()
8083
8184 private val balanceState = MutableStateFlow (BalanceState ())
85+ private val nodeEvents = MutableSharedFlow <Event >()
8286
8387 private val timedSheetManager = mock<TimedSheetManager >()
8488
8589 @Before
8690 fun setUp () {
91+ stubRepositories()
92+ sut = createViewModel()
93+ }
94+
95+ private fun stubRepositories () {
8796 whenever(context.getString(any())).thenReturn(" " )
8897 whenever(connectivityRepo.isOnline).thenReturn(MutableStateFlow (ConnectivityState .CONNECTED ))
8998 whenever(healthRepo.healthState).thenReturn(MutableStateFlow (mock()))
9099 whenever(lightningRepo.lightningState).thenReturn(MutableStateFlow (LightningState ()))
91- whenever(lightningRepo.nodeEvents).thenReturn(MutableSharedFlow () )
100+ whenever(lightningRepo.nodeEvents).thenReturn(nodeEvents )
92101 whenever(walletRepo.balanceState).thenReturn(balanceState)
93102 whenever(walletRepo.walletState).thenReturn(MutableStateFlow (WalletState ()))
103+ whenever(walletRepo.walletExists()).thenReturn(true )
94104 whenever(settingsStore.data).thenReturn(flowOf(SettingsData ()))
95105 whenever(cacheStore.data).thenReturn(flowOf(AppCacheData ()))
96106 whenever(transferRepo.activeTransfers).thenReturn(flowOf(emptyList()))
@@ -108,42 +118,42 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
108118 whenever { lightningRepo.getFeeRateForSpeed(any(), anyOrNull()) }
109119 .thenReturn(Result .success(2u ))
110120 whenever { lightningRepo.canSend(any(), any()) }.thenReturn(true )
111-
112- sut = AppViewModel (
113- connectivityRepo = connectivityRepo,
114- healthRepo = healthRepo,
115- toastManagerProvider = { mock<ToastQueueManager >() },
116- timedSheetManagerProvider = { timedSheetManager },
117- context = context,
118- bgDispatcher = testDispatcher,
119- keychain = keychain,
120- lightningRepo = lightningRepo,
121- pendingPaymentRepo = pendingPaymentRepo,
122- walletRepo = walletRepo,
123- backupRepo = backupRepo,
124- settingsStore = settingsStore,
125- currencyRepo = currencyRepo,
126- activityRepo = activityRepo,
127- preActivityMetadataRepo = preActivityMetadataRepo,
128- blocktankRepo = blocktankRepo,
129- appUpdaterService = appUpdaterService,
130- notifyPaymentReceivedHandler = notifyPaymentReceivedHandler,
131- cacheStore = cacheStore,
132- transferRepo = transferRepo,
133- migrationService = migrationService,
134- coreService = coreService,
135- publicPaykitRepo = publicPaykitRepo,
136- appUpdateSheet = mock(),
137- backupSheet = mock(),
138- notificationsSheet = mock(),
139- quickPaySheet = mock(),
140- highBalanceSheet = mock(),
141- formatMoneyValue = formatMoneyValue,
142- widgetsRepo = widgetsRepo,
143- pubkyRepo = pubkyRepo,
144- )
145121 }
146122
123+ private fun createViewModel () = AppViewModel (
124+ connectivityRepo = connectivityRepo,
125+ healthRepo = healthRepo,
126+ toastManagerProvider = { mock<ToastQueueManager >() },
127+ timedSheetManagerProvider = { timedSheetManager },
128+ context = context,
129+ bgDispatcher = testDispatcher,
130+ keychain = keychain,
131+ lightningRepo = lightningRepo,
132+ pendingPaymentRepo = pendingPaymentRepo,
133+ walletRepo = walletRepo,
134+ backupRepo = backupRepo,
135+ settingsStore = settingsStore,
136+ currencyRepo = currencyRepo,
137+ activityRepo = activityRepo,
138+ preActivityMetadataRepo = preActivityMetadataRepo,
139+ blocktankRepo = blocktankRepo,
140+ appUpdaterService = appUpdaterService,
141+ notifyPaymentReceivedHandler = notifyPaymentReceivedHandler,
142+ cacheStore = cacheStore,
143+ transferRepo = transferRepo,
144+ migrationService = migrationService,
145+ coreService = coreService,
146+ publicPaykitRepo = publicPaykitRepo,
147+ appUpdateSheet = mock(),
148+ backupSheet = mock(),
149+ notificationsSheet = mock(),
150+ quickPaySheet = mock(),
151+ highBalanceSheet = mock(),
152+ formatMoneyValue = formatMoneyValue,
153+ widgetsRepo = widgetsRepo,
154+ pubkyRepo = pubkyRepo,
155+ )
156+
147157 @Test
148158 fun `canSwitchWallet is false when not unified` () = test {
149159 sut.setSendEvent(SendEvent .AmountChange (1000u ))
@@ -254,6 +264,30 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
254264 assertEquals(before, sut.sendUiState.value.payMethod)
255265 }
256266
267+ @Test
268+ fun `pending contact lightning success tags activity` () = test {
269+ val contactKey = " pubkycontact"
270+ val paymentHash = " pending_hash"
271+ whenever(pendingPaymentRepo.isPending(paymentHash)).thenReturn(true )
272+ whenever(pendingPaymentRepo.isActive(paymentHash)).thenReturn(false )
273+ whenever(activityRepo.setContact(contactKey, paymentHash)).thenReturn(Result .success(Unit ))
274+ advanceUntilIdle()
275+
276+ setPendingContactPaymentContext(paymentHash, contactKey)
277+ nodeEvents.emit(
278+ Event .PaymentSuccessful (
279+ paymentId = " payment_id" ,
280+ paymentHash = paymentHash,
281+ paymentPreimage = " preimage" ,
282+ feePaidMsat = 10uL ,
283+ ),
284+ )
285+ advanceUntilIdle()
286+
287+ verify(pendingPaymentRepo).resolve(PendingPaymentResolution .Success (paymentHash))
288+ verify(activityRepo).setContact(contactPublicKey = contactKey, forPaymentId = paymentHash)
289+ }
290+
257291 @Test
258292 fun `amount change clears confirmedWarnings` () = test {
259293 setUnifiedState(amount = 1000u )
@@ -307,6 +341,14 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
307341 assertEquals(0L , sut.sendUiState.value.lastLightningFee)
308342 }
309343
344+ @Suppress(" UNCHECKED_CAST" )
345+ private fun setPendingContactPaymentContext (paymentHash : String , publicKey : String ) {
346+ val field = AppViewModel ::class .java.getDeclaredField(" pendingContactPaymentContexts" )
347+ field.isAccessible = true
348+ val contexts = field.get(sut) as MutableMap <String , ContactPaymentContext >
349+ contexts[paymentHash] = ContactPaymentContext (publicKey)
350+ }
351+
310352 @Suppress(" UNCHECKED_CAST" )
311353 private fun setSendState (state : SendUiState ) {
312354 val field = AppViewModel ::class .java.getDeclaredField(" _sendUiState" )
0 commit comments