Merge pull request #40 from fknives/issue#16-login-setup-removal

Issue#16 Swap white box logout and login state into ui interaction based
This commit is contained in:
Gergely Hegedis 2022-01-24 16:05:47 +02:00 committed by GitHub
commit e3bf7fd3e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 99 additions and 128 deletions

View file

@ -0,0 +1,52 @@
package org.fnives.test.showcase.testutils.statesetup
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
import org.fnives.test.showcase.ui.ActivityClassHolder
import org.fnives.test.showcase.ui.home.HomeRobot
import org.fnives.test.showcase.ui.login.LoginRobot
import org.koin.test.KoinTest
object SetupAuthenticationState : KoinTest {
fun setupLogin(
mainDispatcherTestRule: MainDispatcherTestRule,
mockServerScenarioSetup: MockServerScenarioSetup
) {
mockServerScenarioSetup.setScenario(
AuthScenario.Success(
username = "a",
password = "b"
)
)
val activityScenario = ActivityScenario.launch(ActivityClassHolder.authActivity().java)
activityScenario.moveToState(Lifecycle.State.RESUMED)
val loginRobot = LoginRobot()
loginRobot.setupIntentResults()
loginRobot
.setPassword("b")
.setUsername("a")
.clickOnLogin()
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
activityScenario.moveToState(Lifecycle.State.DESTROYED)
}
fun setupLogout(
mainDispatcherTestRule: MainDispatcherTestRule
) {
val activityScenario = ActivityScenario.launch(ActivityClassHolder.mainActivity().java)
activityScenario.moveToState(Lifecycle.State.RESUMED)
val homeRobot = HomeRobot()
homeRobot
.clickSignOut()
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
activityScenario.moveToState(Lifecycle.State.DESTROYED)
}
}

View file

@ -1,31 +0,0 @@
// package org.fnives.test.showcase.testutils.statesetup
//
// import kotlinx.coroutines.runBlocking
// import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
// import org.fnives.test.showcase.core.login.LoginUseCase
// import org.fnives.test.showcase.core.login.LogoutUseCase
// import org.fnives.test.showcase.model.auth.LoginCredentials
// import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
// import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
// import org.koin.test.KoinTest
// import org.koin.test.get
//
// object SetupLoggedInState : KoinTest {
//
// private val logoutUseCase get() = get<LogoutUseCase>()
// private val loginUseCase get() = get<LoginUseCase>()
// private val isUserLoggedInUseCase get() = get<IsUserLoggedInUseCase>()
//
// fun setupLogin(mockServerScenarioSetup: MockServerScenarioSetup) {
// mockServerScenarioSetup.setScenario(AuthScenario.Success("a", "b"))
// runBlocking {
// loginUseCase.invoke(LoginCredentials("a", "b"))
// }
// }
//
// fun isLoggedIn() = isUserLoggedInUseCase.invoke()
//
// fun setupLogout() {
// runBlocking { logoutUseCase.invoke() }
// }
// }

View file

@ -19,7 +19,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import org.fnives.test.showcase.R import org.fnives.test.showcase.R
import org.fnives.test.showcase.model.content.Content import org.fnives.test.showcase.model.content.Content
import org.fnives.test.showcase.model.content.FavouriteContent import org.fnives.test.showcase.model.content.FavouriteContent
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
import org.fnives.test.showcase.testutils.robot.Robot import org.fnives.test.showcase.testutils.robot.Robot
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState
import org.fnives.test.showcase.testutils.viewactions.PullToRefresh import org.fnives.test.showcase.testutils.viewactions.PullToRefresh
import org.fnives.test.showcase.testutils.viewactions.WithDrawable import org.fnives.test.showcase.testutils.viewactions.WithDrawable
import org.fnives.test.showcase.testutils.viewactions.notIntended import org.fnives.test.showcase.testutils.viewactions.notIntended
@ -100,4 +103,11 @@ class HomeRobot : Robot {
Espresso.onView(withId(R.id.error_message)) Espresso.onView(withId(R.id.error_message))
.check(matches(allOf(isDisplayed(), withText(R.string.something_went_wrong)))) .check(matches(allOf(isDisplayed(), withText(R.string.something_went_wrong))))
} }
fun setupLogin(
mainDispatcherTestRule: MainDispatcherTestRule,
mockServerScenarioSetup: MockServerScenarioSetup
) {
SetupAuthenticationState.setupLogin(mainDispatcherTestRule, mockServerScenarioSetup)
}
} }

View file

@ -37,6 +37,10 @@ class LoginRobot(
override fun init() { override fun init() {
Intents.init() Intents.init()
setupIntentResults()
}
fun setupIntentResults() {
intending(hasComponent(ActivityClassHolder.mainActivity().java.canonicalName)) intending(hasComponent(ActivityClassHolder.mainActivity().java.canonicalName))
.respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, Intent())) .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, Intent()))
} }

