diff options
| author | Albin <albin@mullvad.net> | 2022-05-03 16:37:20 +0200 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2022-05-17 15:06:04 +0200 |
| commit | d2b3deb89ba20cb0af6e82cad85e718624bb20df (patch) | |
| tree | da3bbe450396253b66029640c7c4f5126d8bddc2 /android | |
| parent | f00ad159a30c12c778e1602d277425f9e196d2ff (diff) | |
| download | mullvadvpn-d2b3deb89ba20cb0af6e82cad85e718624bb20df.tar.xz mullvadvpn-d2b3deb89ba20cb0af6e82cad85e718624bb20df.zip | |
Fix login vm unit tests
Diffstat (limited to 'android')
| -rw-r--r-- | android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt | 7 | ||||
| -rw-r--r-- | android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt | 136 |
2 files changed, 38 insertions, 105 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt index 4ec72c529d..cb4f151fd1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt @@ -84,9 +84,10 @@ class LoginViewModel( } private fun AccountCreationResult.mapToUiState(): LoginUiState { - return when (this) { - is AccountCreationResult.Success -> LoginUiState.AccountCreated - AccountCreationResult.Failure -> LoginUiState.UnableToCreateAccountError + return if (this is AccountCreationResult.Success) { + LoginUiState.AccountCreated + } else { + LoginUiState.UnableToCreateAccountError } } diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt index 174c378e23..6147a77a1d 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt @@ -3,20 +3,21 @@ package net.mullvad.mullvadvpn.viewmodel import app.cash.turbine.FlowTurbine import app.cash.turbine.test import io.mockk.MockKAnnotations -import io.mockk.Runs import io.mockk.every import io.mockk.impl.annotations.MockK -import io.mockk.invoke -import io.mockk.just import io.mockk.mockk -import io.mockk.slot import io.mockk.verify import junit.framework.Assert.assertEquals +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.runBlockingTest +import kotlinx.coroutines.test.setMain +import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.model.AccountCreationResult +import net.mullvad.mullvadvpn.model.AccountHistory import net.mullvad.mullvadvpn.model.LoginResult -import net.mullvad.mullvadvpn.model.LoginStatus import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache -import net.mullvad.talpid.util.EventNotifier import org.junit.Before import org.junit.Test @@ -25,37 +26,20 @@ class LoginViewModelTest { @MockK private lateinit var mockedAccountCache: AccountCache - @MockK - private lateinit var mockedLoginStatusNotifier: EventNotifier<LoginStatus?> - - @MockK - private lateinit var mockedAccountHistoryNotifier: EventNotifier<String?> - private lateinit var loginViewModel: LoginViewModel - private val capturedLoginStatusNotifierCallback = slot<(LoginStatus?) -> Unit>() - private val capturedAccountHistoryNotifierCallback = slot<(String?) -> Unit>() + + private val accountCreationTestEvents = MutableSharedFlow<AccountCreationResult>() + private val accountHistoryTestEvents = MutableSharedFlow<AccountHistory>() + private val loginTestEvents = MutableSharedFlow<Event.LoginEvent>() @Before fun setup() { + Dispatchers.setMain(TestCoroutineDispatcher()) MockKAnnotations.init(this, relaxUnitFun = true) - every { - mockedLoginStatusNotifier.subscribe( - any(), - any(), - capture(capturedLoginStatusNotifierCallback) - ) - } just Runs - - every { - mockedAccountHistoryNotifier.subscribe( - any(), - capture(capturedAccountHistoryNotifierCallback) - ) - } just Runs - - every { mockedAccountCache.onLoginStatusChange } returns mockedLoginStatusNotifier - every { mockedAccountCache.onAccountHistoryChange } returns mockedAccountHistoryNotifier + every { mockedAccountCache.accountCreationEvents } returns accountCreationTestEvents + every { mockedAccountCache.accountHistoryEvents } returns accountHistoryTestEvents + every { mockedAccountCache.loginEvents } returns loginTestEvents loginViewModel = LoginViewModel(mockk()) } @@ -69,23 +53,13 @@ class LoginViewModelTest { } @Test - fun testClearingViewModel() { - loginViewModel.updateAccountCacheInstance(mockedAccountCache) - loginViewModel.onCleared() - verify { - mockedLoginStatusNotifier.unsubscribe(any()) - mockedAccountHistoryNotifier.unsubscribe(any()) - } - } - - @Test fun testCreateAccount() = runBlockingTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() loginViewModel.createAccount() assertEquals(LoginViewModel.LoginUiState.CreatingAccount, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke(DummyLoginStatus.ACCOUNT_CREATED) + accountCreationTestEvents.emit(AccountCreationResult.Success(DUMMY_ACCOUNT_TOKEN)) assertEquals(LoginViewModel.LoginUiState.AccountCreated, awaitItem()) } } @@ -95,9 +69,9 @@ class LoginViewModelTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() - loginViewModel.login("") + loginViewModel.login(DUMMY_ACCOUNT_TOKEN) assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke(DummyLoginStatus.SUCCESSFUL_LOGIN) + loginTestEvents.emit(Event.LoginEvent(LoginResult.Ok)) assertEquals(LoginViewModel.LoginUiState.Success(isOutOfTime = false), awaitItem()) } } @@ -107,11 +81,9 @@ class LoginViewModelTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() - loginViewModel.login("") + loginViewModel.login(DUMMY_ACCOUNT_TOKEN) assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke( - DummyLoginStatus.INVALID_ACCOUNT_ERROR - ) + loginTestEvents.emit(Event.LoginEvent(LoginResult.InvalidAccount)) assertEquals(LoginViewModel.LoginUiState.InvalidAccountError, awaitItem()) } } @@ -121,9 +93,9 @@ class LoginViewModelTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() - loginViewModel.login("") + loginViewModel.login(DUMMY_ACCOUNT_TOKEN) assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke(DummyLoginStatus.MAX_DEVICES_ERROR) + loginTestEvents.emit(Event.LoginEvent(LoginResult.MaxDevicesReached)) assertEquals(LoginViewModel.LoginUiState.TooManyDevicesError, awaitItem()) } } @@ -133,10 +105,10 @@ class LoginViewModelTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() - loginViewModel.login("") + loginViewModel.login(DUMMY_ACCOUNT_TOKEN) assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke(DummyLoginStatus.RPC_ERROR) - assertEquals(LoginViewModel.LoginUiState.OtherError("RpcError"), awaitItem()) + loginTestEvents.emit(Event.LoginEvent(LoginResult.RpcError)) + assertEquals(LoginViewModel.LoginUiState.OtherError(EXPECTED_RPC_ERROR_MESSAGE), awaitItem()) } } @@ -145,10 +117,10 @@ class LoginViewModelTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.uiState.test { skipDefaultItem() - loginViewModel.login("") + loginViewModel.login(DUMMY_ACCOUNT_TOKEN) assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem()) - capturedLoginStatusNotifierCallback.captured.invoke(DummyLoginStatus.OTHER_ERROR) - assertEquals(LoginViewModel.LoginUiState.OtherError("OtherError"), awaitItem()) + loginTestEvents.emit(Event.LoginEvent(LoginResult.OtherError)) + assertEquals(LoginViewModel.LoginUiState.OtherError(EXPECTED_OTHER_ERROR_MESSAGE), awaitItem()) } } @@ -156,8 +128,10 @@ class LoginViewModelTest { fun testAccountHistory() = runBlockingTest { loginViewModel.updateAccountCacheInstance(mockedAccountCache) loginViewModel.accountHistory.test { skipDefaultItem() } - capturedAccountHistoryNotifierCallback.invoke(DUMMY_ACCOUNT_TOKEN) - loginViewModel.accountHistory.test { assertEquals(DUMMY_ACCOUNT_TOKEN, awaitItem()) } + accountHistoryTestEvents.emit(AccountHistory.Available(DUMMY_ACCOUNT_TOKEN)) + loginViewModel.accountHistory.test { + assertEquals(AccountHistory.Available(DUMMY_ACCOUNT_TOKEN), awaitItem()) + } } @Test @@ -173,49 +147,7 @@ class LoginViewModelTest { companion object { private const val DUMMY_ACCOUNT_TOKEN = "DUMMY" - - private object DummyLoginStatus { - val ACCOUNT_CREATED = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = true, - mockk() - ) - - val SUCCESSFUL_LOGIN = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = false, - LoginResult.Ok - ) - - val INVALID_ACCOUNT_ERROR = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = false, - LoginResult.InvalidAccount - ) - - val MAX_DEVICES_ERROR = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = false, - LoginResult.MaxDevicesReached - ) - - val RPC_ERROR = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = false, - LoginResult.RpcError - ) - - val OTHER_ERROR = LoginStatus( - DUMMY_ACCOUNT_TOKEN, - mockk(), - isNewAccount = false, - LoginResult.OtherError - ) - } + private const val EXPECTED_RPC_ERROR_MESSAGE = "RpcError" + private const val EXPECTED_OTHER_ERROR_MESSAGE = "OtherError" } } |
