Skip to content

Commit

Permalink
Merge pull request #18457 from wordpress-mobile/feature/enable-accoun…
Browse files Browse the repository at this point in the history
…t-closure--add-unit-tests

Add unit tests for the account closure feature
  • Loading branch information
Antonis Lilis authored May 18, 2023
2 parents 011c091 + bdf5833 commit 229c44c
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.wordpress.android.R
import org.wordpress.android.WordPress
import org.wordpress.android.fluxc.network.rest.wpcom.account.AccountRestClient
import org.wordpress.android.fluxc.network.rest.wpcom.account.CloseAccountResult
import org.wordpress.android.fluxc.network.rest.wpcom.account.closeAccount
import org.wordpress.android.fluxc.store.AccountStore.AccountError
import org.wordpress.android.fluxc.store.AccountStore.AccountErrorType.SETTINGS_FETCH_GENERIC_ERROR
import org.wordpress.android.fluxc.store.AccountStore.AccountErrorType.SETTINGS_FETCH_REAUTHORIZATION_REQUIRED_ERROR
Expand All @@ -30,6 +28,7 @@ import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.A
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.AccountClosureUiState.Opened.Error
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.AccountClosureUiState.Opened.Default
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.AccountClosureUiState.Opened.Success
import org.wordpress.android.ui.prefs.accountsettings.usecase.AccountClosureUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.FetchAccountSettingsUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.GetAccountUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.GetSitesUseCase
Expand All @@ -56,7 +55,7 @@ class AccountSettingsViewModel @Inject constructor(
private val getAccountUseCase: GetAccountUseCase,
private val getSitesUseCase: GetSitesUseCase,
private val optimisticUpdateHandler: AccountSettingsOptimisticUpdateHandler,
private val accountRestClient: AccountRestClient,
private val accountClosureUseCase: AccountClosureUseCase,
) : ScopedViewModel(mainDispatcher) {
private var fetchNewSettingsJob: Job? = null
private var _accountSettingsUiState = MutableStateFlow(getAccountSettingsUiState(true))
Expand Down Expand Up @@ -334,7 +333,7 @@ class AccountSettingsViewModel @Inject constructor(
_accountClosureUiState.value = uiState.copy(isPending = true)

launch {
accountRestClient.closeAccount(
accountClosureUseCase.closeAccount(
onResult = {
when(it) {
is CloseAccountResult.Success -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.wordpress.android.ui.prefs.accountsettings.usecase

import org.wordpress.android.fluxc.network.rest.wpcom.account.AccountRestClient
import org.wordpress.android.fluxc.network.rest.wpcom.account.CloseAccountResult
import org.wordpress.android.fluxc.network.rest.wpcom.account.closeAccount
import javax.inject.Inject

class AccountClosureUseCase @Inject constructor(
private val accountRestClient: AccountRestClient,
) {
fun closeAccount(onResult: (CloseAccountResult) -> Unit) = accountRestClient.closeAccount(onResult)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.wordpress.android.ui.prefs.accountsettings

import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.toList
Expand All @@ -8,17 +9,21 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.wordpress.android.BaseUnitTest
import org.wordpress.android.R.string
import org.wordpress.android.fluxc.model.AccountModel
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpcom.account.CloseAccountResult
import org.wordpress.android.fluxc.store.AccountStore.AccountError
import org.wordpress.android.fluxc.store.AccountStore.AccountErrorType.GENERIC_ERROR
import org.wordpress.android.fluxc.store.AccountStore.OnAccountChanged
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.AccountClosureUiState
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.AccountSettingsUiState
import org.wordpress.android.ui.prefs.accountsettings.AccountSettingsViewModel.SiteUiModel
import org.wordpress.android.ui.prefs.accountsettings.usecase.AccountClosureUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.FetchAccountSettingsUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.GetAccountUseCase
import org.wordpress.android.ui.prefs.accountsettings.usecase.GetSitesUseCase
Expand Down Expand Up @@ -54,6 +59,9 @@ class AccountSettingsViewModelTest : BaseUnitTest() {
@Mock
private lateinit var account: AccountModel

@Mock
lateinit var accountClosureUseCase: AccountClosureUseCase

private val siteViewModels = mutableListOf<SiteUiModel>().apply {
add(SiteUiModel("HappyDay", 1L, "http://happyday.wordpress.com"))
add(SiteUiModel("WonderLand", 2L, "http://wonderland.wordpress.com"))
Expand All @@ -80,7 +88,7 @@ class AccountSettingsViewModelTest : BaseUnitTest() {
}

@Test
fun `The initial primarysite is shown from cached account settings`() = test {
fun `The initial primary site is shown from cached account settings`() = test {
uiState.primarySiteSettingsUiState.primarySite?.siteId?.let {
assertThat(it).isEqualTo(getAccountUseCase.account.primarySiteId)
}
Expand Down Expand Up @@ -407,6 +415,31 @@ class AccountSettingsViewModelTest : BaseUnitTest() {
.isEqualTo(false)
}

@Test
fun `When account closure succeeds, then the closure dialog should be in the success state`() = test {
mockAccountClosureWithResult(CloseAccountResult.Success)
viewModel.closeAccount()
assertTrue(viewModel.accountClosureUiState.value is AccountClosureUiState.Opened.Success)
}

@Test
fun `When account closure fails, then the closure dialog should be in the error state`() = test {
mockAccountClosureWithResult(CloseAccountResult.Failure(CloseAccountResult.Error(
CloseAccountResult.ErrorType.UNKNOWN,
"unknown",
)))
viewModel.closeAccount()
assertTrue(viewModel.accountClosureUiState.value is AccountClosureUiState.Opened.Error)
}

@Test
fun `When there is an Atomic site, then the closure dialog should open in the error state`() = test {
val mockAtomicSite: SiteModel = mock()
whenever(getSitesUseCase.getAtomic()).thenReturn(listOf(mockAtomicSite))
viewModel.openAccountClosureDialog()
assertTrue(viewModel.accountClosureUiState.value is AccountClosureUiState.Opened.Error)
}

// Helper Methods
private fun <T> testUiStateChanges(
block: suspend CoroutineScope.() -> T
Expand Down Expand Up @@ -443,10 +476,19 @@ class AccountSettingsViewModelTest : BaseUnitTest() {
getAccountUseCase,
getSitesUseCase,
optimisticUpdateHandler,
mock(),
accountClosureUseCase,
)
}

private suspend fun mockAccountClosureWithResult(result: CloseAccountResult) {
whenever(getSitesUseCase.getAtomic()).thenReturn(emptyList())
whenever(accountClosureUseCase.closeAccount(any())).thenAnswer {
val completion = it.getArgument<((CloseAccountResult) -> Unit)>(0)
completion.invoke(result)
}
viewModel.openAccountClosureDialog()
}

private suspend fun mockSites(siteViewModels: List<SiteUiModel>) {
val sites = siteViewModels.map {
SiteModel().apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.wordpress.android.ui.prefs.accountsettings

import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.wordpress.android.BaseUnitTest
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.ui.prefs.accountsettings.usecase.GetSitesUseCase

@ExperimentalCoroutinesApi
class GetSitesUseCaseTest: BaseUnitTest() {
private lateinit var useCase: GetSitesUseCase

@Mock
private lateinit var siteStore: SiteStore

val mockAtomicSite: SiteModel = mock()
val mockNonAtomicSite: SiteModel = mock()

@Before
fun setUp() = test {
useCase = GetSitesUseCase(
testDispatcher(),
siteStore,
)
whenever(mockAtomicSite.isWPComAtomic).thenReturn(true)
whenever(mockNonAtomicSite.isWPComAtomic).thenReturn(false)
whenever(siteStore.sitesAccessedViaWPComRest).thenReturn(listOf(
mockAtomicSite,
mockNonAtomicSite,
))
}

@Test
fun `getAtomic filters for Atomic sites`() {
test {
val atomicSites = useCase.getAtomic()
assertThat(atomicSites.size).isEqualTo(1)
assertThat(atomicSites.first()).isEqualTo(mockAtomicSite)
}
}
}

0 comments on commit 229c44c

Please sign in to comment.