View file

@ -3,7 +3,10 @@ package org.fnives.test.showcase.ui.splash
import android.app.Instrumentation import android.app.Instrumentation
import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.intent.matcher.IntentMatchers
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
import org.fnives.test.showcase.testutils.robot.Robot import org.fnives.test.showcase.testutils.robot.Robot
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState
import org.fnives.test.showcase.testutils.viewactions.notIntended import org.fnives.test.showcase.testutils.viewactions.notIntended
import org.fnives.test.showcase.ui.ActivityClassHolder import org.fnives.test.showcase.ui.ActivityClassHolder
@ -21,6 +24,23 @@ class SplashRobot : Robot {
Intents.release() Intents.release()
} }
fun setupLoggedInState(
mainDispatcherTestRule: MainDispatcherTestRule,
mockServerScenarioSetup: MockServerScenarioSetup
) {
SetupAuthenticationState.setupLogin(mainDispatcherTestRule, mockServerScenarioSetup)
release()
init()
}
fun setupLoggedOutState(
mainDispatcherTestRule: MainDispatcherTestRule
) {
SetupAuthenticationState.setupLogout(mainDispatcherTestRule)
release()
init()
}
fun assertHomeIsStarted() = apply { fun assertHomeIsStarted() = apply {
Intents.intended(IntentMatchers.hasComponent(ActivityClassHolder.mainActivity().java.canonicalName)) Intents.intended(IntentMatchers.hasComponent(ActivityClassHolder.mainActivity().java.canonicalName))
} }

View file

@ -1,30 +0,0 @@
package org.fnives.test.showcase.testutils.statesetup
import kotlinx.coroutines.runBlocking
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
import org.fnives.test.showcase.core.login.LoginUseCase
import org.fnives.test.showcase.core.login.LogoutUseCase
import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import javax.inject.Inject
class SetupLoggedInState @Inject constructor(
private val logoutUseCase: LogoutUseCase,
private val loginUseCase: LoginUseCase,
private val isUserLoggedInUseCase: IsUserLoggedInUseCase
) {
fun setupLogin(mockServerScenarioSetup: MockServerScenarioSetup) {
mockServerScenarioSetup.setScenario(AuthScenario.Success("a", "b"))
runBlocking {
loginUseCase.invoke(LoginCredentials("a", "b"))
}
}
fun isLoggedIn() = isUserLoggedInUseCase.invoke()
fun setupLogout() {
runBlocking { logoutUseCase.invoke() }
}
}

View file

@ -17,9 +17,7 @@ import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
import org.fnives.test.showcase.testutils.idling.loopMainThreadFor import org.fnives.test.showcase.testutils.idling.loopMainThreadFor
import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources
import org.fnives.test.showcase.testutils.robot.RobotTestRule import org.fnives.test.showcase.testutils.robot.RobotTestRule
import org.fnives.test.showcase.testutils.statesetup.SetupLoggedInState
import org.junit.After import org.junit.After
import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -58,9 +56,6 @@ class MainActivityTest {
@JvmField @JvmField
val hiltRule = HiltAndroidRule(this) val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var setupLoggedInState: SetupLoggedInState
@Inject @Inject
lateinit var networkSynchronization: NetworkSynchronization lateinit var networkSynchronization: NetworkSynchronization
@ -72,8 +67,8 @@ class MainActivityTest {
.invoke(mockServerScenarioSetupTestRule.mockServerScenarioSetup) .invoke(mockServerScenarioSetupTestRule.mockServerScenarioSetup)
hiltRule.inject() hiltRule.inject()
setupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup)
disposable = networkSynchronization.registerNetworkingSynchronization() disposable = networkSynchronization.registerNetworkingSynchronization()
homeRobot.setupLogin(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
} }
@After @After
@ -94,7 +89,6 @@ class MainActivityTest {
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed() mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
homeRobot.assertNavigatedToAuth() homeRobot.assertNavigatedToAuth()
Assert.assertEquals(false, setupLoggedInState.isLoggedIn())
} }
/** GIVEN success response WHEN data is returned THEN it is shown on the ui */ /** GIVEN success response WHEN data is returned THEN it is shown on the ui */
@ -253,6 +247,5 @@ class MainActivityTest {
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources() mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
homeRobot.assertNavigatedToAuth() homeRobot.assertNavigatedToAuth()
Assert.assertEquals(false, setupLoggedInState.isLoggedIn())
} }
} }

View file

