@@ -10,31 +10,35 @@ import org.junit.Before
1010import org.junit.Test
1111import org.mockito.kotlin.doReturn
1212import org.mockito.kotlin.mock
13+ import org.mockito.kotlin.mockingDetails
1314import org.mockito.kotlin.whenever
1415import to.bitkit.R
1516import to.bitkit.data.SettingsStore
17+ import to.bitkit.ext.create
1618import to.bitkit.test.BaseUnitTest
1719import to.bitkit.viewmodels.ActivityDetailViewModel
1820import kotlin.test.assertEquals
1921import kotlin.test.assertNull
2022import kotlin.test.assertTrue
2123
2224class ActivityDetailViewModelTest : BaseUnitTest () {
25+ private lateinit var sut: ActivityDetailViewModel
2326
2427 private val context = mock<Context >()
2528 private val activityRepo = mock<ActivityRepo >()
2629 private val blocktankRepo = mock<BlocktankRepo >()
2730 private val settingsStore = mock<SettingsStore >()
2831 private val lightningRepo = mock<LightningRepo >()
2932
30- private lateinit var sut: ActivityDetailViewModel
33+ companion object Fixtures {
34+ const val ACTIVITY_ID = " test-activity-1"
35+ const val ORDER_ID = " test-order-id"
36+ }
3137
3238 @Before
3339 fun setUp () {
34- whenever(context.getString(R .string.wallet__activity_error_not_found))
35- .thenReturn(" Activity not found" )
36- whenever(context.getString(R .string.wallet__activity_error_load_failed))
37- .thenReturn(" Failed to load activity" )
40+ whenever(context.getString(R .string.wallet__activity_error_not_found)).thenReturn(" Activity not found" )
41+ whenever(context.getString(R .string.wallet__activity_error_load_failed)).thenReturn(" Failed to load activity" )
3842 whenever(blocktankRepo.blocktankState).thenReturn(MutableStateFlow (BlocktankState ()))
3943 whenever(activityRepo.activitiesChanged).thenReturn(MutableStateFlow (System .currentTimeMillis()))
4044
@@ -57,41 +61,27 @@ class ActivityDetailViewModelTest : BaseUnitTest() {
5761
5862 @Test
5963 fun `findOrderForTransfer finds order by channelId` () = test {
60- val orderId = " test-order-id"
61- val mockOrder = mock<IBtOrder > {
62- on { id } doReturn orderId
63- }
64-
65- whenever(blocktankRepo.blocktankState).thenReturn(
66- MutableStateFlow (BlocktankState (orders = listOf (mockOrder)))
67- )
64+ val order = mock<IBtOrder > { on { id } doReturn ORDER_ID }
65+ whenever(blocktankRepo.blocktankState).thenReturn(MutableStateFlow (BlocktankState (orders = listOf (order))))
6866
69- val result = sut.findOrderForTransfer(orderId , null )
67+ val result = sut.findOrderForTransfer(ORDER_ID , null )
7068
71- assertEquals(mockOrder , result)
69+ assertEquals(order , result)
7270 }
7371
7472 @Test
7573 fun `findOrderForTransfer finds order by channelId matching order id` () = test {
76- val orderId = " order-123"
77- val mockOrder = mock<IBtOrder > {
78- on { id } doReturn orderId
79- }
74+ val order = mock<IBtOrder > { on { id } doReturn ORDER_ID }
75+ whenever(blocktankRepo.blocktankState).thenReturn(MutableStateFlow (BlocktankState (orders = listOf (order))))
8076
81- whenever(blocktankRepo.blocktankState).thenReturn(
82- MutableStateFlow (BlocktankState (orders = listOf (mockOrder)))
83- )
84-
85- val result = sut.findOrderForTransfer(orderId, null )
77+ val result = sut.findOrderForTransfer(ORDER_ID , null )
8678
87- assertEquals(mockOrder , result)
79+ assertEquals(order , result)
8880 }
8981
9082 @Test
9183 fun `findOrderForTransfer returns null when order not found` () = test {
92- whenever(blocktankRepo.blocktankState).thenReturn(
93- MutableStateFlow (BlocktankState (orders = emptyList()))
94- )
84+ whenever(blocktankRepo.blocktankState).thenReturn(MutableStateFlow (BlocktankState (orders = emptyList())))
9585
9686 val result = sut.findOrderForTransfer(" non-existent-id" , null )
9787
@@ -100,97 +90,83 @@ class ActivityDetailViewModelTest : BaseUnitTest() {
10090
10191 @Test
10292 fun `loadActivity starts observation of activity changes` () = test {
103- val activityId = " test-activity-1"
104- val initialActivity = createTestActivity(activityId, confirmed = false )
105- val updatedActivity = createTestActivity(activityId, confirmed = true )
93+ val initialActivity = createTestActivity(ACTIVITY_ID , confirmed = false )
94+ val updatedActivity = createTestActivity(ACTIVITY_ID , confirmed = true )
10695 val activitiesChangedFlow = MutableStateFlow (System .currentTimeMillis())
10796
10897 whenever(activityRepo.activitiesChanged).thenReturn(activitiesChangedFlow)
109- whenever(activityRepo.getActivity(activityId))
110- .thenReturn(Result .success(initialActivity))
111- whenever(activityRepo.getActivityTags(activityId))
112- .thenReturn(Result .success(emptyList()))
98+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .success(initialActivity))
99+ whenever(activityRepo.getActivityTags(ACTIVITY_ID )).thenReturn(Result .success(emptyList()))
113100
114101 // Load activity
115- sut.loadActivity(activityId )
102+ sut.loadActivity(ACTIVITY_ID )
116103
117104 // Verify initial state loaded
118105 val initialState = sut.uiState.value.activityLoadState
119106 assertTrue(initialState is ActivityDetailViewModel .ActivityLoadState .Success )
120- assertEquals(initialActivity, ( initialState as ActivityDetailViewModel . ActivityLoadState . Success ) .activity)
107+ assertEquals(initialActivity, initialState.activity)
121108
122109 // Simulate activity update
123- whenever(activityRepo.getActivity(activityId))
124- .thenReturn(Result .success(updatedActivity))
110+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .success(updatedActivity))
125111 activitiesChangedFlow.value = System .currentTimeMillis()
126112
127113 // Verify ViewModel reflects updated activity
128114 val updatedState = sut.uiState.value.activityLoadState
129115 assertTrue(updatedState is ActivityDetailViewModel .ActivityLoadState .Success )
130- assertEquals(updatedActivity, ( updatedState as ActivityDetailViewModel . ActivityLoadState . Success ) .activity)
116+ assertEquals(updatedActivity, updatedState.activity)
131117 }
132118
133119 @Test
134120 fun `clearActivityState stops observation` () = test {
135- val activityId = " test-activity-1"
136- val activity = createTestActivity(activityId)
121+ val activity = createTestActivity(ACTIVITY_ID )
137122 val activitiesChangedFlow = MutableStateFlow (System .currentTimeMillis())
138123
139124 whenever(activityRepo.activitiesChanged).thenReturn(activitiesChangedFlow)
140- whenever(activityRepo.getActivity(activityId))
141- .thenReturn(Result .success(activity))
142- whenever(activityRepo.getActivityTags(activityId))
143- .thenReturn(Result .success(emptyList()))
125+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .success(activity))
126+ whenever(activityRepo.getActivityTags(ACTIVITY_ID )).thenReturn(Result .success(emptyList()))
144127
145128 // Load activity
146- sut.loadActivity(activityId )
129+ sut.loadActivity(ACTIVITY_ID )
147130
148131 // Clear state
149132 sut.clearActivityState()
150133
151134 // Trigger activity change
152- val callCountBefore = org.mockito.kotlin. mockingDetails(activityRepo).invocations.size
135+ val callCountBefore = mockingDetails(activityRepo).invocations.size
153136 activitiesChangedFlow.value = System .currentTimeMillis()
154137
155138 // Verify no reload after clear (getActivity not called again)
156- val callCountAfter = org.mockito.kotlin. mockingDetails(activityRepo).invocations.size
139+ val callCountAfter = mockingDetails(activityRepo).invocations.size
157140 assertEquals(callCountBefore, callCountAfter)
158141 }
159142
160143 @Test
161144 fun `reloadActivity keeps last state on failure` () = test {
162- val activityId = " test-activity-1"
163- val activity = createTestActivity(activityId)
145+ val activity = createTestActivity(ACTIVITY_ID )
164146 val activitiesChangedFlow = MutableStateFlow (System .currentTimeMillis())
165147
166148 whenever(activityRepo.activitiesChanged).thenReturn(activitiesChangedFlow)
167- whenever(activityRepo.getActivity(activityId))
168- .thenReturn(Result .success(activity))
169- whenever(activityRepo.getActivityTags(activityId))
170- .thenReturn(Result .success(emptyList()))
149+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .success(activity))
150+ whenever(activityRepo.getActivityTags(ACTIVITY_ID )).thenReturn(Result .success(emptyList()))
171151
172152 // Load activity
173- sut.loadActivity(activityId )
153+ sut.loadActivity(ACTIVITY_ID )
174154
175155 // Simulate reload failure
176- whenever(activityRepo.getActivity(activityId))
177- .thenReturn(Result .failure(Exception (" Network error" )))
156+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .failure(Exception (" Network error" )))
178157 activitiesChangedFlow.value = System .currentTimeMillis()
179158
180159 // Verify last known state is preserved
181160 val state = sut.uiState.value.activityLoadState
182161 assertTrue(state is ActivityDetailViewModel .ActivityLoadState .Success )
183- assertEquals(activity, ( state as ActivityDetailViewModel . ActivityLoadState . Success ) .activity)
162+ assertEquals(activity, state.activity)
184163 }
185164
186165 @Test
187166 fun `loadActivity handles error gracefully` () = test {
188- val activityId = " test-activity-1"
189-
190- whenever(activityRepo.getActivity(activityId))
191- .thenReturn(Result .failure(Exception (" Database error" )))
167+ whenever(activityRepo.getActivity(ACTIVITY_ID )).thenReturn(Result .failure(Exception (" Database error" )))
192168
193- sut.loadActivity(activityId )
169+ sut.loadActivity(ACTIVITY_ID )
194170
195171 val state = sut.uiState.value.activityLoadState
196172 assertTrue(state is ActivityDetailViewModel .ActivityLoadState .Error )
@@ -201,7 +177,7 @@ class ActivityDetailViewModelTest : BaseUnitTest() {
201177 confirmed : Boolean = false,
202178 ): Activity .Onchain {
203179 return Activity .Onchain (
204- v1 = OnchainActivity (
180+ v1 = OnchainActivity .create (
205181 id = id,
206182 txType = PaymentType .RECEIVED ,
207183 txId = " tx-$id " ,
@@ -211,15 +187,7 @@ class ActivityDetailViewModelTest : BaseUnitTest() {
211187 address = " bc1..." ,
212188 confirmed = confirmed,
213189 timestamp = (System .currentTimeMillis() / 1000 ).toULong(),
214- isBoosted = false ,
215- boostTxIds = emptyList(),
216- isTransfer = false ,
217- doesExist = true ,
218190 confirmTimestamp = if (confirmed) (System .currentTimeMillis() / 1000 ).toULong() else null ,
219- channelId = null ,
220- transferTxId = null ,
221- createdAt = null ,
222- updatedAt = null ,
223191 )
224192 )
225193 }
0 commit comments