secant-android-wallet/ui-lib/src/androidTest/java/co/electriccoin/zcash/ui/screen/update/integration/UpdateViewModelTest.kt

108 lines
4.1 KiB
Kotlin

package co.electriccoin.zcash.ui.screen.update.integration
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.lifecycle.viewModelScope
import androidx.test.filters.MediumTest
import co.electriccoin.zcash.ui.common.UiTestingActivity
import co.electriccoin.zcash.ui.screen.update.AppUpdateChecker
import co.electriccoin.zcash.ui.screen.update.fixture.UpdateInfoFixture
import co.electriccoin.zcash.ui.screen.update.model.UpdateInfo
import co.electriccoin.zcash.ui.screen.update.model.UpdateState
import co.electriccoin.zcash.ui.screen.update.view.AppUpdateCheckerMock
import co.electriccoin.zcash.ui.screen.update.viewmodel.UpdateViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collectIndexed
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
@ExperimentalCoroutinesApi
class UpdateViewModelTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<UiTestingActivity>()
private lateinit var viewModel: UpdateViewModel
private lateinit var checker: AppUpdateCheckerMock
private lateinit var initialUpdateInfo: UpdateInfo
@Before
fun setup() {
checker = AppUpdateCheckerMock.new()
initialUpdateInfo = UpdateInfoFixture.new(
appUpdateInfo = null,
state = UpdateState.Prepared,
priority = AppUpdateChecker.Priority.LOW,
force = false
)
viewModel = UpdateViewModel(
composeTestRule.activity.application,
initialUpdateInfo,
checker
)
}
@After
fun cleanup() {
viewModel.viewModelScope.cancel()
}
@Test
@MediumTest
fun validate_result_of_update_methods_calls() = runTest {
viewModel.checkForAppUpdate()
// Although this test does not copy the real world situation, as the initial and result objects
// should be mostly the same, we test VM proper functionality. VM emits the initial object
// defined in this class, then we expect the result object from the AppUpdateCheckerMock class
// and a newly acquired AppUpdateInfo object.
viewModel.updateInfo.take(4).collectIndexed { index, incomingInfo ->
when (index) {
0 -> {
// checkForAppUpdate initial callback
incomingInfo.also {
assertNull(it.appUpdateInfo)
assertEquals(initialUpdateInfo.state, it.state)
assertEquals(initialUpdateInfo.appUpdateInfo, it.appUpdateInfo)
assertEquals(initialUpdateInfo.priority, it.priority)
assertEquals(initialUpdateInfo.state, it.state)
assertEquals(initialUpdateInfo.isForce, it.isForce)
}
}
1 -> {
// checkForAppUpdate result callback
incomingInfo.also {
assertNotNull(it.appUpdateInfo)
assertEquals(AppUpdateCheckerMock.resultUpdateInfo.state, it.state)
assertEquals(AppUpdateCheckerMock.resultUpdateInfo.priority, it.priority)
assertEquals(AppUpdateCheckerMock.resultUpdateInfo.isForce, it.isForce)
}
// now we can start the update
viewModel.goForUpdate(composeTestRule.activity, incomingInfo.appUpdateInfo!!)
}
2 -> {
// goForUpdate initial callback
assertNotNull(incomingInfo.appUpdateInfo)
assertEquals(UpdateState.Running, incomingInfo.state)
}
3 -> {
// goForUpdate result callback
assertNotNull(incomingInfo.appUpdateInfo)
assertEquals(UpdateState.Done, incomingInfo.state)
}
}
}
}
}