@ -11,7 +11,6 @@ import org.fnives.test.showcase.testutils.configuration.SpecificTestConfiguratio
import org.fnives.test.showcase.testutils.idling.Disposable import org.fnives.test.showcase.testutils.idling.Disposable
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
import org.fnives.test.showcase.testutils.robot.RobotTestRule import org.fnives.test.showcase.testutils.robot.RobotTestRule
import org.fnives.test.showcase.testutils.statesetup.SetupLoggedInState
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
@ -49,9 +48,6 @@ class SplashActivityTest : KoinTest {
@JvmField @JvmField
val hiltRule = HiltAndroidRule(this) val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var setupLoggedInState: SetupLoggedInState
@Inject @Inject
lateinit var networkSynchronization: NetworkSynchronization lateinit var networkSynchronization: NetworkSynchronization
@ -74,7 +70,7 @@ class SplashActivityTest : KoinTest {
/** GIVEN loggedInState WHEN opened THEN MainActivity is started */ /** GIVEN loggedInState WHEN opened THEN MainActivity is started */
@Test @Test
fun loggedInStateNavigatesToHome() { fun loggedInStateNavigatesToHome() {
setupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup) splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java) activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java)
@ -82,14 +78,12 @@ class SplashActivityTest : KoinTest {
splashRobot.assertHomeIsStarted() splashRobot.assertHomeIsStarted()
.assertAuthIsNotStarted() .assertAuthIsNotStarted()
setupLoggedInState.setupLogout()
} }
/** GIVEN loggedOffState WHEN opened THEN AuthActivity is started */ /** GIVEN loggedOffState WHEN opened THEN AuthActivity is started */
@Test @Test
fun loggedOutStatesNavigatesToAuthentication() { fun loggedOutStatesNavigatesToAuthentication() {
setupLoggedInState.setupLogout() splashRobot.setupLoggedOutState(mainDispatcherTestRule)
activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java) activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java)
@ -101,7 +95,7 @@ class SplashActivityTest : KoinTest {
@Test @Test
fun loggedOutStatesNotEnoughTime() { fun loggedOutStatesNotEnoughTime() {
setupLoggedInState.setupLogout() splashRobot.setupLoggedOutState(mainDispatcherTestRule)
activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java) activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java)
@ -114,7 +108,7 @@ class SplashActivityTest : KoinTest {
/** GIVEN loggedInState and not enough time WHEN opened THEN no activity is started */ /** GIVEN loggedInState and not enough time WHEN opened THEN no activity is started */
@Test @Test
fun loggedInStatesNotEnoughTime() { fun loggedInStatesNotEnoughTime() {
setupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup) splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java) activityScenario = ActivityScenario.launch(HiltSplashActivity::class.java)
@ -122,7 +116,5 @@ class SplashActivityTest : KoinTest {
splashRobot.assertHomeIsNotStarted() splashRobot.assertHomeIsNotStarted()
.assertAuthIsNotStarted() .assertAuthIsNotStarted()
setupLoggedInState.setupLogout()
} }
} }

View file

@ -1,31 +0,0 @@
package org.fnives.test.showcase.testutils.statesetup
import kotlinx.coroutines.runBlocking
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
import org.fnives.test.showcase.core.login.LoginUseCase
import org.fnives.test.showcase.core.login.LogoutUseCase
import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.koin.test.KoinTest
import org.koin.test.get
object SetupLoggedInState : KoinTest {
private val logoutUseCase get() = get<LogoutUseCase>()
private val loginUseCase get() = get<LoginUseCase>()
private val isUserLoggedInUseCase get() = get<IsUserLoggedInUseCase>()
fun setupLogin(mockServerScenarioSetup: MockServerScenarioSetup) {
mockServerScenarioSetup.setScenario(AuthScenario.Success("a", "b"))
runBlocking {
loginUseCase.invoke(LoginCredentials("a", "b"))
}
}
fun isLoggedIn() = isUserLoggedInUseCase.invoke()
fun setupLogout() {
runBlocking { logoutUseCase.invoke() }
}
}

View file

@ -16,9 +16,7 @@ import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
import org.fnives.test.showcase.testutils.idling.loopMainThreadFor import org.fnives.test.showcase.testutils.idling.loopMainThreadFor
import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources
import org.fnives.test.showcase.testutils.robot.RobotTestRule import org.fnives.test.showcase.testutils.robot.RobotTestRule
import org.fnives.test.showcase.testutils.statesetup.SetupLoggedInState
import org.junit.After import org.junit.After
import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -64,8 +62,11 @@ class MainActivityTest : KoinTest {
SpecificTestConfigurationsFactory.createServerTypeConfiguration() SpecificTestConfigurationsFactory.createServerTypeConfiguration()
.invoke(mockServerScenarioSetupTestRule.mockServerScenarioSetup) .invoke(mockServerScenarioSetupTestRule.mockServerScenarioSetup)
SetupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup)
disposable = NetworkSynchronization.registerNetworkingSynchronization() disposable = NetworkSynchronization.registerNetworkingSynchronization()
homeRobot.setupLogin(
mainDispatcherTestRule,
mockServerScenarioSetupTestRule.mockServerScenarioSetup
)
} }
@After @After
@ -86,7 +87,6 @@ class MainActivityTest : KoinTest {
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed() mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
homeRobot.assertNavigatedToAuth() homeRobot.assertNavigatedToAuth()
Assert.assertEquals(false, SetupLoggedInState.isLoggedIn())
} }
/** GIVEN success response WHEN data is returned THEN it is shown on the ui */ /** GIVEN success response WHEN data is returned THEN it is shown on the ui */
@ -245,6 +245,5 @@ class MainActivityTest : KoinTest {
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources() mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
homeRobot.assertNavigatedToAuth() homeRobot.assertNavigatedToAuth()
Assert.assertEquals(false, SetupLoggedInState.isLoggedIn())
} }
} }

