mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Move the fake entry points of RootFlowNodeTest to the test modules
The fakes were declared in RootFlowNodeTest, so other tests could not use them. Move each of them next to the API it fakes, following the existing convention of a createNodeResult lambda defaulting to lambdaError(): - FakeLoginEntryPoint in features/login/test - FakeBugReportEntryPoint in features/rageshake/test - FakeSignedOutEntryPoint in features/signedout/test (new module) - FakeAccountSelectEntryPoint in libraries/accountselect/test (new module) The login and rageshake test modules did not have Appyx on their classpath, so add the architecture module to their dependencies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,7 @@ dependencies {
|
||||
testCommonDependencies(libs)
|
||||
testImplementation(projects.features.login.test)
|
||||
testImplementation(projects.features.share.test)
|
||||
testImplementation(projects.libraries.accountselect.test)
|
||||
testImplementation(projects.libraries.featureflag.test)
|
||||
testImplementation(projects.libraries.matrix.test)
|
||||
testImplementation(projects.libraries.matrixmedia.test)
|
||||
@@ -75,6 +76,7 @@ dependencies {
|
||||
testImplementation(projects.features.messages.test)
|
||||
testImplementation(projects.features.networkmonitor.test)
|
||||
testImplementation(projects.features.rageshake.test)
|
||||
testImplementation(projects.features.signedout.test)
|
||||
testImplementation(projects.services.apperror.test)
|
||||
testImplementation(projects.services.appnavstate.test)
|
||||
testImplementation(projects.services.analytics.test)
|
||||
|
||||
@@ -33,13 +33,14 @@ import io.element.android.appnav.root.RootPresenter
|
||||
import io.element.android.features.login.api.LoginEntryPoint
|
||||
import io.element.android.features.login.api.LoginParams
|
||||
import io.element.android.features.login.api.accesscontrol.AccountProviderAccessControl
|
||||
import io.element.android.features.login.test.FakeLoginEntryPoint
|
||||
import io.element.android.features.login.test.FakeLoginIntentResolver
|
||||
import io.element.android.features.preferences.api.CacheService
|
||||
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
|
||||
import io.element.android.features.rageshake.test.FakeBugReportEntryPoint
|
||||
import io.element.android.features.rageshake.test.logs.FakeAnnouncementService
|
||||
import io.element.android.features.share.test.FakeShareIntentHandler
|
||||
import io.element.android.features.signedout.api.SignedOutEntryPoint
|
||||
import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
|
||||
import io.element.android.features.signedout.test.FakeSignedOutEntryPoint
|
||||
import io.element.android.libraries.accountselect.test.FakeAccountSelectEntryPoint
|
||||
import io.element.android.libraries.architecture.AssistedNodeFactory
|
||||
import io.element.android.libraries.architecture.NodeFactoriesBindings
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
@@ -81,8 +82,13 @@ class RootFlowNodeTest : RobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `given no session, when a login link is handled before the nav state is observed, then the login params are kept`() = runTest {
|
||||
val loginEntryPoint = FakeLoginEntryPoint()
|
||||
val rootFlowNode = createRootFlowNode(loginEntryPoint = loginEntryPoint)
|
||||
var loginEntryPointParams: LoginEntryPoint.Params? = null
|
||||
val rootFlowNode = createRootFlowNode(
|
||||
loginEntryPoint = FakeLoginEntryPoint { buildContext, params ->
|
||||
loginEntryPointParams = params
|
||||
node(buildContext) {}
|
||||
},
|
||||
)
|
||||
rootFlowNode.parentNodeTestHelper()
|
||||
// The intent is handled first, this is what happens when the deep link cold starts the app.
|
||||
rootFlowNode.handleIntent(aLoginIntent())
|
||||
@@ -90,13 +96,18 @@ class RootFlowNodeTest : RobolectricTest() {
|
||||
// Then the first nav state emission lands, it must not override the login params.
|
||||
runCurrent()
|
||||
assertThat(rootFlowNode.backstack.activeElement).isEqualTo(RootFlowNode.NavTarget.NotLoggedInFlow(A_LOGIN_PARAMS))
|
||||
assertThat(loginEntryPoint.params).isEqualTo(A_LOGIN_ENTRY_POINT_PARAMS)
|
||||
assertThat(loginEntryPointParams).isEqualTo(A_LOGIN_ENTRY_POINT_PARAMS)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given no session, when a login link is handled after the nav state is observed, then the login params are applied`() = runTest {
|
||||
val loginEntryPoint = FakeLoginEntryPoint()
|
||||
val rootFlowNode = createRootFlowNode(loginEntryPoint = loginEntryPoint)
|
||||
var loginEntryPointParams: LoginEntryPoint.Params? = null
|
||||
val rootFlowNode = createRootFlowNode(
|
||||
loginEntryPoint = FakeLoginEntryPoint { buildContext, params ->
|
||||
loginEntryPointParams = params
|
||||
node(buildContext) {}
|
||||
},
|
||||
)
|
||||
rootFlowNode.parentNodeTestHelper()
|
||||
// The nav state is observed first, this is what happens when the app is already running.
|
||||
runCurrent()
|
||||
@@ -104,13 +115,13 @@ class RootFlowNodeTest : RobolectricTest() {
|
||||
rootFlowNode.handleIntent(aLoginIntent())
|
||||
runCurrent()
|
||||
assertThat(rootFlowNode.backstack.activeElement).isEqualTo(RootFlowNode.NavTarget.NotLoggedInFlow(A_LOGIN_PARAMS))
|
||||
assertThat(loginEntryPoint.params).isEqualTo(A_LOGIN_ENTRY_POINT_PARAMS)
|
||||
assertThat(loginEntryPointParams).isEqualTo(A_LOGIN_ENTRY_POINT_PARAMS)
|
||||
}
|
||||
|
||||
private fun aLoginIntent() = Intent(Intent.ACTION_VIEW, Uri.parse(A_LOGIN_LINK))
|
||||
|
||||
private fun TestScope.createRootFlowNode(
|
||||
loginEntryPoint: LoginEntryPoint = FakeLoginEntryPoint(),
|
||||
loginEntryPoint: LoginEntryPoint,
|
||||
sessionStore: SessionStore = InMemorySessionStore(),
|
||||
): RootFlowNode {
|
||||
val matrixSessionCache = MatrixSessionCache(
|
||||
@@ -215,33 +226,6 @@ private class FakeAccountProviderAccessControl : AccountProviderAccessControl {
|
||||
override suspend fun isAllowedToConnectToAccountProvider(accountProviderUrl: String) = true
|
||||
}
|
||||
|
||||
private class FakeBugReportEntryPoint : BugReportEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, callback: BugReportEntryPoint.Callback): Node = node(buildContext) {}
|
||||
}
|
||||
|
||||
private class FakeSignedOutEntryPoint : SignedOutEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, params: SignedOutEntryPoint.Params): Node = node(buildContext) {}
|
||||
}
|
||||
|
||||
private class FakeAccountSelectEntryPoint : AccountSelectEntryPoint {
|
||||
override fun createNode(parentNode: Node, buildContext: BuildContext, callback: AccountSelectEntryPoint.Callback): Node = node(buildContext) {}
|
||||
}
|
||||
|
||||
private class FakeLoginEntryPoint : LoginEntryPoint {
|
||||
var params: LoginEntryPoint.Params? = null
|
||||
private set
|
||||
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
params: LoginEntryPoint.Params,
|
||||
callback: LoginEntryPoint.Callback,
|
||||
): Node {
|
||||
this.params = params
|
||||
return node(buildContext) {}
|
||||
}
|
||||
}
|
||||
|
||||
private class FakeNodeFactoriesBindings(
|
||||
private val nodeFactories: Map<KClass<out Node>, AssistedNodeFactory<*>>,
|
||||
) : NodeFactoriesBindings {
|
||||
|
||||
@@ -15,6 +15,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.features.login.api)
|
||||
implementation(projects.tests.testutils)
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.login.test
|
||||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import io.element.android.features.login.api.LoginEntryPoint
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeLoginEntryPoint(
|
||||
private val createNodeResult: (BuildContext, LoginEntryPoint.Params) -> Node = { _, _ -> lambdaError() },
|
||||
) : LoginEntryPoint {
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
params: LoginEntryPoint.Params,
|
||||
callback: LoginEntryPoint.Callback,
|
||||
): Node = createNodeResult(buildContext, params)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.features.rageshake.api)
|
||||
implementation(libs.coroutines.core)
|
||||
implementation(projects.tests.testutils)
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.rageshake.test
|
||||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeBugReportEntryPoint(
|
||||
private val createNodeResult: (BuildContext, BugReportEntryPoint.Callback) -> Node = { _, _ -> lambdaError() },
|
||||
) : BugReportEntryPoint {
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
callback: BugReportEntryPoint.Callback,
|
||||
): Node = createNodeResult(buildContext, callback)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.features.signedout.test"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.features.signedout.api)
|
||||
implementation(projects.tests.testutils)
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.signedout.test
|
||||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import io.element.android.features.signedout.api.SignedOutEntryPoint
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeSignedOutEntryPoint(
|
||||
private val createNodeResult: (BuildContext, SignedOutEntryPoint.Params) -> Node = { _, _ -> lambdaError() },
|
||||
) : SignedOutEntryPoint {
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
params: SignedOutEntryPoint.Params,
|
||||
): Node = createNodeResult(buildContext, params)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
plugins {
|
||||
id("io.element.android-library")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.libraries.accountselect.test"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.accountselect.api)
|
||||
implementation(projects.tests.testutils)
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.accountselect.test
|
||||
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeAccountSelectEntryPoint(
|
||||
private val createNodeResult: (BuildContext, AccountSelectEntryPoint.Callback) -> Node = { _, _ -> lambdaError() },
|
||||
) : AccountSelectEntryPoint {
|
||||
override fun createNode(
|
||||
parentNode: Node,
|
||||
buildContext: BuildContext,
|
||||
callback: AccountSelectEntryPoint.Callback,
|
||||
): Node = createNodeResult(buildContext, callback)
|
||||
}
|
||||
Reference in New Issue
Block a user