Issue#13 Simplify rule sets to minimal and appy them in order
This commit is contained in:
parent
d8b9fadcbc
commit
5a08525e42
10 changed files with 140 additions and 157 deletions
|
|
@ -4,7 +4,9 @@ import okhttp3.OkHttpClient
|
|||
import okhttp3.tls.HandshakeCertificates
|
||||
import org.fnives.test.showcase.model.network.BaseUrl
|
||||
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization.OkHttpClientTypes
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronizationTestRule
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronizationTestRule.OkHttpClientTypes
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import org.koin.core.context.loadKoinModules
|
||||
|
|
@ -12,14 +14,26 @@ import org.koin.dsl.module
|
|||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
|
||||
class MockServerScenarioSetupTestRule : ReloadKoinModulesIfNecessaryTestRule(), KoinTest {
|
||||
/**
|
||||
* TestRule which ensures Koin is reseted between each tests and setups Network mocking.
|
||||
*
|
||||
* It First resets koin if needed.
|
||||
* Then creates and starts the mockwebserver, it also injects the correct baseUrl into the OkHttp Client.
|
||||
* Then synchronizes Espresso with the OkHttp Client
|
||||
*/
|
||||
class MockServerScenarioSetupResetingTestRule(
|
||||
private val reloadKoinModulesIfNecessaryTestRule: ReloadKoinModulesIfNecessaryTestRule = ReloadKoinModulesIfNecessaryTestRule(),
|
||||
private val networkSynchronizationTestRule: NetworkSynchronizationTestRule = NetworkSynchronizationTestRule()
|
||||
) : TestRule, KoinTest {
|
||||
|
||||
lateinit var mockServerScenarioSetup: MockServerScenarioSetup
|
||||
|
||||
private val sessionlessQualifier get() = OkHttpClientTypes.SESSIONLESS.asQualifier()
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement =
|
||||
super.apply(createStatement(base), description)
|
||||
networkSynchronizationTestRule.apply(base, description)
|
||||
.let(::createStatement)
|
||||
.let { reloadKoinModulesIfNecessaryTestRule.apply(it, description) }
|
||||
|
||||
private fun createStatement(base: Statement) = object : Statement() {
|
||||
@Throws(Throwable::class)
|
||||
|
|
@ -9,6 +9,7 @@ import org.junit.rules.TestRule
|
|||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.context.GlobalContext
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.stopKoin
|
||||
import org.koin.mp.KoinPlatformTools
|
||||
|
|
@ -22,7 +23,7 @@ import org.koin.test.KoinTest
|
|||
*
|
||||
* Note: Do not use if you want your test's to share Koin, and in such case do not stop your Koin.
|
||||
*/
|
||||
open class ReloadKoinModulesIfNecessaryTestRule : TestRule, KoinTest {
|
||||
class ReloadKoinModulesIfNecessaryTestRule : TestRule, KoinTest {
|
||||
override fun apply(base: Statement, description: Description): Statement =
|
||||
ReinitKoinStatement(base)
|
||||
|
||||
|
|
@ -38,6 +39,7 @@ open class ReloadKoinModulesIfNecessaryTestRule : TestRule, KoinTest {
|
|||
|
||||
private fun reinitKoinIfNeeded() {
|
||||
if (KoinPlatformTools.defaultContext().getOrNull() != null) return
|
||||
if (GlobalContext.getOrNull() != null) return
|
||||
|
||||
val application = ApplicationProvider.getApplicationContext<TestShowcaseApplication>()
|
||||
val baseUrl = BaseUrl(BuildConfig.BASE_URL)
|
||||
|
|
|
|||
|
|
@ -12,3 +12,7 @@ interface MainDispatcherTestRule : TestRule {
|
|||
|
||||
fun advanceTimeBy(delayInMillis: Long)
|
||||
}
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
fun MainDispatcherTestRule(): MainDispatcherTestRule =
|
||||
SpecificTestConfigurationsFactory.createMainDispatcherTestRule()
|
||||
|
|
|
|||
|
|
@ -3,14 +3,35 @@ package org.fnives.test.showcase.testutils.idling
|
|||
import androidx.annotation.CheckResult
|
||||
import androidx.test.espresso.IdlingResource
|
||||
import okhttp3.OkHttpClient
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
import org.koin.core.qualifier.StringQualifier
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
|
||||
object NetworkSynchronization : KoinTest {
|
||||
class NetworkSynchronizationTestRule : TestRule, KoinTest {
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
return object : Statement() {
|
||||
override fun evaluate() {
|
||||
disposable = registerNetworkingSynchronization()
|
||||
try {
|
||||
base.evaluate()
|
||||
} finally {
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun dispose() = disposable?.dispose()
|
||||
|
||||
@CheckResult
|
||||
fun registerNetworkingSynchronization(): Disposable {
|
||||
private fun registerNetworkingSynchronization(): Disposable {
|
||||
val idlingResources = OkHttpClientTypes.values()
|
||||
.map { it to getOkHttpClient(it) }
|
||||
.associateBy { it.second.dispatcher }
|
||||
|
|
@ -2,6 +2,8 @@ package org.fnives.test.showcase.testutils.statesetup
|
|||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.espresso.intent.Intents
|
||||
import androidx.test.runner.intent.IntentStubberRegistry
|
||||
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
|
||||
|
|
@ -15,7 +17,8 @@ object SetupAuthenticationState : KoinTest {
|
|||
|
||||
fun setupLogin(
|
||||
mainDispatcherTestRule: MainDispatcherTestRule,
|
||||
mockServerScenarioSetup: MockServerScenarioSetup
|
||||
mockServerScenarioSetup: MockServerScenarioSetup,
|
||||
resetIntents: Boolean = true
|
||||
) {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.Success(username = "a", password = "b"))
|
||||
val activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
|
|
@ -30,19 +33,27 @@ object SetupAuthenticationState : KoinTest {
|
|||
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
|
||||
|
||||
activityScenario.close()
|
||||
resetIntentsIfNeeded(resetIntents)
|
||||
}
|
||||
|
||||
fun setupLogout(
|
||||
mainDispatcherTestRule: MainDispatcherTestRule
|
||||
mainDispatcherTestRule: MainDispatcherTestRule,
|
||||
resetIntents: Boolean = true
|
||||
) {
|
||||
val activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
val homeRobot = HomeRobot()
|
||||
homeRobot
|
||||
.clickSignOut()
|
||||
HomeRobot().clickSignOut()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
|
||||
|
||||
activityScenario.close()
|
||||
resetIntentsIfNeeded(resetIntents)
|
||||
}
|
||||
|
||||
private fun resetIntentsIfNeeded(resetIntents: Boolean) {
|
||||
if (resetIntents && IntentStubberRegistry.isLoaded()) {
|
||||
Intents.release()
|
||||
Intents.init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
|
|||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.model.content.Content
|
||||
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.statesetup.SetupAuthenticationState
|
||||
import org.fnives.test.showcase.testutils.viewactions.PullToRefresh
|
||||
import org.fnives.test.showcase.testutils.viewactions.WithDrawable
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
|
|
@ -33,8 +30,6 @@ class HomeRobot : Robot {
|
|||
|
||||
override fun init() {
|
||||
Intents.init()
|
||||
Intents.intending(IntentMatchers.hasComponent(AuthActivity::class.java.canonicalName))
|
||||
.respondWith(Instrumentation.ActivityResult(0, null))
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
|
|
@ -50,6 +45,9 @@ class HomeRobot : Robot {
|
|||
}
|
||||
|
||||
fun clickSignOut() = apply {
|
||||
Intents.intending(IntentMatchers.hasComponent(AuthActivity::class.java.canonicalName))
|
||||
.respondWith(Instrumentation.ActivityResult(0, null))
|
||||
|
||||
Espresso.onView(withId(R.id.logout_cta)).perform(click())
|
||||
}
|
||||
|
||||
|
|
@ -103,11 +101,4 @@ class HomeRobot : Robot {
|
|||
Espresso.onView(withId(R.id.error_message))
|
||||
.check(matches(allOf(isDisplayed(), withText(R.string.something_went_wrong))))
|
||||
}
|
||||
|
||||
fun setupLogin(
|
||||
mainDispatcherTestRule: MainDispatcherTestRule,
|
||||
mockServerScenarioSetup: MockServerScenarioSetup
|
||||
) {
|
||||
SetupAuthenticationState.setupLogin(mainDispatcherTestRule, mockServerScenarioSetup)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ import org.fnives.test.showcase.model.content.FavouriteContent
|
|||
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.SpecificTestConfigurationsFactory
|
||||
import org.fnives.test.showcase.testutils.idling.Disposable
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
|
||||
import org.fnives.test.showcase.testutils.idling.loopMainThreadFor
|
||||
import org.fnives.test.showcase.testutils.idling.loopMainThreadUntilIdleWithIdlingResources
|
||||
import org.fnives.test.showcase.testutils.robot.RobotTestRule
|
||||
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState.setupLogin
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
|
||||
|
|
@ -26,37 +26,26 @@ class MainActivityTest : KoinTest {
|
|||
|
||||
private lateinit var activityScenario: ActivityScenario<MainActivity>
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val robotRule = RobotTestRule(HomeRobot())
|
||||
private val homeRobot get() = robotRule.robot
|
||||
private val mockServerScenarioSetupTestRule = MockServerScenarioSetupResetingTestRule()
|
||||
private val mockServerScenarioSetup
|
||||
get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||
private val mainDispatcherTestRule = MainDispatcherTestRule()
|
||||
private val robot = HomeRobot()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mockServerScenarioSetupTestRule = MockServerScenarioSetupTestRule()
|
||||
|
||||
val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mainDispatcherTestRule = SpecificTestConfigurationsFactory.createMainDispatcherTestRule()
|
||||
|
||||
private lateinit var disposable: Disposable
|
||||
val ruleOrder: RuleChain = RuleChain.outerRule(mockServerScenarioSetupTestRule)
|
||||
.around(mainDispatcherTestRule)
|
||||
.around(RobotTestRule(robot))
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
||||
disposable = NetworkSynchronization.registerNetworkingSynchronization()
|
||||
homeRobot.setupLogin(
|
||||
mainDispatcherTestRule,
|
||||
mockServerScenarioSetup
|
||||
)
|
||||
fun setup() {
|
||||
setupLogin(mainDispatcherTestRule, mockServerScenarioSetup)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
activityScenario.close()
|
||||
disposable.dispose()
|
||||
}
|
||||
|
||||
/** GIVEN initialized MainActivity WHEN signout is clicked THEN user is signed out */
|
||||
|
|
@ -66,10 +55,10 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.clickSignOut()
|
||||
robot.clickSignOut()
|
||||
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
|
||||
|
||||
homeRobot.assertNavigatedToAuth()
|
||||
robot.assertNavigatedToAuth()
|
||||
}
|
||||
|
||||
/** GIVEN success response WHEN data is returned THEN it is shown on the ui */
|
||||
|
|
@ -80,9 +69,9 @@ class MainActivityTest : KoinTest {
|
|||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
ContentData.contentSuccess.forEachIndexed { index, content ->
|
||||
homeRobot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
robot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
}
|
||||
homeRobot.assertDidNotNavigateToAuth()
|
||||
robot.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
/** GIVEN success response WHEN item is clicked THEN ui is updated */
|
||||
|
|
@ -92,11 +81,11 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
homeRobot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
robot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
val expectedItem = FavouriteContent(ContentData.contentSuccess.first(), true)
|
||||
homeRobot.assertContainsItem(0, expectedItem)
|
||||
robot.assertContainsItem(0, expectedItem)
|
||||
.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +96,7 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
homeRobot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
robot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
val expectedItem = FavouriteContent(ContentData.contentSuccess.first(), true)
|
||||
|
|
@ -116,7 +105,7 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.assertContainsItem(0, expectedItem)
|
||||
robot.assertContainsItem(0, expectedItem)
|
||||
.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
|
|
@ -127,13 +116,13 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
homeRobot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
robot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
homeRobot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
robot.clickOnContentItem(0, ContentData.contentSuccess.first())
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
val expectedItem = FavouriteContent(ContentData.contentSuccess.first(), false)
|
||||
homeRobot.assertContainsItem(0, expectedItem)
|
||||
robot.assertContainsItem(0, expectedItem)
|
||||
.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +133,7 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.assertContainsNoItems()
|
||||
robot.assertContainsNoItems()
|
||||
.assertContainsError()
|
||||
.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
|
@ -159,14 +148,14 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.swipeRefresh()
|
||||
robot.swipeRefresh()
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loopMainThreadFor(2000L)
|
||||
|
||||
ContentData.contentSuccess.forEachIndexed { index, content ->
|
||||
homeRobot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
robot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
}
|
||||
homeRobot.assertDidNotNavigateToAuth()
|
||||
robot.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
/** GIVEN success then error WHEN retried THEN error is shown */
|
||||
|
|
@ -179,13 +168,13 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.swipeRefresh()
|
||||
robot.swipeRefresh()
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loopMainThreadUntilIdleWithIdlingResources()
|
||||
mainDispatcherTestRule.advanceTimeBy(1000L)
|
||||
loopMainThreadFor(1000)
|
||||
|
||||
homeRobot
|
||||
robot
|
||||
.assertContainsError()
|
||||
.assertContainsNoItems()
|
||||
.assertDidNotNavigateToAuth()
|
||||
|
|
@ -204,9 +193,9 @@ class MainActivityTest : KoinTest {
|
|||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
ContentData.contentSuccess.forEachIndexed { index, content ->
|
||||
homeRobot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
robot.assertContainsItem(index, FavouriteContent(content, false))
|
||||
}
|
||||
homeRobot.assertDidNotNavigateToAuth()
|
||||
robot.assertDidNotNavigateToAuth()
|
||||
}
|
||||
|
||||
/** GIVEN unauthenticated then error WHEN loaded THEN navigated to auth */
|
||||
|
|
@ -218,6 +207,6 @@ class MainActivityTest : KoinTest {
|
|||
activityScenario = ActivityScenario.launch(MainActivity::class.java)
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
|
||||
homeRobot.assertNavigatedToAuth()
|
||||
robot.assertNavigatedToAuth()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,14 @@ import androidx.test.core.app.ActivityScenario
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.fnives.test.showcase.R
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.SpecificTestConfigurationsFactory
|
||||
import org.fnives.test.showcase.testutils.idling.Disposable
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
|
||||
import org.fnives.test.showcase.testutils.robot.RobotTestRule
|
||||
import org.fnives.test.showcase.ui.auth.AuthActivity
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
|
||||
|
|
@ -23,31 +21,20 @@ class AuthActivityTest : KoinTest {
|
|||
|
||||
private lateinit var activityScenario: ActivityScenario<AuthActivity>
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val robotRule = RobotTestRule(LoginRobot())
|
||||
private val loginRobot get() = robotRule.robot
|
||||
private val mockServerScenarioSetupTestRule = MockServerScenarioSetupResetingTestRule()
|
||||
private val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||
private val mainDispatcherTestRule = MainDispatcherTestRule()
|
||||
private val robot = LoginRobot()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mockServerScenarioSetupTestRule = MockServerScenarioSetupTestRule()
|
||||
val mockServerScenarioSetup get() = mockServerScenarioSetupTestRule.mockServerScenarioSetup
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mainDispatcherTestRule = SpecificTestConfigurationsFactory.createMainDispatcherTestRule()
|
||||
|
||||
private lateinit var disposable: Disposable
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
disposable = NetworkSynchronization.registerNetworkingSynchronization()
|
||||
}
|
||||
val ruleOrder: RuleChain = RuleChain.outerRule(mockServerScenarioSetupTestRule)
|
||||
.around(mainDispatcherTestRule)
|
||||
.around(RobotTestRule(robot))
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
activityScenario.close()
|
||||
disposable.dispose()
|
||||
}
|
||||
|
||||
/** GIVEN non empty password and username and successful response WHEN signIn THEN no error is shown and navigating to home */
|
||||
|
|
@ -57,7 +44,7 @@ class AuthActivityTest : KoinTest {
|
|||
AuthScenario.Success(password = "alma", username = "banan")
|
||||
)
|
||||
activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
loginRobot
|
||||
robot
|
||||
.setPassword("alma")
|
||||
.setUsername("banan")
|
||||
.assertPassword("alma")
|
||||
|
|
@ -66,21 +53,21 @@ class AuthActivityTest : KoinTest {
|
|||
.assertLoadingBeforeRequests()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleOrActivityIsDestroyed()
|
||||
loginRobot.assertNavigatedToHome()
|
||||
robot.assertNavigatedToHome()
|
||||
}
|
||||
|
||||
/** GIVEN empty password and username WHEN signIn THEN error password is shown */
|
||||
@Test
|
||||
fun emptyPasswordShowsProperErrorMessage() {
|
||||
activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
loginRobot
|
||||
robot
|
||||
.setUsername("banan")
|
||||
.assertUsername("banan")
|
||||
.clickOnLogin()
|
||||
.assertLoadingBeforeRequests()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loginRobot.assertErrorIsShown(R.string.password_is_invalid)
|
||||
robot.assertErrorIsShown(R.string.password_is_invalid)
|
||||
.assertNotNavigatedToHome()
|
||||
.assertNotLoading()
|
||||
}
|
||||
|
|
@ -89,14 +76,14 @@ class AuthActivityTest : KoinTest {
|
|||
@Test
|
||||
fun emptyUserNameShowsProperErrorMessage() {
|
||||
activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
loginRobot
|
||||
robot
|
||||
.setPassword("banan")
|
||||
.assertPassword("banan")
|
||||
.clickOnLogin()
|
||||
.assertLoadingBeforeRequests()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loginRobot.assertErrorIsShown(R.string.username_is_invalid)
|
||||
robot.assertErrorIsShown(R.string.username_is_invalid)
|
||||
.assertNotNavigatedToHome()
|
||||
.assertNotLoading()
|
||||
}
|
||||
|
|
@ -108,7 +95,7 @@ class AuthActivityTest : KoinTest {
|
|||
AuthScenario.InvalidCredentials(username = "alma", password = "banan")
|
||||
)
|
||||
activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
loginRobot
|
||||
robot
|
||||
.setUsername("alma")
|
||||
.setPassword("banan")
|
||||
.assertUsername("alma")
|
||||
|
|
@ -117,7 +104,7 @@ class AuthActivityTest : KoinTest {
|
|||
.assertLoadingBeforeRequests()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loginRobot.assertErrorIsShown(R.string.credentials_invalid)
|
||||
robot.assertErrorIsShown(R.string.credentials_invalid)
|
||||
.assertNotNavigatedToHome()
|
||||
.assertNotLoading()
|
||||
}
|
||||
|
|
@ -129,7 +116,7 @@ class AuthActivityTest : KoinTest {
|
|||
AuthScenario.GenericError(username = "alma", password = "banan")
|
||||
)
|
||||
activityScenario = ActivityScenario.launch(AuthActivity::class.java)
|
||||
loginRobot
|
||||
robot
|
||||
.setUsername("alma")
|
||||
.setPassword("banan")
|
||||
.assertUsername("alma")
|
||||
|
|
@ -138,7 +125,7 @@ class AuthActivityTest : KoinTest {
|
|||
.assertLoadingBeforeRequests()
|
||||
|
||||
mainDispatcherTestRule.advanceUntilIdleWithIdlingResources()
|
||||
loginRobot.assertErrorIsShown(R.string.something_went_wrong)
|
||||
robot.assertErrorIsShown(R.string.something_went_wrong)
|
||||
.assertNotNavigatedToHome()
|
||||
.assertNotLoading()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ package org.fnives.test.showcase.ui.splash
|
|||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.SpecificTestConfigurationsFactory
|
||||
import org.fnives.test.showcase.testutils.idling.Disposable
|
||||
import org.fnives.test.showcase.testutils.idling.NetworkSynchronization
|
||||
import org.fnives.test.showcase.testutils.MockServerScenarioSetupResetingTestRule
|
||||
import org.fnives.test.showcase.testutils.configuration.MainDispatcherTestRule
|
||||
import org.fnives.test.showcase.testutils.robot.RobotTestRule
|
||||
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState.setupLogin
|
||||
import org.fnives.test.showcase.testutils.statesetup.SetupAuthenticationState.setupLogout
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
|
||||
|
|
@ -21,44 +21,33 @@ class SplashActivityTest : KoinTest {
|
|||
|
||||
private lateinit var activityScenario: ActivityScenario<SplashActivity>
|
||||
|
||||
private val splashRobot: SplashRobot get() = robotTestRule.robot
|
||||
private val mainDispatcherTestRule = MainDispatcherTestRule()
|
||||
private val mockServerScenarioSetupTestRule = MockServerScenarioSetupResetingTestRule()
|
||||
|
||||
private val robot = SplashRobot()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val robotTestRule = RobotTestRule(SplashRobot())
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mainDispatcherTestRule = SpecificTestConfigurationsFactory.createMainDispatcherTestRule()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val mockServerScenarioSetupTestRule = MockServerScenarioSetupTestRule()
|
||||
|
||||
lateinit var disposable: Disposable
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
disposable = NetworkSynchronization.registerNetworkingSynchronization()
|
||||
}
|
||||
val ruleOrder: RuleChain = RuleChain.outerRule(mockServerScenarioSetupTestRule)
|
||||
.around(mainDispatcherTestRule)
|
||||
.around(RobotTestRule(robot))
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
activityScenario.close()
|
||||
disposable.dispose()
|
||||
}
|
||||
|
||||
/** GIVEN loggedInState WHEN opened after some time THEN MainActivity is started */
|
||||
@Test
|
||||
fun loggedInStateNavigatesToHome() {
|
||||
splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
|
||||
setupLogin(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
|
||||
|
||||
activityScenario = ActivityScenario.launch(SplashActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
|
||||
mainDispatcherTestRule.advanceTimeBy(501)
|
||||
|
||||
splashRobot.assertHomeIsStarted()
|
||||
robot.assertHomeIsStarted()
|
||||
.assertAuthIsNotStarted()
|
||||
|
||||
workaroundForActivityScenarioCLoseLockingUp()
|
||||
|
|
@ -67,13 +56,13 @@ class SplashActivityTest : KoinTest {
|
|||
/** GIVEN loggedOffState WHEN opened after some time THEN AuthActivity is started */
|
||||
@Test
|
||||
fun loggedOutStatesNavigatesToAuthentication() {
|
||||
splashRobot.setupLoggedOutState(mainDispatcherTestRule)
|
||||
setupLogout(mainDispatcherTestRule)
|
||||
activityScenario = ActivityScenario.launch(SplashActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
|
||||
mainDispatcherTestRule.advanceTimeBy(501)
|
||||
|
||||
splashRobot.assertAuthIsStarted()
|
||||
robot.assertAuthIsStarted()
|
||||
.assertHomeIsNotStarted()
|
||||
|
||||
workaroundForActivityScenarioCLoseLockingUp()
|
||||
|
|
@ -82,27 +71,27 @@ class SplashActivityTest : KoinTest {
|
|||
/** GIVEN loggedOffState and not enough time WHEN opened THEN no activity is started */
|
||||
@Test
|
||||
fun loggedOutStatesNotEnoughTime() {
|
||||
splashRobot.setupLoggedOutState(mainDispatcherTestRule)
|
||||
setupLogout(mainDispatcherTestRule)
|
||||
activityScenario = ActivityScenario.launch(SplashActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
|
||||
mainDispatcherTestRule.advanceTimeBy(10)
|
||||
|
||||
splashRobot.assertAuthIsNotStarted()
|
||||
robot.assertAuthIsNotStarted()
|
||||
.assertHomeIsNotStarted()
|
||||
}
|
||||
|
||||
/** GIVEN loggedInState and not enough time WHEN opened THEN no activity is started */
|
||||
@Test
|
||||
fun loggedInStatesNotEnoughTime() {
|
||||
splashRobot.setupLoggedInState(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
|
||||
setupLogin(mainDispatcherTestRule, mockServerScenarioSetupTestRule.mockServerScenarioSetup)
|
||||
|
||||
activityScenario = ActivityScenario.launch(SplashActivity::class.java)
|
||||
activityScenario.moveToState(Lifecycle.State.RESUMED)
|
||||
|
||||
mainDispatcherTestRule.advanceTimeBy(10)
|
||||
|
||||
splashRobot.assertHomeIsNotStarted()
|
||||
robot.assertHomeIsNotStarted()
|
||||
.assertAuthIsNotStarted()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
package org.fnives.test.showcase.ui.splash
|
||||
|
||||
import android.app.Instrumentation
|
||||
import androidx.test.espresso.intent.Intents
|
||||
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.statesetup.SetupAuthenticationState
|
||||
import org.fnives.test.showcase.testutils.viewactions.notIntended
|
||||
import org.fnives.test.showcase.ui.auth.AuthActivity
|
||||
import org.fnives.test.showcase.ui.home.MainActivity
|
||||
|
|
@ -15,33 +11,12 @@ class SplashRobot : Robot {
|
|||
|
||||
override fun init() {
|
||||
Intents.init()
|
||||
Intents.intending(IntentMatchers.hasComponent(MainActivity::class.java.canonicalName))
|
||||
.respondWith(Instrumentation.ActivityResult(0, null))
|
||||
Intents.intending(IntentMatchers.hasComponent(AuthActivity::class.java.canonicalName))
|
||||
.respondWith(Instrumentation.ActivityResult(0, null))
|
||||
}
|
||||
|
||||
override fun 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 {
|
||||
Intents.intended(IntentMatchers.hasComponent(MainActivity::class.java.canonicalName))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue