Skip to content

Commit c555af3

Browse files
committed
test: move TFA config UI test to integration tests
Signed-off-by: Manu Muñoz <manu.munoz@dhis2.org>
1 parent e11d770 commit c555af3

2 files changed

Lines changed: 180 additions & 23 deletions

File tree

app/src/androidTest/java/org/dhis2/usescases/settings/SettingsTest.kt

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
11
package org.dhis2.usescases.settings
22

3+
import androidx.compose.runtime.mutableStateSetOf
34
import androidx.compose.ui.test.junit4.createComposeRule
5+
import androidx.lifecycle.MutableLiveData
46
import androidx.test.core.app.ApplicationProvider
57
import androidx.test.ext.junit.runners.AndroidJUnit4
8+
import kotlinx.coroutines.flow.MutableStateFlow
9+
import kotlinx.coroutines.flow.StateFlow
10+
import kotlinx.coroutines.flow.flow
11+
import kotlinx.coroutines.flow.flowOf
612
import org.dhis2.mobile.commons.featureconfig.model.Feature
713
import org.dhis2.lazyActivityScenarioRule
814
import org.dhis2.usescases.BaseTest
915
import org.dhis2.usescases.main.MainActivity
1016
import org.dhis2.usescases.main.MainScreenType
17+
import org.dhis2.usescases.settings.models.DataSettingsViewModel
18+
import org.dhis2.usescases.settings.models.MetadataSettingsViewModel
19+
import org.dhis2.usescases.settings.models.ReservedValueSettingsViewModel
20+
import org.dhis2.usescases.settings.models.SMSSettingsViewModel
21+
import org.dhis2.usescases.settings.models.SettingsState
22+
import org.dhis2.usescases.settings.models.SyncParametersViewModel
23+
import org.dhis2.usescases.settings.ui.SettingsScreen
1124
import org.junit.Before
1225
import org.junit.Rule
1326
import org.junit.Test
1427
import org.junit.runner.RunWith
28+
import org.mockito.kotlin.doReturn
29+
import org.mockito.kotlin.mock
30+
import org.mockito.kotlin.whenever
31+
import java.io.File
1532

1633
@RunWith(AndroidJUnit4::class)
1734
class SettingsTest : BaseTest() {
@@ -73,29 +90,6 @@ class SettingsTest : BaseTest() {
7390
}
7491
}
7592

76-
//This test covers test case ANDROAPP-7139
77-
@Test
78-
fun shouldNotShowTwoFAOption() {
79-
disableFeatureConfigValue(Feature.TWO_FACTOR_AUTHENTICATION)
80-
startActivity()
81-
settingsRobot(composeTestRule) {
82-
checkTwoFAOptionIsNotDisplayed()
83-
}
84-
}
85-
86-
//This test covers test case ANDROAPP-7139 and ANDROAPP-7140
87-
@Test
88-
fun shouldShowTwoFAOption() {
89-
enableFeatureConfigValue(Feature.TWO_FACTOR_AUTHENTICATION)
90-
91-
startActivity()
92-
settingsRobot(composeTestRule) {
93-
checkTwoFAOptionIsDisplayed()
94-
clickOnTwoFASettings()
95-
checkTwoFAScreenIsDisplayed()
96-
}
97-
}
98-
9993
private fun startActivity() {
10094
val intent = MainActivity.intent(
10195
ApplicationProvider.getApplicationContext(),
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package org.dhis2.usescases.settings
2+
3+
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
4+
import app.cash.turbine.test
5+
import io.reactivex.Single
6+
import kotlinx.coroutines.CoroutineDispatcher
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.ExperimentalCoroutinesApi
9+
import kotlinx.coroutines.flow.flowOf
10+
import kotlinx.coroutines.test.StandardTestDispatcher
11+
import kotlinx.coroutines.test.runTest
12+
import kotlinx.coroutines.test.setMain
13+
import org.dhis2.commons.network.NetworkUtils
14+
import org.dhis2.commons.viewmodel.DispatcherProvider
15+
import org.dhis2.usescases.settings.GatewayValidator.GatewayValidationResult
16+
import org.dhis2.usescases.settings.domain.CheckVersionUpdate
17+
import org.dhis2.usescases.settings.domain.DeleteLocalData
18+
import org.dhis2.usescases.settings.domain.ExportDatabase
19+
import org.dhis2.usescases.settings.domain.GetSettingsState
20+
import org.dhis2.usescases.settings.domain.GetSyncErrors
21+
import org.dhis2.usescases.settings.domain.LaunchSync
22+
import org.dhis2.usescases.settings.domain.SettingsMessages
23+
import org.dhis2.usescases.settings.domain.UpdateSmsModule
24+
import org.dhis2.usescases.settings.domain.UpdateSmsResponse
25+
import org.dhis2.usescases.settings.domain.UpdateSyncSettings
26+
import org.dhis2.usescases.settings.models.DataSettingsViewModel
27+
import org.dhis2.usescases.settings.models.MetadataSettingsViewModel
28+
import org.dhis2.usescases.settings.models.ReservedValueSettingsViewModel
29+
import org.dhis2.usescases.settings.models.SMSSettingsViewModel
30+
import org.dhis2.usescases.settings.models.SyncParametersViewModel
31+
import org.dhis2.utils.MainCoroutineScopeRule
32+
import org.junit.Before
33+
import org.junit.Rule
34+
import org.junit.Test
35+
import org.mockito.kotlin.doReturn
36+
import org.mockito.kotlin.mock
37+
import org.mockito.kotlin.whenever
38+
39+
class SettingsIntegrationTest {
40+
private val settingsMessages: SettingsMessages = mock()
41+
private val networkUtils: NetworkUtils = mock()
42+
private val launchSync: LaunchSync = mock()
43+
private val checkVersionUpdate: CheckVersionUpdate = mock()
44+
private val exportDatabase: ExportDatabase = mock()
45+
private val deleteLocalData: DeleteLocalData = mock()
46+
private val updateSmsModule: UpdateSmsModule = mock()
47+
private val getSyncErrors: GetSyncErrors = mock()
48+
private val updateSmsResponse: UpdateSmsResponse = mock()
49+
private val updateSyncSettings: UpdateSyncSettings = mock()
50+
private val metadataSettingsViewModel: MetadataSettingsViewModel = mock()
51+
private val dataSettingsViewModel: DataSettingsViewModel = mock()
52+
private val syncParametersViewModel: SyncParametersViewModel = mock()
53+
private val reservedValueSettingsViewModel: ReservedValueSettingsViewModel = mock()
54+
private val smsSettingsViewModel: SMSSettingsViewModel =
55+
mock {
56+
on { gatewayNumber } doReturn ""
57+
}
58+
private val settingsRepository: SettingsRepository =
59+
mock {
60+
on { metaSync() } doReturn Single.just(metadataSettingsViewModel)
61+
on { dataSync() } doReturn Single.just(dataSettingsViewModel)
62+
on { syncParameters() } doReturn Single.just(syncParametersViewModel)
63+
on { reservedValues() } doReturn Single.just(reservedValueSettingsViewModel)
64+
on { sms() } doReturn Single.just(smsSettingsViewModel)
65+
on { getVersionName() } doReturn "1.0"
66+
}
67+
private val gatewayValidator: GatewayValidator =
68+
mock {
69+
on { invoke("") } doReturn GatewayValidationResult.Empty
70+
}
71+
private val getSettingsState: GetSettingsState =
72+
GetSettingsState(settingsRepository, gatewayValidator)
73+
74+
@OptIn(ExperimentalCoroutinesApi::class)
75+
@get:Rule
76+
val coroutineScope = MainCoroutineScopeRule()
77+
78+
@get:Rule
79+
val instantExecutorRule = InstantTaskExecutorRule()
80+
81+
private val testingDispatcher = StandardTestDispatcher()
82+
83+
private lateinit var syncManagerPresenter: SyncManagerPresenter
84+
85+
@OptIn(ExperimentalCoroutinesApi::class)
86+
@Before
87+
fun setUp() {
88+
Dispatchers.setMain(testingDispatcher)
89+
90+
whenever(
91+
settingsRepository.metaSync().blockingGet().copy(syncInProgress = false),
92+
) doReturn metadataSettingsViewModel
93+
whenever(
94+
settingsRepository.dataSync().blockingGet().copy(syncInProgress = false),
95+
) doReturn dataSettingsViewModel
96+
whenever(
97+
with(settingsRepository.sms().blockingGet()) {
98+
copy(
99+
gatewayValidationResult = gatewayValidator(this.gatewayNumber),
100+
)
101+
},
102+
) doReturn smsSettingsViewModel
103+
whenever(networkUtils.connectionStatus) doReturn flowOf(false)
104+
whenever(launchSync.syncWorkInfo) doReturn mock()
105+
}
106+
107+
private fun buildPresenter() {
108+
syncManagerPresenter =
109+
SyncManagerPresenter(
110+
getSettingsState = getSettingsState,
111+
updateSyncSettings = updateSyncSettings,
112+
updateSmsResponse = updateSmsResponse,
113+
getSyncErrors = getSyncErrors,
114+
updateSmsModule = updateSmsModule,
115+
deleteLocalData = deleteLocalData,
116+
exportDatabase = exportDatabase,
117+
checkVersionUpdate = checkVersionUpdate,
118+
launchSync = launchSync,
119+
dispatcherProvider =
120+
object : DispatcherProvider {
121+
override fun io(): CoroutineDispatcher = testingDispatcher
122+
123+
override fun computation(): CoroutineDispatcher = testingDispatcher
124+
125+
override fun ui(): CoroutineDispatcher = testingDispatcher
126+
},
127+
networkUtils = networkUtils,
128+
settingsMessages = settingsMessages,
129+
)
130+
}
131+
132+
@Test
133+
fun `should display TFA when it is configured`() =
134+
runTest {
135+
// Given TFA configured
136+
whenever(settingsRepository.isTwoFAConfigured()) doReturn true
137+
138+
// When set settings config
139+
buildPresenter()
140+
141+
// Then TFA should be displayed
142+
syncManagerPresenter.settingsState.test {
143+
assert(awaitItem() == null)
144+
assert(awaitItem()?.isTwoFAConfigured == true)
145+
}
146+
}
147+
148+
@Test
149+
fun `should not display TFA when it is not configured`() =
150+
runTest {
151+
// Given TFA not configured
152+
whenever(settingsRepository.isTwoFAConfigured()) doReturn false
153+
154+
// When set settings config
155+
buildPresenter()
156+
157+
// Then TFA should not be displayed
158+
syncManagerPresenter.settingsState.test {
159+
assert(awaitItem() == null)
160+
assert(awaitItem()?.isTwoFAConfigured == false)
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)