View file

@ -9,7 +9,6 @@ import org.fnives.test.showcase.testutils.configuration.SpecificTestConfiguratio
import org.fnives.test.showcase.testutils.idling.Disposable import org.fnives.test.showcase.testutils.idling.Disposable
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
import org.fnives.test.showcase.testutils.robot.RobotTestRule import org.fnives.test.showcase.testutils.robot.RobotTestRule
import org.fnives.test.showcase.testutils.statesetup.SetupLoggedInState
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
@ -59,7 +58,7 @@ class SplashActivityTest : KoinTest {
/** GIVEN loggedInState WHEN opened after some time THEN MainActivity is started */ /** GIVEN loggedInState WHEN opened after some time THEN MainActivity is started */
@Test @Test
fun loggedInStateNavigatesToHome() { fun loggedInStateNavigatesToHome() {
SetupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup) splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
activityScenario = ActivityScenario.launch(SplashActivity::class.java) activityScenario = ActivityScenario.launch(SplashActivity::class.java)
activityScenario.moveToState(Lifecycle.State.RESUMED) activityScenario.moveToState(Lifecycle.State.RESUMED)
@ -68,15 +67,12 @@ class SplashActivityTest : KoinTest {
splashRobot.assertHomeIsStarted() splashRobot.assertHomeIsStarted()
.assertAuthIsNotStarted() .assertAuthIsNotStarted()
SetupLoggedInState.setupLogout()
} }
/** GIVEN loggedOffState WHEN opened after some time THEN AuthActivity is started */ /** GIVEN loggedOffState WHEN opened after some time THEN AuthActivity is started */
@Test @Test
fun loggedOutStatesNavigatesToAuthentication() { fun loggedOutStatesNavigatesToAuthentication() {
SetupLoggedInState.setupLogout() splashRobot.setupLoggedOutState(mainDispatcherTestRule)
activityScenario = ActivityScenario.launch(SplashActivity::class.java) activityScenario = ActivityScenario.launch(SplashActivity::class.java)
activityScenario.moveToState(Lifecycle.State.RESUMED) activityScenario.moveToState(Lifecycle.State.RESUMED)
@ -89,8 +85,7 @@ class SplashActivityTest : KoinTest {
/** GIVEN loggedOffState and not enough time WHEN opened THEN no activity is started */ /** GIVEN loggedOffState and not enough time WHEN opened THEN no activity is started */
@Test @Test
fun loggedOutStatesNotEnoughTime() { fun loggedOutStatesNotEnoughTime() {
SetupLoggedInState.setupLogout() splashRobot.setupLoggedOutState(mainDispatcherTestRule)
activityScenario = ActivityScenario.launch(SplashActivity::class.java) activityScenario = ActivityScenario.launch(SplashActivity::class.java)
activityScenario.moveToState(Lifecycle.State.RESUMED) activityScenario.moveToState(Lifecycle.State.RESUMED)
@ -103,7 +98,7 @@ class SplashActivityTest : KoinTest {
/** GIVEN loggedInState and not enough time WHEN opened THEN no activity is started */ /** GIVEN loggedInState and not enough time WHEN opened THEN no activity is started */
@Test @Test
fun loggedInStatesNotEnoughTime() { fun loggedInStatesNotEnoughTime() {
SetupLoggedInState.setupLogin(mockServerScenarioSetupTestRule.mockServerScenarioSetup) splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
activityScenario = ActivityScenario.launch(SplashActivity::class.java) activityScenario = ActivityScenario.launch(SplashActivity::class.java)
activityScenario.moveToState(Lifecycle.State.RESUMED) activityScenario.moveToState(Lifecycle.State.RESUMED)
@ -112,7 +107,5 @@ class SplashActivityTest : KoinTest {
splashRobot.assertHomeIsNotStarted() splashRobot.assertHomeIsNotStarted()
.assertAuthIsNotStarted() .assertAuthIsNotStarted()
SetupLoggedInState.setupLogout()
} }
} }