Add test on DefaultEntryPoints
This commit is contained in:
parent
629fc552e5
commit
e36273b94c
93 changed files with 2426 additions and 418 deletions
|
|
@ -9,6 +9,6 @@ package io.element.android.appnav.di
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
|
|
||||||
interface RoomComponentFactory {
|
fun interface RoomComponentFactory {
|
||||||
fun create(room: JoinedRoom): Any
|
fun create(room: JoinedRoom): Any
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,4 @@ package io.element.android.features.analytics.api
|
||||||
|
|
||||||
import io.element.android.libraries.architecture.SimpleFeatureEntryPoint
|
import io.element.android.libraries.architecture.SimpleFeatureEntryPoint
|
||||||
|
|
||||||
interface AnalyticsEntryPoint : SimpleFeatureEntryPoint
|
fun interface AnalyticsEntryPoint : SimpleFeatureEntryPoint
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import io.element.android.libraries.architecture.NodeInputs
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
|
|
||||||
interface ChangeRoomMemberRolesEntryPoint : FeatureEntryPoint {
|
fun interface ChangeRoomMemberRolesEntryPoint : FeatureEntryPoint {
|
||||||
fun builder(parentNode: Node, buildContext: BuildContext): Builder
|
fun builder(parentNode: Node, buildContext: BuildContext): Builder
|
||||||
|
|
||||||
interface Builder {
|
interface Builder {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class ChangeRolesPresenter(
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
) : Presenter<ChangeRolesState> {
|
) : Presenter<ChangeRolesState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(role: RoomMember.Role): ChangeRolesPresenter
|
fun create(role: RoomMember.Role): ChangeRolesPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ import kotlinx.collections.immutable.toPersistentMap
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.collections.plus
|
|
||||||
|
|
||||||
class ChangeRolesPresenterTest {
|
class ChangeRolesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -556,18 +555,18 @@ class ChangeRolesPresenterTest {
|
||||||
users = pairs.associate { (userId, role) -> userId to role.powerLevel }.toPersistentMap()
|
users = pairs.associate { (userId, role) -> userId to role.powerLevel }.toPersistentMap()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun TestScope.createChangeRolesPresenter(
|
|
||||||
role: RoomMember.Role = RoomMember.Role.Admin,
|
internal fun TestScope.createChangeRolesPresenter(
|
||||||
room: FakeJoinedRoom = FakeJoinedRoom(baseRoom = FakeBaseRoom(updateMembersResult = {})),
|
role: RoomMember.Role = RoomMember.Role.Admin,
|
||||||
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
room: FakeJoinedRoom = FakeJoinedRoom(baseRoom = FakeBaseRoom(updateMembersResult = {})),
|
||||||
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||||
): ChangeRolesPresenter {
|
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||||
return ChangeRolesPresenter(
|
): ChangeRolesPresenter {
|
||||||
role = role,
|
return ChangeRolesPresenter(
|
||||||
room = room,
|
role = role,
|
||||||
dispatchers = dispatchers,
|
room = room,
|
||||||
analyticsService = analyticsService,
|
dispatchers = dispatchers,
|
||||||
)
|
analyticsService = analyticsService,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.changeroommemberroles.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultChangeRoomMemberRolesEntyPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultChangeRoomMemberRolesEntyPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
ChangeRoomMemberRolesRootNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
roomComponentFactory = { },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val room = FakeJoinedRoom()
|
||||||
|
val listType = ChangeRoomMemberRolesListType.Admins
|
||||||
|
val result = entryPoint.builder(parentNode, BuildContext.root(null))
|
||||||
|
.room(FakeJoinedRoom())
|
||||||
|
.listType(listType)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(ChangeRoomMemberRolesRootNode::class.java)
|
||||||
|
// Search for the Inputs plugin
|
||||||
|
val input = result.plugins.filterIsInstance<ChangeRoomMemberRolesRootNode.Inputs>().single()
|
||||||
|
assertThat(input.joinedRoom.roomId).isEqualTo(room.roomId)
|
||||||
|
assertThat(input.listType).isEqualTo(listType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.createroom.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.createroom.api.CreateRoomEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultCreateRoomEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultCreateRoomEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
CreateRoomFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : CreateRoomEntryPoint.Callback {
|
||||||
|
override fun onRoomCreated(roomId: RoomId) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -149,9 +149,10 @@ class AccountDeactivationPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPresenter(
|
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
|
||||||
) = AccountDeactivationPresenter(
|
|
||||||
matrixClient = matrixClient,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createPresenter(
|
||||||
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
|
) = AccountDeactivationPresenter(
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.logout.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultAccountDeactivationEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultAccountDeactivationEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
AccountDeactivationNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createPresenter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.createNode(parentNode, BuildContext.root(null))
|
||||||
|
assertThat(result).isInstanceOf(AccountDeactivationNode::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.ftue.impl
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultFtueEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultFtueEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
FtueFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
analyticsEntryPoint = { _, _ -> lambdaError() },
|
||||||
|
ftueState = createDefaultFtueService(),
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
lockScreenEntryPoint = object : LockScreenEntryPoint {
|
||||||
|
override fun nodeBuilder(
|
||||||
|
parentNode: com.bumble.appyx.core.node.Node,
|
||||||
|
buildContext: BuildContext,
|
||||||
|
navTarget: LockScreenEntryPoint.Target
|
||||||
|
): LockScreenEntryPoint.NodeBuilder {
|
||||||
|
lambdaError()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pinUnlockIntent(context: Context): Intent {
|
||||||
|
lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(FtueFlowNode::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -226,22 +226,22 @@ class DefaultFtueServiceTest {
|
||||||
resetPermissionLambda.assertions().isCalledOnce()
|
resetPermissionLambda.assertions().isCalledOnce()
|
||||||
.with(value("android.permission.POST_NOTIFICATIONS"))
|
.with(value("android.permission.POST_NOTIFICATIONS"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createDefaultFtueService(
|
|
||||||
sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
|
|
||||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
|
||||||
permissionStateProvider: PermissionStateProvider = FakePermissionStateProvider(permissionGranted = false),
|
|
||||||
lockScreenService: LockScreenService = FakeLockScreenService(),
|
|
||||||
sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(),
|
|
||||||
// First version where notification permission is required
|
|
||||||
sdkIntVersion: Int = Build.VERSION_CODES.TIRAMISU,
|
|
||||||
) = DefaultFtueService(
|
|
||||||
sessionCoroutineScope = backgroundScope,
|
|
||||||
sessionVerificationService = sessionVerificationService,
|
|
||||||
sdkVersionProvider = FakeBuildVersionSdkIntProvider(sdkIntVersion),
|
|
||||||
analyticsService = analyticsService,
|
|
||||||
permissionStateProvider = permissionStateProvider,
|
|
||||||
lockScreenService = lockScreenService,
|
|
||||||
sessionPreferencesStore = sessionPreferencesStore,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun TestScope.createDefaultFtueService(
|
||||||
|
sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
|
||||||
|
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||||
|
permissionStateProvider: PermissionStateProvider = FakePermissionStateProvider(permissionGranted = false),
|
||||||
|
lockScreenService: LockScreenService = FakeLockScreenService(),
|
||||||
|
sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(),
|
||||||
|
// First version where notification permission is required
|
||||||
|
sdkIntVersion: Int = Build.VERSION_CODES.TIRAMISU,
|
||||||
|
) = DefaultFtueService(
|
||||||
|
sessionCoroutineScope = backgroundScope,
|
||||||
|
sessionVerificationService = sessionVerificationService,
|
||||||
|
sdkVersionProvider = FakeBuildVersionSdkIntProvider(sdkIntVersion),
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
permissionStateProvider = permissionStateProvider,
|
||||||
|
lockScreenService = lockScreenService,
|
||||||
|
sessionPreferencesStore = sessionPreferencesStore,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.home.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.home.api.HomeEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultHomeEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultHomeEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
HomeFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
matrixClient = FakeMatrixClient(),
|
||||||
|
presenter = createHomePresenter(),
|
||||||
|
inviteFriendsUseCase = { lambdaError() },
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
acceptDeclineInviteView = { _, _, _, _ -> lambdaError() },
|
||||||
|
directLogoutView = { _ -> lambdaError() },
|
||||||
|
reportRoomEntryPoint = { _, _, _ -> lambdaError() },
|
||||||
|
declineInviteAndBlockUserEntryPoint = { _, _, _ -> lambdaError() },
|
||||||
|
changeRoomMemberRolesEntryPoint = { _, _ -> lambdaError() },
|
||||||
|
leaveRoomRenderer = { _, _, _ -> lambdaError() },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : HomeEntryPoint.Callback {
|
||||||
|
override fun onRoomClick(roomId: RoomId) = lambdaError()
|
||||||
|
override fun onStartChatClick() = lambdaError()
|
||||||
|
override fun onSettingsClick() = lambdaError()
|
||||||
|
override fun onSetUpRecoveryClick() = lambdaError()
|
||||||
|
override fun onSessionConfirmRecoveryKeyClick() = lambdaError()
|
||||||
|
override fun onRoomSettingsClick(roomId: RoomId) = lambdaError()
|
||||||
|
override fun onReportBugClick() = lambdaError()
|
||||||
|
override fun onLogoutForNativeSlidingSyncMigrationNeeded() = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(HomeFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -175,24 +175,24 @@ class HomePresenterTest {
|
||||||
assertThat(finalState.showNavigationBar).isFalse()
|
assertThat(finalState.showNavigationBar).isFalse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createHomePresenter(
|
|
||||||
client: MatrixClient = FakeMatrixClient(),
|
|
||||||
syncService: SyncService = FakeSyncService(),
|
|
||||||
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
|
|
||||||
rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) },
|
|
||||||
indicatorService: IndicatorService = FakeIndicatorService(),
|
|
||||||
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
|
|
||||||
homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() },
|
|
||||||
) = HomePresenter(
|
|
||||||
client = client,
|
|
||||||
syncService = syncService,
|
|
||||||
snackbarDispatcher = snackbarDispatcher,
|
|
||||||
indicatorService = indicatorService,
|
|
||||||
logoutPresenter = { aDirectLogoutState() },
|
|
||||||
roomListPresenter = { aRoomListState() },
|
|
||||||
homeSpacesPresenter = homeSpacesPresenter,
|
|
||||||
rageshakeFeatureAvailability = rageshakeFeatureAvailability,
|
|
||||||
featureFlagService = featureFlagService,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createHomePresenter(
|
||||||
|
client: MatrixClient = FakeMatrixClient(),
|
||||||
|
syncService: SyncService = FakeSyncService(),
|
||||||
|
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
|
||||||
|
rageshakeFeatureAvailability: RageshakeFeatureAvailability = RageshakeFeatureAvailability { flowOf(false) },
|
||||||
|
indicatorService: IndicatorService = FakeIndicatorService(),
|
||||||
|
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
|
||||||
|
homeSpacesPresenter: Presenter<HomeSpacesState> = Presenter { aHomeSpacesState() },
|
||||||
|
) = HomePresenter(
|
||||||
|
client = client,
|
||||||
|
syncService = syncService,
|
||||||
|
snackbarDispatcher = snackbarDispatcher,
|
||||||
|
indicatorService = indicatorService,
|
||||||
|
logoutPresenter = { aDirectLogoutState() },
|
||||||
|
roomListPresenter = { aRoomListState() },
|
||||||
|
homeSpacesPresenter = homeSpacesPresenter,
|
||||||
|
rageshakeFeatureAvailability = rageshakeFeatureAvailability,
|
||||||
|
featureFlagService = featureFlagService,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
interface AcceptDeclineInviteView {
|
fun interface AcceptDeclineInviteView {
|
||||||
@Composable
|
@Composable
|
||||||
fun Render(
|
fun Render(
|
||||||
state: AcceptDeclineInviteState,
|
state: AcceptDeclineInviteState,
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ import com.bumble.appyx.core.node.Node
|
||||||
import io.element.android.features.invite.api.InviteData
|
import io.element.android.features.invite.api.InviteData
|
||||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||||
|
|
||||||
interface DeclineInviteAndBlockEntryPoint : FeatureEntryPoint {
|
fun interface DeclineInviteAndBlockEntryPoint : FeatureEntryPoint {
|
||||||
fun createNode(parentNode: Node, buildContext: BuildContext, inviteData: InviteData): Node
|
fun createNode(parentNode: Node, buildContext: BuildContext, inviteData: InviteData): Node
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class DeclineAndBlockPresenter(
|
||||||
private val snackbarDispatcher: SnackbarDispatcher,
|
private val snackbarDispatcher: SnackbarDispatcher,
|
||||||
) : Presenter<DeclineAndBlockState> {
|
) : Presenter<DeclineAndBlockState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(inviteData: InviteData): DeclineAndBlockPresenter
|
fun create(inviteData: InviteData): DeclineAndBlockPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.invite.api.InviteData
|
import io.element.android.features.invite.api.InviteData
|
||||||
import io.element.android.features.invite.impl.DeclineInvite
|
import io.element.android.features.invite.impl.DeclineInvite
|
||||||
import io.element.android.features.invite.impl.fake.FakeDeclineInvite
|
import io.element.android.features.invite.impl.fake.FakeDeclineInvite
|
||||||
|
import io.element.android.features.invite.test.anInviteData
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
@ -148,28 +149,16 @@ class DeclineAndBlockPresenterTest {
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.with(value(A_ROOM_ID), value(true), value(false), value(""))
|
.with(value(A_ROOM_ID), value(true), value(false), value(""))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun anInviteData(
|
|
||||||
roomId: RoomId = A_ROOM_ID,
|
internal fun createDeclineAndBlockPresenter(
|
||||||
name: String = A_ROOM_NAME,
|
inviteData: InviteData = anInviteData(),
|
||||||
isDm: Boolean = false,
|
declineInvite: DeclineInvite = FakeDeclineInvite(),
|
||||||
): InviteData {
|
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
|
||||||
return InviteData(
|
): DeclineAndBlockPresenter {
|
||||||
roomId = roomId,
|
return DeclineAndBlockPresenter(
|
||||||
roomName = name,
|
inviteData = inviteData,
|
||||||
isDm = isDm,
|
declineInvite = declineInvite,
|
||||||
)
|
snackbarDispatcher = snackbarDispatcher,
|
||||||
}
|
)
|
||||||
|
|
||||||
private fun createDeclineAndBlockPresenter(
|
|
||||||
inviteData: InviteData = anInviteData(),
|
|
||||||
declineInvite: DeclineInvite = FakeDeclineInvite(),
|
|
||||||
snackbarDispatcher: SnackbarDispatcher = SnackbarDispatcher(),
|
|
||||||
): DeclineAndBlockPresenter {
|
|
||||||
return DeclineAndBlockPresenter(
|
|
||||||
inviteData = inviteData,
|
|
||||||
declineInvite = declineInvite,
|
|
||||||
snackbarDispatcher = snackbarDispatcher,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.invite.impl.declineandblock
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.invite.test.anInviteData
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultDeclineAndBlockEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultDeclineAndBlockEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
DeclineAndBlockNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { inviteData -> createDeclineAndBlockPresenter() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val inviteData = anInviteData()
|
||||||
|
val result = entryPoint.createNode(
|
||||||
|
parentNode = parentNode,
|
||||||
|
buildContext = BuildContext.root(null),
|
||||||
|
inviteData = inviteData
|
||||||
|
)
|
||||||
|
assertThat(result).isInstanceOf(DeclineAndBlockNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(DeclineAndBlockNode.Inputs(inviteData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ class JoinRoomPresenter(
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
private val seenInvitesStore: SeenInvitesStore,
|
private val seenInvitesStore: SeenInvitesStore,
|
||||||
) : Presenter<JoinRoomState> {
|
) : Presenter<JoinRoomState> {
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
roomId: RoomId,
|
roomId: RoomId,
|
||||||
roomIdOrAlias: RoomIdOrAlias,
|
roomIdOrAlias: RoomIdOrAlias,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.joinroom.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||||
|
import io.element.android.features.invite.api.InviteData
|
||||||
|
import io.element.android.features.invite.api.declineandblock.DeclineInviteAndBlockEntryPoint
|
||||||
|
import io.element.android.features.joinroom.api.JoinRoomEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||||
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import java.util.Optional
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultJoinRoomEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultJoinRoomEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
JoinRoomFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { _, _, _, _, _ -> createJoinRoomPresenter() },
|
||||||
|
acceptDeclineInviteView = { _, _, _, _ -> lambdaError() },
|
||||||
|
declineAndBlockEntryPoint = object : DeclineInviteAndBlockEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext, inviteData: InviteData) = lambdaError()
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val inputs = JoinRoomEntryPoint.Inputs(
|
||||||
|
roomId = A_ROOM_ID,
|
||||||
|
roomIdOrAlias = A_ROOM_ID.toRoomIdOrAlias(),
|
||||||
|
roomDescription = Optional.ofNullable(null),
|
||||||
|
serverNames = emptyList(),
|
||||||
|
trigger = JoinedRoom.Trigger.RoomDirectory,
|
||||||
|
)
|
||||||
|
val result = entryPoint.createNode(parentNode, BuildContext.root(null), inputs)
|
||||||
|
assertThat(result).isInstanceOf(JoinRoomFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(inputs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1042,39 +1042,6 @@ class JoinRoomPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createJoinRoomPresenter(
|
|
||||||
roomId: RoomId = A_ROOM_ID,
|
|
||||||
roomDescription: Optional<RoomDescription> = Optional.empty(),
|
|
||||||
serverNames: List<String> = emptyList(),
|
|
||||||
trigger: JoinedRoom.Trigger = JoinedRoom.Trigger.Invite,
|
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
|
||||||
joinRoomLambda: (RoomIdOrAlias, List<String>, JoinedRoom.Trigger) -> Result<Unit> = { _, _, _ ->
|
|
||||||
Result.success(Unit)
|
|
||||||
},
|
|
||||||
knockRoom: KnockRoom = FakeKnockRoom(),
|
|
||||||
cancelKnockRoom: CancelKnockRoom = FakeCancelKnockRoom(),
|
|
||||||
forgetRoom: ForgetRoom = FakeForgetRoom(),
|
|
||||||
buildMeta: BuildMeta = aBuildMeta(applicationName = "AppName"),
|
|
||||||
acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState> = Presenter { anAcceptDeclineInviteState() },
|
|
||||||
seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(),
|
|
||||||
): JoinRoomPresenter {
|
|
||||||
return JoinRoomPresenter(
|
|
||||||
roomId = roomId,
|
|
||||||
roomIdOrAlias = roomId.toRoomIdOrAlias(),
|
|
||||||
roomDescription = roomDescription,
|
|
||||||
serverNames = serverNames,
|
|
||||||
trigger = trigger,
|
|
||||||
matrixClient = matrixClient,
|
|
||||||
joinRoom = FakeJoinRoom(joinRoomLambda),
|
|
||||||
knockRoom = knockRoom,
|
|
||||||
cancelKnockRoom = cancelKnockRoom,
|
|
||||||
forgetRoom = forgetRoom,
|
|
||||||
buildMeta = buildMeta,
|
|
||||||
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
|
|
||||||
seenInvitesStore = seenInvitesStore,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun aRoomDescription(
|
private fun aRoomDescription(
|
||||||
roomId: RoomId = A_ROOM_ID,
|
roomId: RoomId = A_ROOM_ID,
|
||||||
name: String? = A_ROOM_NAME,
|
name: String? = A_ROOM_NAME,
|
||||||
|
|
@ -1095,3 +1062,36 @@ class JoinRoomPresenterTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createJoinRoomPresenter(
|
||||||
|
roomId: RoomId = A_ROOM_ID,
|
||||||
|
roomDescription: Optional<RoomDescription> = Optional.empty(),
|
||||||
|
serverNames: List<String> = emptyList(),
|
||||||
|
trigger: JoinedRoom.Trigger = JoinedRoom.Trigger.Invite,
|
||||||
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
|
joinRoomLambda: (RoomIdOrAlias, List<String>, JoinedRoom.Trigger) -> Result<Unit> = { _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
},
|
||||||
|
knockRoom: KnockRoom = FakeKnockRoom(),
|
||||||
|
cancelKnockRoom: CancelKnockRoom = FakeCancelKnockRoom(),
|
||||||
|
forgetRoom: ForgetRoom = FakeForgetRoom(),
|
||||||
|
buildMeta: BuildMeta = aBuildMeta(applicationName = "AppName"),
|
||||||
|
acceptDeclineInvitePresenter: Presenter<AcceptDeclineInviteState> = Presenter { anAcceptDeclineInviteState() },
|
||||||
|
seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(),
|
||||||
|
): JoinRoomPresenter {
|
||||||
|
return JoinRoomPresenter(
|
||||||
|
roomId = roomId,
|
||||||
|
roomIdOrAlias = roomId.toRoomIdOrAlias(),
|
||||||
|
roomDescription = roomDescription,
|
||||||
|
serverNames = serverNames,
|
||||||
|
trigger = trigger,
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
joinRoom = FakeJoinRoom(joinRoomLambda),
|
||||||
|
knockRoom = knockRoom,
|
||||||
|
cancelKnockRoom = cancelKnockRoom,
|
||||||
|
forgetRoom = forgetRoom,
|
||||||
|
buildMeta = buildMeta,
|
||||||
|
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
|
||||||
|
seenInvitesStore = seenInvitesStore,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.knockrequests.impl.list
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultKnockRequestsListEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultKnockRequestsListEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
KnockRequestsListNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createKnockRequestsListPresenter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.createNode(parentNode, BuildContext.root(null))
|
||||||
|
assertThat(result).isInstanceOf(KnockRequestsListNode::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -286,19 +286,19 @@ class KnockRequestsListPresenterTest {
|
||||||
assert(acceptFailureLambda).isCalledOnce()
|
assert(acceptFailureLambda).isCalledOnce()
|
||||||
assert(acceptSuccessLambda).isCalledOnce()
|
assert(acceptSuccessLambda).isCalledOnce()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun TestScope.createKnockRequestsListPresenter(
|
|
||||||
canAccept: Boolean = true,
|
internal fun TestScope.createKnockRequestsListPresenter(
|
||||||
canDecline: Boolean = true,
|
canAccept: Boolean = true,
|
||||||
canBan: Boolean = true,
|
canDecline: Boolean = true,
|
||||||
knockRequestsFlow: Flow<List<KnockRequest>> = flowOf(emptyList())
|
canBan: Boolean = true,
|
||||||
): KnockRequestsListPresenter {
|
knockRequestsFlow: Flow<List<KnockRequest>> = flowOf(emptyList())
|
||||||
val knockRequestsService = KnockRequestsService(
|
): KnockRequestsListPresenter {
|
||||||
knockRequestsFlow = knockRequestsFlow,
|
val knockRequestsService = KnockRequestsService(
|
||||||
coroutineScope = backgroundScope,
|
knockRequestsFlow = knockRequestsFlow,
|
||||||
isKnockFeatureEnabledFlow = flowOf(true),
|
coroutineScope = backgroundScope,
|
||||||
permissionsFlow = flowOf(KnockRequestPermissions(canAccept, canDecline, canBan)),
|
isKnockFeatureEnabledFlow = flowOf(true),
|
||||||
)
|
permissionsFlow = flowOf(KnockRequestPermissions(canAccept, canDecline, canBan)),
|
||||||
return KnockRequestsListPresenter(knockRequestsService = knockRequestsService)
|
)
|
||||||
}
|
return KnockRequestsListPresenter(knockRequestsService = knockRequestsService)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
interface LeaveRoomRenderer {
|
fun interface LeaveRoomRenderer {
|
||||||
@Composable
|
@Composable
|
||||||
fun Render(
|
fun Render(
|
||||||
state: LeaveRoomState,
|
state: LeaveRoomState,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.licenses.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultOpenSourcesLicensesEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultOpenSourcesLicensesEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
DependenciesFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.getNode(parentNode, BuildContext.root(null))
|
||||||
|
assertThat(result).isInstanceOf(DependenciesFlowNode::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ package io.element.android.features.location.impl.common.permissions
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
|
||||||
interface PermissionsPresenter : Presenter<PermissionsState> {
|
interface PermissionsPresenter : Presenter<PermissionsState> {
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(permissions: List<String>): PermissionsPresenter
|
fun create(permissions: List<String>): PermissionsPresenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class SendLocationPresenter(
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
) : Presenter<SendLocationState> {
|
) : Presenter<SendLocationState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(timelineMode: Timeline.Mode): SendLocationPresenter
|
fun create(timelineMode: Timeline.Mode): SendLocationPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ import io.element.android.services.analytics.api.AnalyticsService
|
||||||
@ContributesNode(RoomScope::class)
|
@ContributesNode(RoomScope::class)
|
||||||
@Inject
|
@Inject
|
||||||
class ShowLocationNode(
|
class ShowLocationNode(
|
||||||
presenterFactory: ShowLocationPresenter.Factory,
|
|
||||||
analyticsService: AnalyticsService,
|
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
|
presenterFactory: ShowLocationPresenter.Factory,
|
||||||
|
analyticsService: AnalyticsService,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
init {
|
init {
|
||||||
lifecycle.subscribe(
|
lifecycle.subscribe(
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,14 @@ import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
class ShowLocationPresenter(
|
class ShowLocationPresenter(
|
||||||
|
@Assisted private val location: Location,
|
||||||
|
@Assisted private val description: String?,
|
||||||
permissionsPresenterFactory: PermissionsPresenter.Factory,
|
permissionsPresenterFactory: PermissionsPresenter.Factory,
|
||||||
private val locationActions: LocationActions,
|
private val locationActions: LocationActions,
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
@Assisted private val location: Location,
|
|
||||||
@Assisted private val description: String?
|
|
||||||
) : Presenter<ShowLocationState> {
|
) : Presenter<ShowLocationState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(location: Location, description: String?): ShowLocationPresenter
|
fun create(location: Location, description: String?): ShowLocationPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.location.impl.send
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.location.impl.common.actions.FakeLocationActions
|
||||||
|
import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter
|
||||||
|
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultSendLocationEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultSendLocationEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
SendLocationNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { timelineMode: Timeline.Mode ->
|
||||||
|
SendLocationPresenter(
|
||||||
|
permissionsPresenterFactory = { FakePermissionsPresenter() },
|
||||||
|
room = FakeJoinedRoom(),
|
||||||
|
timelineMode = timelineMode,
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
messageComposerContext = FakeMessageComposerContext(),
|
||||||
|
locationActions = FakeLocationActions(),
|
||||||
|
buildMeta = aBuildMeta(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val timelineMode = Timeline.Mode.Live
|
||||||
|
val result = entryPoint.builder(timelineMode)
|
||||||
|
.build(parentNode, BuildContext.root(null))
|
||||||
|
assertThat(result).isInstanceOf(SendLocationNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(SendLocationNode.Inputs(timelineMode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.location.impl.show
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.location.api.Location
|
||||||
|
import io.element.android.features.location.api.ShowLocationEntryPoint
|
||||||
|
import io.element.android.features.location.impl.common.actions.FakeLocationActions
|
||||||
|
import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter
|
||||||
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultShowLocationEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultShowLocationEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
ShowLocationNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { location: Location, description: String? ->
|
||||||
|
ShowLocationPresenter(
|
||||||
|
permissionsPresenterFactory = { FakePermissionsPresenter() },
|
||||||
|
locationActions = FakeLocationActions(),
|
||||||
|
buildMeta = aBuildMeta(),
|
||||||
|
location = location,
|
||||||
|
description = description,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val inputs = ShowLocationEntryPoint.Inputs(
|
||||||
|
location = Location(37.4219983, -122.084, 10f),
|
||||||
|
description = "My location",
|
||||||
|
)
|
||||||
|
val result = entryPoint.createNode(
|
||||||
|
parentNode,
|
||||||
|
BuildContext.root(null),
|
||||||
|
inputs = inputs,
|
||||||
|
)
|
||||||
|
assertThat(result).isInstanceOf(ShowLocationNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(inputs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,10 +37,10 @@ class ShowLocationPresenterTest {
|
||||||
permissionsPresenterFactory = object : PermissionsPresenter.Factory {
|
permissionsPresenterFactory = object : PermissionsPresenter.Factory {
|
||||||
override fun create(permissions: List<String>): PermissionsPresenter = fakePermissionsPresenter
|
override fun create(permissions: List<String>): PermissionsPresenter = fakePermissionsPresenter
|
||||||
},
|
},
|
||||||
fakeLocationActions,
|
locationActions = fakeLocationActions,
|
||||||
fakeBuildMeta,
|
buildMeta = fakeBuildMeta,
|
||||||
location,
|
location = location,
|
||||||
A_DESCRIPTION,
|
description = A_DESCRIPTION,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ package io.element.android.features.location.test
|
||||||
import io.element.android.features.location.api.LocationService
|
import io.element.android.features.location.api.LocationService
|
||||||
|
|
||||||
class FakeLocationService(
|
class FakeLocationService(
|
||||||
private val isServiceAvailable: Boolean,
|
private val isServiceAvailable: Boolean = false,
|
||||||
) : LocationService {
|
) : LocationService {
|
||||||
override fun isServiceAvailable() = isServiceAvailable
|
override fun isServiceAvailable() = isServiceAvailable
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.lockscreen.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultLockScreenEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder Setup`() {
|
||||||
|
val entryPoint = DefaultLockScreenEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
LockScreenFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : LockScreenEntryPoint.Callback {
|
||||||
|
override fun onSetupDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val navTarget = LockScreenEntryPoint.Target.Setup
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null), navTarget)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(LockScreenFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Setup))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test node builder Settings`() {
|
||||||
|
val entryPoint = DefaultLockScreenEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
LockScreenFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : LockScreenEntryPoint.Callback {
|
||||||
|
override fun onSetupDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val navTarget = LockScreenEntryPoint.Target.Settings
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null), navTarget)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(LockScreenFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Settings))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||||
|
import io.element.android.features.login.api.LoginEntryPoint
|
||||||
|
import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
|
||||||
|
import io.element.android.libraries.oidc.test.customtab.FakeOidcActionFlow
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultLoginEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultLoginEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
LoginFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
accountProviderDataSource = AccountProviderDataSource(FakeEnterpriseService()),
|
||||||
|
oidcActionFlow = FakeOidcActionFlow(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : LoginEntryPoint.Callback {
|
||||||
|
override fun onReportProblem() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = LoginEntryPoint.Params(
|
||||||
|
accountProvider = "ac",
|
||||||
|
loginHint = "lh",
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(LoginFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(LoginFlowNode.Params(params.accountProvider, params.loginHint))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@ package io.element.android.features.logout.api.direct
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
interface DirectLogoutView {
|
fun interface DirectLogoutView {
|
||||||
@Composable
|
@Composable
|
||||||
fun Render(state: DirectLogoutState)
|
fun Render(state: DirectLogoutState)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.logout.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.logout.api.LogoutEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultLogoutEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultLogoutEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
LogoutNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createLogoutPresenter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : LogoutEntryPoint.Callback {
|
||||||
|
override fun onChangeRecoveryKeyClick() = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(LogoutNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -225,12 +225,12 @@ class LogoutPresenterTest {
|
||||||
skipItems(2)
|
skipItems(2)
|
||||||
return awaitItem()
|
return awaitItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLogoutPresenter(
|
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
|
||||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
|
||||||
): LogoutPresenter = LogoutPresenter(
|
|
||||||
matrixClient = matrixClient,
|
|
||||||
encryptionService = encryptionService,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createLogoutPresenter(
|
||||||
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
|
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||||
|
): LogoutPresenter = LogoutPresenter(
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
encryptionService = encryptionService,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.messages.impl
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.call.api.CallType
|
||||||
|
import io.element.android.features.call.api.ElementCallEntryPoint
|
||||||
|
import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint
|
||||||
|
import io.element.android.features.location.api.SendLocationEntryPoint
|
||||||
|
import io.element.android.features.location.api.ShowLocationEntryPoint
|
||||||
|
import io.element.android.features.location.test.FakeLocationService
|
||||||
|
import io.element.android.features.messages.api.MessagesEntryPoint
|
||||||
|
import io.element.android.features.messages.impl.pinned.banner.createPinnedEventsTimelineProvider
|
||||||
|
import io.element.android.features.messages.impl.timeline.createTimelineController
|
||||||
|
import io.element.android.features.poll.api.create.CreatePollEntryPoint
|
||||||
|
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
||||||
|
import io.element.android.libraries.matrix.ui.messages.RoomMemberProfilesCache
|
||||||
|
import io.element.android.libraries.matrix.ui.messages.RoomNamesCache
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
|
import io.element.android.libraries.textcomposer.mentions.MentionSpanTheme
|
||||||
|
import io.element.android.libraries.textcomposer.mentions.MentionSpanUpdater
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultMessagesEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultMessagesEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
MessagesFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
matrixClient = FakeMatrixClient(),
|
||||||
|
sendLocationEntryPoint = object : SendLocationEntryPoint {
|
||||||
|
override fun builder(timelineMode: Timeline.Mode) = lambdaError()
|
||||||
|
},
|
||||||
|
showLocationEntryPoint = object : ShowLocationEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: ShowLocationEntryPoint.Inputs) = lambdaError()
|
||||||
|
},
|
||||||
|
createPollEntryPoint = object : CreatePollEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
elementCallEntryPoint = object : ElementCallEntryPoint {
|
||||||
|
override fun startCall(callType: CallType) = lambdaError()
|
||||||
|
override suspend fun handleIncomingCall(
|
||||||
|
callType: CallType.RoomCall,
|
||||||
|
eventId: EventId,
|
||||||
|
senderId: UserId,
|
||||||
|
roomName: String?,
|
||||||
|
senderName: String?,
|
||||||
|
avatarUrl: String?,
|
||||||
|
timestamp: Long,
|
||||||
|
notificationChannelId: String,
|
||||||
|
textContent: String?,
|
||||||
|
) = lambdaError()
|
||||||
|
},
|
||||||
|
mediaViewerEntryPoint = object : MediaViewerEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
locationService = FakeLocationService(),
|
||||||
|
room = FakeBaseRoom(),
|
||||||
|
roomMemberProfilesCache = RoomMemberProfilesCache(),
|
||||||
|
roomNamesCache = RoomNamesCache(),
|
||||||
|
mentionSpanUpdater = object : MentionSpanUpdater {
|
||||||
|
override fun updateMentionSpans(text: CharSequence) = text
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun rememberMentionSpans(text: CharSequence) = text
|
||||||
|
},
|
||||||
|
mentionSpanTheme = MentionSpanTheme(A_USER_ID),
|
||||||
|
pinnedEventsTimelineProvider = createPinnedEventsTimelineProvider(),
|
||||||
|
timelineController = createTimelineController(),
|
||||||
|
knockRequestsListEntryPoint = object : KnockRequestsListEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
dateFormatter = FakeDateFormatter(),
|
||||||
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : MessagesEntryPoint.Callback {
|
||||||
|
override fun onRoomDetailsClick() = lambdaError()
|
||||||
|
override fun onUserDataClick(userId: UserId) = lambdaError()
|
||||||
|
override fun onPermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
|
||||||
|
override fun onForwardedToSingleRoom(roomId: RoomId) = lambdaError()
|
||||||
|
}
|
||||||
|
val initialTarget = MessagesEntryPoint.InitialTarget.Messages(focusedEventId = AN_EVENT_ID)
|
||||||
|
val params = MessagesEntryPoint.Params(initialTarget)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(MessagesFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(MessagesEntryPoint.Params(initialTarget))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -178,10 +178,9 @@ class PinnedMessagesBannerPresenterTest {
|
||||||
),
|
),
|
||||||
syncService: SyncService = FakeSyncService(),
|
syncService: SyncService = FakeSyncService(),
|
||||||
): PinnedMessagesBannerPresenter {
|
): PinnedMessagesBannerPresenter {
|
||||||
val timelineProvider = PinnedEventsTimelineProvider(
|
val timelineProvider = createPinnedEventsTimelineProvider(
|
||||||
room = room,
|
room = room,
|
||||||
syncService = syncService,
|
syncService = syncService,
|
||||||
dispatchers = testCoroutineDispatchers(),
|
|
||||||
)
|
)
|
||||||
timelineProvider.launchIn(backgroundScope)
|
timelineProvider.launchIn(backgroundScope)
|
||||||
|
|
||||||
|
|
@ -192,3 +191,12 @@ class PinnedMessagesBannerPresenterTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun TestScope.createPinnedEventsTimelineProvider(
|
||||||
|
room: JoinedRoom = FakeJoinedRoom(),
|
||||||
|
syncService: SyncService = FakeSyncService(),
|
||||||
|
) = PinnedEventsTimelineProvider(
|
||||||
|
room = room,
|
||||||
|
syncService = syncService,
|
||||||
|
dispatchers = testCoroutineDispatchers(),
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -217,3 +217,13 @@ class TimelineControllerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createTimelineController(
|
||||||
|
room: FakeJoinedRoom = FakeJoinedRoom(liveTimeline = FakeTimeline()),
|
||||||
|
liveTimeline: Timeline = FakeTimeline(name = "live"),
|
||||||
|
): TimelineController {
|
||||||
|
return TimelineController(
|
||||||
|
room = room,
|
||||||
|
liveTimeline = liveTimeline
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class CreatePollPresenter(
|
||||||
@Assisted private val timelineMode: Timeline.Mode,
|
@Assisted private val timelineMode: Timeline.Mode,
|
||||||
) : Presenter<CreatePollState> {
|
) : Presenter<CreatePollState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
timelineMode: Timeline.Mode,
|
timelineMode: Timeline.Mode,
|
||||||
backNavigator: () -> Unit,
|
backNavigator: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class PollRepository(
|
||||||
@Assisted private val timelineMode: Timeline.Mode,
|
@Assisted private val timelineMode: Timeline.Mode,
|
||||||
) {
|
) {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
timelineMode: Timeline.Mode,
|
timelineMode: Timeline.Mode,
|
||||||
): PollRepository
|
): PollRepository
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.poll.impl.create
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||||
|
import io.element.android.features.poll.api.create.CreatePollEntryPoint
|
||||||
|
import io.element.android.features.poll.api.create.CreatePollMode
|
||||||
|
import io.element.android.features.poll.impl.data.PollRepository
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultCreatePollEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultCreatePollEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
CreatePollNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { timelineMode: Timeline.Mode, backNavigator: () -> Unit, mode: CreatePollMode ->
|
||||||
|
CreatePollPresenter(
|
||||||
|
repositoryFactory = {
|
||||||
|
val room = FakeJoinedRoom()
|
||||||
|
PollRepository(room, LiveTimelineProvider(room), timelineMode)
|
||||||
|
},
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
messageComposerContext = FakeMessageComposerContext(),
|
||||||
|
navigateUp = backNavigator,
|
||||||
|
mode = mode,
|
||||||
|
timelineMode = timelineMode,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val params = CreatePollEntryPoint.Params(
|
||||||
|
timelineMode = Timeline.Mode.Live,
|
||||||
|
mode = CreatePollMode.NewPoll,
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(CreatePollNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(CreatePollNode.Inputs(timelineMode = params.timelineMode, mode = params.mode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.poll.impl.history
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.poll.api.create.CreatePollEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultPollHistoryEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultPollHistoryEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
PollHistoryFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
createPollEntryPoint = object : CreatePollEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.createNode(parentNode, BuildContext.root(null))
|
||||||
|
assertThat(result).isInstanceOf(PollHistoryFlowNode::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -151,23 +151,23 @@ class PollHistoryPresenterTest {
|
||||||
assert(paginateLambda).isCalledExactly(2)
|
assert(paginateLambda).isCalledExactly(2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun TestScope.createPollHistoryPresenter(
|
|
||||||
room: FakeJoinedRoom = FakeJoinedRoom(),
|
internal fun TestScope.createPollHistoryPresenter(
|
||||||
endPollAction: EndPollAction = FakeEndPollAction(),
|
room: FakeJoinedRoom = FakeJoinedRoom(),
|
||||||
sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(),
|
endPollAction: EndPollAction = FakeEndPollAction(),
|
||||||
pollHistoryItemFactory: PollHistoryItemsFactory = PollHistoryItemsFactory(
|
sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(),
|
||||||
pollContentStateFactory = DefaultPollContentStateFactory(FakeMatrixClient()),
|
pollHistoryItemFactory: PollHistoryItemsFactory = PollHistoryItemsFactory(
|
||||||
dateFormatter = FakeDateFormatter(),
|
pollContentStateFactory = DefaultPollContentStateFactory(FakeMatrixClient()),
|
||||||
dispatchers = testCoroutineDispatchers(),
|
dateFormatter = FakeDateFormatter(),
|
||||||
),
|
dispatchers = testCoroutineDispatchers(),
|
||||||
): PollHistoryPresenter {
|
),
|
||||||
return PollHistoryPresenter(
|
): PollHistoryPresenter {
|
||||||
sessionCoroutineScope = this,
|
return PollHistoryPresenter(
|
||||||
sendPollResponseAction = sendPollResponseAction,
|
sessionCoroutineScope = this,
|
||||||
endPollAction = endPollAction,
|
sendPollResponseAction = sendPollResponseAction,
|
||||||
pollHistoryItemFactory = pollHistoryItemFactory,
|
endPollAction = endPollAction,
|
||||||
room = room,
|
pollHistoryItemFactory = pollHistoryItemFactory,
|
||||||
)
|
room = room,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.preferences.impl
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.deactivation.api.AccountDeactivationEntryPoint
|
||||||
|
import io.element.android.features.licenses.api.OpenSourceLicensesEntryPoint
|
||||||
|
import io.element.android.features.lockscreen.api.LockScreenEntryPoint
|
||||||
|
import io.element.android.features.logout.api.LogoutEntryPoint
|
||||||
|
import io.element.android.features.preferences.api.PreferencesEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.troubleshoot.api.NotificationTroubleShootEntryPoint
|
||||||
|
import io.element.android.libraries.troubleshoot.api.PushHistoryEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultPreferencesEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultPreferencesEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
PreferencesFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
lockScreenEntryPoint = object : LockScreenEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext, navTarget: LockScreenEntryPoint.Target) = lambdaError()
|
||||||
|
override fun pinUnlockIntent(context: Context) = lambdaError()
|
||||||
|
},
|
||||||
|
notificationTroubleShootEntryPoint = object : NotificationTroubleShootEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
pushHistoryEntryPoint = object : PushHistoryEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
logoutEntryPoint = object : LogoutEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
openSourceLicensesEntryPoint = object : OpenSourceLicensesEntryPoint {
|
||||||
|
override fun getNode(node: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
accountDeactivationEntryPoint = object : AccountDeactivationEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : PreferencesEntryPoint.Callback {
|
||||||
|
override fun onOpenBugReport() = lambdaError()
|
||||||
|
override fun onSecureBackupClick() = lambdaError()
|
||||||
|
override fun onOpenRoomNotificationSettings(roomId: RoomId) = lambdaError()
|
||||||
|
override fun navigateTo(sessionId: SessionId, roomId: RoomId, eventId: EventId) = lambdaError()
|
||||||
|
}
|
||||||
|
val params = PreferencesEntryPoint.Params(
|
||||||
|
initialElement = PreferencesEntryPoint.InitialTarget.NotificationSettings,
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(PreferencesFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -225,15 +225,15 @@ class BugReportPresenterTest {
|
||||||
assertThat(awaitItem().sending).isEqualTo(AsyncAction.Uninitialized)
|
assertThat(awaitItem().sending).isEqualTo(AsyncAction.Uninitialized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createPresenter(
|
|
||||||
bugReporter: BugReporter = FakeBugReporter(),
|
|
||||||
crashDataStore: CrashDataStore = FakeCrashDataStore(),
|
|
||||||
screenshotHolder: ScreenshotHolder = FakeScreenshotHolder(),
|
|
||||||
) = BugReportPresenter(
|
|
||||||
bugReporter = bugReporter,
|
|
||||||
crashDataStore = crashDataStore,
|
|
||||||
screenshotHolder = screenshotHolder,
|
|
||||||
appCoroutineScope = this,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun TestScope.createPresenter(
|
||||||
|
bugReporter: BugReporter = FakeBugReporter(),
|
||||||
|
crashDataStore: CrashDataStore = FakeCrashDataStore(),
|
||||||
|
screenshotHolder: ScreenshotHolder = FakeScreenshotHolder(),
|
||||||
|
) = BugReportPresenter(
|
||||||
|
bugReporter = bugReporter,
|
||||||
|
crashDataStore = crashDataStore,
|
||||||
|
screenshotHolder = screenshotHolder,
|
||||||
|
appCoroutineScope = this,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.impl.bugreport
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultBugReportEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultBugReportEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
BugReportNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createPresenter(),
|
||||||
|
bugReporter = FakeBugReporter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : BugReportEntryPoint.Callback {
|
||||||
|
override fun onBugReportSent() = lambdaError()
|
||||||
|
override fun onViewLogs(basePath: String) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(BugReportNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,6 @@ import com.bumble.appyx.core.node.Node
|
||||||
import io.element.android.libraries.architecture.FeatureEntryPoint
|
import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
||||||
interface ReportRoomEntryPoint : FeatureEntryPoint {
|
fun interface ReportRoomEntryPoint : FeatureEntryPoint {
|
||||||
fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId): Node
|
fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId): Node
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class ReportRoomPresenter(
|
||||||
private val reportRoom: ReportRoom,
|
private val reportRoom: ReportRoom,
|
||||||
) : Presenter<ReportRoomState> {
|
) : Presenter<ReportRoomState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(roomId: RoomId): ReportRoomPresenter
|
fun create(roomId: RoomId): ReportRoomPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.reportroom.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultReportRoomEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultReportRoomEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
ReportRoomNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { roomId ->
|
||||||
|
assertThat(roomId).isEqualTo(A_ROOM_ID)
|
||||||
|
createReportRoomPresenter()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val result = entryPoint.createNode(parentNode, BuildContext.root(null), A_ROOM_ID)
|
||||||
|
assertThat(result).isInstanceOf(ReportRoomNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(ReportRoomNode.Inputs(A_ROOM_ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -141,11 +141,11 @@ class ReportRoomPresenterTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fun createReportRoomPresenter(
|
|
||||||
roomId: RoomId = A_ROOM_ID,
|
internal fun createReportRoomPresenter(
|
||||||
reportRoom: ReportRoom = FakeReportRoom()
|
roomId: RoomId = A_ROOM_ID,
|
||||||
): ReportRoomPresenter {
|
reportRoom: ReportRoom = FakeReportRoom()
|
||||||
return ReportRoomPresenter(roomId, reportRoom)
|
): ReportRoomPresenter {
|
||||||
}
|
return ReportRoomPresenter(roomId, reportRoom)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class RoomAliasResolverPresenter(
|
||||||
@Assisted private val roomAlias: RoomAlias,
|
@Assisted private val roomAlias: RoomAlias,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
) : Presenter<RoomAliasResolverState> {
|
) : Presenter<RoomAliasResolverState> {
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
roomAlias: RoomAlias,
|
roomAlias: RoomAlias,
|
||||||
): RoomAliasResolverPresenter
|
): RoomAliasResolverPresenter
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.roomaliasresolver.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.roomaliasesolver.api.RoomAliasResolverEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||||
|
import io.element.android.libraries.matrix.test.A_ROOM_ALIAS
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultRoomAliasResolverEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultRoomAliasResolverEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
RoomAliasResolverNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { alias ->
|
||||||
|
assertThat(alias).isEqualTo(A_ROOM_ALIAS)
|
||||||
|
createPresenter(
|
||||||
|
alias,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : RoomAliasResolverEntryPoint.Callback {
|
||||||
|
override fun onAliasResolved(data: ResolvedRoomAlias) = lambdaError()
|
||||||
|
}
|
||||||
|
val params = RoomAliasResolverEntryPoint.Params(
|
||||||
|
roomAlias = A_ROOM_ALIAS
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(RoomAliasResolverNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -79,16 +79,16 @@ class RoomAliasHelperPresenterTest {
|
||||||
assertThat(retryState.resolveState.errorOrNull()).isEqualTo(AN_EXCEPTION)
|
assertThat(retryState.resolveState.errorOrNull()).isEqualTo(AN_EXCEPTION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPresenter(
|
|
||||||
roomAlias: RoomAlias = A_ROOM_ALIAS,
|
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
|
||||||
) = RoomAliasResolverPresenter(
|
|
||||||
roomAlias = roomAlias,
|
|
||||||
matrixClient = matrixClient,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun createPresenter(
|
||||||
|
roomAlias: RoomAlias = A_ROOM_ALIAS,
|
||||||
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
|
) = RoomAliasResolverPresenter(
|
||||||
|
roomAlias = roomAlias,
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
)
|
||||||
|
|
||||||
internal fun aResolvedRoomAlias(
|
internal fun aResolvedRoomAlias(
|
||||||
roomId: RoomId = A_ROOM_ID,
|
roomId: RoomId = A_ROOM_ID,
|
||||||
servers: List<String> = A_SERVER_LIST,
|
servers: List<String> = A_SERVER_LIST,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.roomdetails.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.call.api.CallType
|
||||||
|
import io.element.android.features.call.api.ElementCallEntryPoint
|
||||||
|
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
|
||||||
|
import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint
|
||||||
|
import io.element.android.features.messages.api.MessagesEntryPoint
|
||||||
|
import io.element.android.features.poll.api.history.PollHistoryEntryPoint
|
||||||
|
import io.element.android.features.reportroom.api.ReportRoomEntryPoint
|
||||||
|
import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint
|
||||||
|
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultRoomDetailsEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultRoomDetailsEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
RoomDetailsFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
pollHistoryEntryPoint = object : PollHistoryEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
elementCallEntryPoint = object : ElementCallEntryPoint {
|
||||||
|
override fun startCall(callType: CallType) = lambdaError()
|
||||||
|
override suspend fun handleIncomingCall(
|
||||||
|
callType: CallType.RoomCall,
|
||||||
|
eventId: EventId,
|
||||||
|
senderId: UserId,
|
||||||
|
roomName: String?,
|
||||||
|
senderName: String?,
|
||||||
|
avatarUrl: String?,
|
||||||
|
timestamp: Long,
|
||||||
|
notificationChannelId: String,
|
||||||
|
textContent: String?
|
||||||
|
) = lambdaError()
|
||||||
|
},
|
||||||
|
room = FakeJoinedRoom(),
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
|
messagesEntryPoint = object : MessagesEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
knockRequestsListEntryPoint = object : KnockRequestsListEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
mediaViewerEntryPoint = object : MediaViewerEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
mediaGalleryEntryPoint = object : MediaGalleryEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
reportRoomEntryPoint = object : ReportRoomEntryPoint {
|
||||||
|
override fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId) = lambdaError()
|
||||||
|
},
|
||||||
|
changeRoomMemberRolesEntryPoint = object : ChangeRoomMemberRolesEntryPoint {
|
||||||
|
override fun builder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : RoomDetailsEntryPoint.Callback {
|
||||||
|
override fun onOpenGlobalNotificationSettings() = lambdaError()
|
||||||
|
override fun onOpenRoom(roomId: RoomId, serverNames: List<String>) = lambdaError()
|
||||||
|
override fun onPermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
|
||||||
|
override fun onForwardedToSingleRoom(roomId: RoomId) = lambdaError()
|
||||||
|
}
|
||||||
|
val params = RoomDetailsEntryPoint.Params(
|
||||||
|
initialElement = RoomDetailsEntryPoint.InitialTarget.RoomDetails,
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(RoomDetailsFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.roomdirectory.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.roomdirectory.api.RoomDescription
|
||||||
|
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
|
||||||
|
import io.element.android.features.roomdirectory.impl.root.RoomDirectoryNode
|
||||||
|
import io.element.android.features.roomdirectory.impl.root.createRoomDirectoryPresenter
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultRoomDirectoryEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultRoomDirectoryEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
RoomDirectoryNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createRoomDirectoryPresenter(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : RoomDirectoryEntryPoint.Callback {
|
||||||
|
override fun onResultClick(roomDescription: RoomDescription) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(RoomDirectoryNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -122,15 +122,15 @@ class RoomDirectoryPresenterTest {
|
||||||
.isCalledOnce()
|
.isCalledOnce()
|
||||||
.withNoParameter()
|
.withNoParameter()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun TestScope.createRoomDirectoryPresenter(
|
|
||||||
roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(
|
internal fun TestScope.createRoomDirectoryPresenter(
|
||||||
createRoomDirectoryListFactory = { FakeRoomDirectoryList() }
|
roomDirectoryService: RoomDirectoryService = FakeRoomDirectoryService(
|
||||||
),
|
createRoomDirectoryListFactory = { FakeRoomDirectoryList() }
|
||||||
): RoomDirectoryPresenter {
|
),
|
||||||
return RoomDirectoryPresenter(
|
): RoomDirectoryPresenter {
|
||||||
dispatchers = testCoroutineDispatchers(),
|
return RoomDirectoryPresenter(
|
||||||
roomDirectoryService = roomDirectoryService,
|
dispatchers = testCoroutineDispatchers(),
|
||||||
)
|
roomDirectoryService = roomDirectoryService,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.securebackup.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultSecureBackupEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultSecureBackupEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
SecureBackupFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : SecureBackupEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(SecureBackupFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ class SharePresenter(
|
||||||
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
|
private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider,
|
||||||
) : Presenter<ShareState> {
|
) : Presenter<ShareState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(intent: Intent): SharePresenter
|
fun create(intent: Intent): SharePresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.share.impl
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.share.api.ShareEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.roomselect.api.RoomSelectEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultShareEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultShareEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
ShareNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { createSharePresenter() },
|
||||||
|
roomSelectEntryPoint = object : RoomSelectEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomSelectEntryPoint.NodeBuilder {
|
||||||
|
lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : ShareEntryPoint.Callback {
|
||||||
|
override fun onDone(roomIds: List<RoomId>) = lambdaError()
|
||||||
|
}
|
||||||
|
val params = ShareEntryPoint.Params(
|
||||||
|
intent = Intent(),
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(ShareNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(ShareNode.Inputs(params.intent))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -158,23 +158,23 @@ class SharePresenterTest {
|
||||||
sendFileResult.assertions().isCalledOnce()
|
sendFileResult.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun TestScope.createSharePresenter(
|
|
||||||
intent: Intent = Intent(),
|
internal fun TestScope.createSharePresenter(
|
||||||
shareIntentHandler: ShareIntentHandler = FakeShareIntentHandler(),
|
intent: Intent = Intent(),
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
shareIntentHandler: ShareIntentHandler = FakeShareIntentHandler(),
|
||||||
mediaPreProcessor: MediaPreProcessor = FakeMediaPreProcessor(),
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
activeRoomsHolder: ActiveRoomsHolder = ActiveRoomsHolder(),
|
mediaPreProcessor: MediaPreProcessor = FakeMediaPreProcessor(),
|
||||||
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
|
activeRoomsHolder: ActiveRoomsHolder = ActiveRoomsHolder(),
|
||||||
): SharePresenter {
|
mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(),
|
||||||
return SharePresenter(
|
): SharePresenter {
|
||||||
intent = intent,
|
return SharePresenter(
|
||||||
sessionCoroutineScope = this,
|
intent = intent,
|
||||||
shareIntentHandler = shareIntentHandler,
|
sessionCoroutineScope = this,
|
||||||
matrixClient = matrixClient,
|
shareIntentHandler = shareIntentHandler,
|
||||||
mediaPreProcessor = mediaPreProcessor,
|
matrixClient = matrixClient,
|
||||||
activeRoomsHolder = activeRoomsHolder,
|
mediaPreProcessor = mediaPreProcessor,
|
||||||
mediaOptimizationConfigProvider = mediaOptimizationConfigProvider,
|
activeRoomsHolder = activeRoomsHolder,
|
||||||
)
|
mediaOptimizationConfigProvider = mediaOptimizationConfigProvider,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class SignedOutPresenter(
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
) : Presenter<SignedOutState> {
|
) : Presenter<SignedOutState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(sessionId: String): SignedOutPresenter
|
fun create(sessionId: String): SignedOutPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.signedout.api.SignedOutEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultSignedOutEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultSignedOutEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
SignedOutNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { sessionId ->
|
||||||
|
assertThat(sessionId).isEqualTo(A_SESSION_ID.value)
|
||||||
|
createSignedOutPresenter()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val params = SignedOutEntryPoint.Params(A_SESSION_ID)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(SignedOutNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(SignedOutNode.Inputs(params.sessionId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,12 +22,12 @@ import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
private val appName = "AppName"
|
||||||
|
|
||||||
class SignedOutPresenterTest {
|
class SignedOutPresenterTest {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
private val appName = "AppName"
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state`() = runTest {
|
fun `present - initial state`() = runTest {
|
||||||
val aSessionData = aSessionData()
|
val aSessionData = aSessionData()
|
||||||
|
|
@ -64,15 +64,15 @@ class SignedOutPresenterTest {
|
||||||
assertThat(sessionStore.getAllSessions()).isEmpty()
|
assertThat(sessionStore.getAllSessions()).isEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun createSignedOutPresenter(
|
|
||||||
sessionId: SessionId = A_SESSION_ID,
|
internal fun createSignedOutPresenter(
|
||||||
sessionStore: SessionStore = InMemorySessionStore(),
|
sessionId: SessionId = A_SESSION_ID,
|
||||||
): SignedOutPresenter {
|
sessionStore: SessionStore = InMemorySessionStore(),
|
||||||
return SignedOutPresenter(
|
): SignedOutPresenter {
|
||||||
sessionId = sessionId.value,
|
return SignedOutPresenter(
|
||||||
sessionStore = sessionStore,
|
sessionId = sessionId.value,
|
||||||
buildMeta = aBuildMeta(applicationName = appName),
|
sessionStore = sessionStore,
|
||||||
)
|
buildMeta = aBuildMeta(applicationName = appName),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import org.junit.runner.RunWith
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class DefaultSpaceEntryPointTest {
|
class DefaultSpaceEntryPointTest {
|
||||||
@Test
|
@Test
|
||||||
fun `test DefaultSpaceEntryPoint`() {
|
fun `test node builder`() {
|
||||||
val entryPoint = DefaultSpaceEntryPoint()
|
val entryPoint = DefaultSpaceEntryPoint()
|
||||||
val nodeInputs = SpaceEntryPoint.Inputs(A_ROOM_ID)
|
val nodeInputs = SpaceEntryPoint.Inputs(A_ROOM_ID)
|
||||||
val parentNode = TestParentNode.create { buildContext, plugins ->
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.startchat.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.createroom.api.CreateRoomEntryPoint
|
||||||
|
import io.element.android.features.startchat.api.StartChatEntryPoint
|
||||||
|
import io.element.android.features.startchat.impl.root.StartChatNode
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultStartChatEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultStartChatEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
StartChatFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
createRoomEntryPoint = object : CreateRoomEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : StartChatEntryPoint.Callback {
|
||||||
|
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) = lambdaError()
|
||||||
|
override fun onOpenRoomDirectory() = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(StartChatFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -177,23 +177,23 @@ class StartChatPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun createStartChatPresenter(
|
|
||||||
startDMAction: StartDMAction = FakeStartDMAction(),
|
internal fun createStartChatPresenter(
|
||||||
isRoomDirectorySearchEnabled: Boolean = false,
|
startDMAction: StartDMAction = FakeStartDMAction(),
|
||||||
): StartChatPresenter {
|
isRoomDirectorySearchEnabled: Boolean = false,
|
||||||
val featureFlagService = FakeFeatureFlagService(
|
): StartChatPresenter {
|
||||||
initialState = mapOf(
|
val featureFlagService = FakeFeatureFlagService(
|
||||||
FeatureFlags.RoomDirectorySearch.key to isRoomDirectorySearchEnabled,
|
initialState = mapOf(
|
||||||
),
|
FeatureFlags.RoomDirectorySearch.key to isRoomDirectorySearchEnabled,
|
||||||
)
|
),
|
||||||
return StartChatPresenter(
|
)
|
||||||
presenterFactory = FakeUserListPresenterFactory(FakeUserListPresenter()),
|
return StartChatPresenter(
|
||||||
userRepository = FakeUserRepository(),
|
presenterFactory = FakeUserListPresenterFactory(FakeUserListPresenter()),
|
||||||
userListDataStore = UserListDataStore(),
|
userRepository = FakeUserRepository(),
|
||||||
startDMAction = startDMAction,
|
userListDataStore = UserListDataStore(),
|
||||||
featureFlagService = featureFlagService,
|
startDMAction = startDMAction,
|
||||||
buildMeta = aBuildMeta(),
|
featureFlagService = featureFlagService,
|
||||||
)
|
buildMeta = aBuildMeta(),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.userprofile.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.call.api.CallType
|
||||||
|
import io.element.android.features.call.api.ElementCallEntryPoint
|
||||||
|
import io.element.android.features.userprofile.api.UserProfileEntryPoint
|
||||||
|
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder
|
||||||
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultUserProfileEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultUserProfileEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
UserProfileFlowNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
sessionIdHolder = CurrentSessionIdHolder(FakeMatrixClient()),
|
||||||
|
elementCallEntryPoint = object : ElementCallEntryPoint {
|
||||||
|
override fun startCall(callType: CallType) = lambdaError()
|
||||||
|
override suspend fun handleIncomingCall(
|
||||||
|
callType: CallType.RoomCall,
|
||||||
|
eventId: EventId,
|
||||||
|
senderId: UserId,
|
||||||
|
roomName: String?,
|
||||||
|
senderName: String?,
|
||||||
|
avatarUrl: String?,
|
||||||
|
timestamp: Long,
|
||||||
|
notificationChannelId: String,
|
||||||
|
textContent: String?
|
||||||
|
) = lambdaError()
|
||||||
|
},
|
||||||
|
mediaViewerEntryPoint = object : MediaViewerEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : UserProfileEntryPoint.Callback {
|
||||||
|
override fun onOpenRoom(roomId: RoomId) {
|
||||||
|
lambdaError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val params = UserProfileEntryPoint.Params(
|
||||||
|
userId = A_USER_ID,
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(UserProfileFlowNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ class IncomingVerificationPresenter(
|
||||||
private val dateFormatter: DateFormatter,
|
private val dateFormatter: DateFormatter,
|
||||||
) : Presenter<IncomingVerificationState> {
|
) : Presenter<IncomingVerificationState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
verificationRequest: VerificationRequest.Incoming,
|
verificationRequest: VerificationRequest.Incoming,
|
||||||
navigator: IncomingVerificationNavigator,
|
navigator: IncomingVerificationNavigator,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class OutgoingVerificationPresenter(
|
||||||
private val encryptionService: EncryptionService,
|
private val encryptionService: EncryptionService,
|
||||||
) : Presenter<OutgoingVerificationState> {
|
) : Presenter<OutgoingVerificationState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
verificationRequest: VerificationRequest.Outgoing,
|
verificationRequest: VerificationRequest.Outgoing,
|
||||||
showDeviceVerifiedScreen: Boolean,
|
showDeviceVerifiedScreen: Boolean,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.verifysession.impl.incoming
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultIncomingVerificationEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultIncomingVerificationEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
IncomingVerificationNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { _, _ -> createPresenter() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : IncomingVerificationEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = IncomingVerificationEntryPoint.Params(
|
||||||
|
verificationRequest = anIncomingSessionVerificationRequest()
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(IncomingVerificationNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -289,31 +289,31 @@ class IncomingVerificationPresenterTest {
|
||||||
navigatorLambda.assertions().isCalledOnce()
|
navigatorLambda.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val anIncomingSessionVerificationRequest = VerificationRequest.Incoming.OtherSession(
|
|
||||||
details = SessionVerificationRequestDetails(
|
|
||||||
senderProfile = SessionVerificationRequestDetails.SenderProfile(
|
|
||||||
userId = A_USER_ID,
|
|
||||||
displayName = "a device name",
|
|
||||||
avatarUrl = null,
|
|
||||||
),
|
|
||||||
flowId = FlowId("flowId"),
|
|
||||||
deviceId = A_DEVICE_ID,
|
|
||||||
firstSeenTimestamp = A_TIMESTAMP,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun TestScope.createPresenter(
|
|
||||||
verificationRequest: VerificationRequest.Incoming = anIncomingSessionVerificationRequest,
|
|
||||||
navigator: IncomingVerificationNavigator = IncomingVerificationNavigator { lambdaError() },
|
|
||||||
service: SessionVerificationService = FakeSessionVerificationService(),
|
|
||||||
dateFormatter: DateFormatter = FakeDateFormatter(),
|
|
||||||
) = IncomingVerificationPresenter(
|
|
||||||
verificationRequest = verificationRequest,
|
|
||||||
navigator = navigator,
|
|
||||||
sessionVerificationService = service,
|
|
||||||
stateMachine = IncomingVerificationStateMachine(service),
|
|
||||||
dateFormatter = dateFormatter,
|
|
||||||
sessionCoroutineScope = backgroundScope,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val anIncomingSessionVerificationRequest = VerificationRequest.Incoming.OtherSession(
|
||||||
|
details = SessionVerificationRequestDetails(
|
||||||
|
senderProfile = SessionVerificationRequestDetails.SenderProfile(
|
||||||
|
userId = A_USER_ID,
|
||||||
|
displayName = "a device name",
|
||||||
|
avatarUrl = null,
|
||||||
|
),
|
||||||
|
flowId = FlowId("flowId"),
|
||||||
|
deviceId = A_DEVICE_ID,
|
||||||
|
firstSeenTimestamp = A_TIMESTAMP,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun TestScope.createPresenter(
|
||||||
|
verificationRequest: VerificationRequest.Incoming = anIncomingSessionVerificationRequest,
|
||||||
|
navigator: IncomingVerificationNavigator = IncomingVerificationNavigator { lambdaError() },
|
||||||
|
service: SessionVerificationService = FakeSessionVerificationService(),
|
||||||
|
dateFormatter: DateFormatter = FakeDateFormatter(),
|
||||||
|
) = IncomingVerificationPresenter(
|
||||||
|
verificationRequest = verificationRequest,
|
||||||
|
navigator = navigator,
|
||||||
|
sessionVerificationService = service,
|
||||||
|
stateMachine = IncomingVerificationStateMachine(service),
|
||||||
|
dateFormatter = dateFormatter,
|
||||||
|
sessionCoroutineScope = backgroundScope,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.verifysession.impl.outgoing
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultOutgoingVerificationEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultOutgoingVerificationEntryPoint()
|
||||||
|
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
OutgoingVerificationNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { _, _ ->
|
||||||
|
createOutgoingVerificationPresenter()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : OutgoingVerificationEntryPoint.Callback {
|
||||||
|
override fun onLearnMoreAboutEncryption() = lambdaError()
|
||||||
|
override fun onBack() = lambdaError()
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = OutgoingVerificationEntryPoint.Params(
|
||||||
|
showDeviceVerifiedScreen = true,
|
||||||
|
verificationRequest = anOutgoingSessionVerificationRequest(),
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(OutgoingVerificationNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -321,18 +321,18 @@ class OutgoingVerificationPresenterTest {
|
||||||
emitVerifiedStatus(SessionVerifiedStatus.NotVerified)
|
emitVerifiedStatus(SessionVerifiedStatus.NotVerified)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun createOutgoingVerificationPresenter(
|
|
||||||
service: SessionVerificationService,
|
internal fun createOutgoingVerificationPresenter(
|
||||||
verificationRequest: VerificationRequest.Outgoing = anOutgoingSessionVerificationRequest(),
|
service: SessionVerificationService = FakeSessionVerificationService(),
|
||||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
verificationRequest: VerificationRequest.Outgoing = anOutgoingSessionVerificationRequest(),
|
||||||
showDeviceVerifiedScreen: Boolean = false,
|
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||||
): OutgoingVerificationPresenter {
|
showDeviceVerifiedScreen: Boolean = false,
|
||||||
return OutgoingVerificationPresenter(
|
): OutgoingVerificationPresenter {
|
||||||
showDeviceVerifiedScreen = showDeviceVerifiedScreen,
|
return OutgoingVerificationPresenter(
|
||||||
verificationRequest = verificationRequest,
|
showDeviceVerifiedScreen = showDeviceVerifiedScreen,
|
||||||
sessionVerificationService = service,
|
verificationRequest = verificationRequest,
|
||||||
encryptionService = encryptionService,
|
sessionVerificationService = service,
|
||||||
)
|
encryptionService = encryptionService,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.viewfolder.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.viewfolder.api.ViewFolderEntryPoint
|
||||||
|
import io.element.android.features.viewfolder.impl.root.ViewFolderRootNode
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultViewFolderEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultViewFolderEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
ViewFolderRootNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : ViewFolderEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = ViewFolderEntryPoint.Params(
|
||||||
|
rootPath = "path",
|
||||||
|
)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(ViewFolderRootNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(ViewFolderRootNode.Inputs(params.rootPath))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,6 @@ interface FeatureEntryPoint
|
||||||
/**
|
/**
|
||||||
* Can be used when the feature only exposes a simple node without the need of plugins.
|
* Can be used when the feature only exposes a simple node without the need of plugins.
|
||||||
*/
|
*/
|
||||||
interface SimpleFeatureEntryPoint : FeatureEntryPoint {
|
fun interface SimpleFeatureEntryPoint : FeatureEntryPoint {
|
||||||
fun createNode(parentNode: Node, buildContext: BuildContext): Node
|
fun createNode(parentNode: Node, buildContext: BuildContext): Node
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ package io.element.android.libraries.deeplink.api.usecase
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
|
||||||
interface InviteFriendsUseCase {
|
fun interface InviteFriendsUseCase {
|
||||||
fun execute(activity: Activity)
|
fun execute(activity: Activity)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ dependencies {
|
||||||
implementation(projects.libraries.matrix.api)
|
implementation(projects.libraries.matrix.api)
|
||||||
|
|
||||||
testCommonDependencies(libs, true)
|
testCommonDependencies(libs, true)
|
||||||
|
testImplementation(projects.libraries.audio.test)
|
||||||
testImplementation(projects.libraries.dateformatter.test)
|
testImplementation(projects.libraries.dateformatter.test)
|
||||||
testImplementation(projects.libraries.featureflag.test)
|
testImplementation(projects.libraries.featureflag.test)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||||
|
|
||||||
interface FocusedTimelineMediaGalleryDataSourceFactory {
|
fun interface FocusedTimelineMediaGalleryDataSourceFactory {
|
||||||
fun createFor(
|
fun createFor(
|
||||||
eventId: EventId,
|
eventId: EventId,
|
||||||
mediaItem: MediaItem.Event,
|
mediaItem: MediaItem.Event,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class MediaViewerPresenter(
|
||||||
private val localMediaActions: LocalMediaActions,
|
private val localMediaActions: LocalMediaActions,
|
||||||
) : Presenter<MediaViewerState> {
|
) : Presenter<MediaViewerState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(
|
fun create(
|
||||||
inputs: MediaViewerEntryPoint.Params,
|
inputs: MediaViewerEntryPoint.Params,
|
||||||
navigator: MediaViewerNavigator,
|
navigator: MediaViewerNavigator,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.mediaviewer.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.bumble.appyx.core.node.Node
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.gallery.root.MediaGalleryRootNode
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultMediaGalleryEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultMediaGalleryEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
MediaGalleryRootNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
mediaViewerEntryPoint = object : MediaViewerEntryPoint {
|
||||||
|
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : MediaGalleryEntryPoint.Callback {
|
||||||
|
override fun onBackClick() = lambdaError()
|
||||||
|
override fun onViewInTimeline(eventId: EventId) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(MediaGalleryRootNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.mediaviewer.impl
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader
|
||||||
|
import io.element.android.libraries.mediaplayer.test.FakeAudioFocus
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaInfo
|
||||||
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.datasource.createTimelineMediaGalleryDataSource
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.viewer.MediaViewerNode
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.viewer.PagerKeysHandler
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.viewer.createMediaViewerEntryPointParams
|
||||||
|
import io.element.android.libraries.mediaviewer.impl.viewer.createMediaViewerPresenter
|
||||||
|
import io.element.android.libraries.mediaviewer.test.FakeLocalMediaFactory
|
||||||
|
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultMediaViewerEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultMediaViewerEntryPoint()
|
||||||
|
val mockMediaUri: Uri = mockk("localMediaUri")
|
||||||
|
val localMediaFactory = FakeLocalMediaFactory(mockMediaUri)
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
MediaViewerNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { _, _, _ ->
|
||||||
|
createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
timelineMediaGalleryDataSource = createTimelineMediaGalleryDataSource(),
|
||||||
|
focusedTimelineMediaGalleryDataSourceFactory = { _, _, _ ->
|
||||||
|
lambdaError()
|
||||||
|
},
|
||||||
|
mediaLoader = FakeMatrixMediaLoader(),
|
||||||
|
localMediaFactory = FakeLocalMediaFactory(mockMediaUri),
|
||||||
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
|
pagerKeysHandler = PagerKeysHandler(),
|
||||||
|
textFileViewer = { _, _ -> lambdaError() },
|
||||||
|
audioFocus = FakeAudioFocus(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : MediaViewerEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
override fun onViewInTimeline(eventId: EventId) = lambdaError()
|
||||||
|
}
|
||||||
|
val params = createMediaViewerEntryPointParams()
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(MediaViewerNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(params)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test node builder avatar`() = runTest {
|
||||||
|
val entryPoint = DefaultMediaViewerEntryPoint()
|
||||||
|
val mockMediaUri: Uri = mockk("localMediaUri")
|
||||||
|
val localMediaFactory = FakeLocalMediaFactory(mockMediaUri)
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
MediaViewerNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { _, _, _ ->
|
||||||
|
createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
timelineMediaGalleryDataSource = createTimelineMediaGalleryDataSource(),
|
||||||
|
focusedTimelineMediaGalleryDataSourceFactory = { _, _, _ ->
|
||||||
|
lambdaError()
|
||||||
|
},
|
||||||
|
mediaLoader = FakeMatrixMediaLoader(),
|
||||||
|
localMediaFactory = FakeLocalMediaFactory(mockMediaUri),
|
||||||
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
|
pagerKeysHandler = PagerKeysHandler(),
|
||||||
|
textFileViewer = { _, _ -> lambdaError() },
|
||||||
|
audioFocus = FakeAudioFocus(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : MediaViewerEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
override fun onViewInTimeline(eventId: EventId) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.avatar(
|
||||||
|
filename = "fn",
|
||||||
|
avatarUrl = "avatarUrl",
|
||||||
|
)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(MediaViewerNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(
|
||||||
|
MediaViewerEntryPoint.Params(
|
||||||
|
mode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
||||||
|
eventId = null,
|
||||||
|
mediaInfo = MediaInfo(
|
||||||
|
filename = "fn",
|
||||||
|
fileSize = null,
|
||||||
|
caption = null,
|
||||||
|
mimeType = MimeTypes.Images,
|
||||||
|
formattedFileSize = "",
|
||||||
|
fileExtension = "",
|
||||||
|
senderId = UserId("@dummy:server.org"),
|
||||||
|
senderName = null,
|
||||||
|
senderAvatar = null,
|
||||||
|
dateSent = null,
|
||||||
|
dateSentFull = null,
|
||||||
|
waveform = null,
|
||||||
|
duration = null,
|
||||||
|
),
|
||||||
|
mediaSource = MediaSource(url = "avatarUrl"),
|
||||||
|
thumbnailSource = null,
|
||||||
|
canShowInfo = false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -255,19 +255,19 @@ class TimelineMediaGalleryDataSourceTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun TestScope.createTimelineMediaGalleryDataSource(
|
internal fun TestScope.createTimelineMediaGalleryDataSource(
|
||||||
room: JoinedRoom = FakeJoinedRoom(
|
room: JoinedRoom = FakeJoinedRoom(
|
||||||
liveTimeline = FakeTimeline(),
|
liveTimeline = FakeTimeline(),
|
||||||
),
|
),
|
||||||
): TimelineMediaGalleryDataSource {
|
): TimelineMediaGalleryDataSource {
|
||||||
return TimelineMediaGalleryDataSource(
|
return TimelineMediaGalleryDataSource(
|
||||||
room = room,
|
room = room,
|
||||||
mediaTimeline = LiveMediaTimeline(room),
|
mediaTimeline = LiveMediaTimeline(room),
|
||||||
timelineMediaItemsFactory = createTimelineMediaItemsFactory(),
|
timelineMediaItemsFactory = createTimelineMediaItemsFactory(),
|
||||||
mediaItemsPostProcessor = MediaItemsPostProcessor(),
|
mediaItemsPostProcessor = MediaItemsPostProcessor(),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TestScope.createTimelineMediaItemsFactory() = TimelineMediaItemsFactory(
|
fun TestScope.createTimelineMediaItemsFactory() = TimelineMediaItemsFactory(
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
|
||||||
import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
|
import io.element.android.libraries.mediaviewer.api.anApkMediaInfo
|
||||||
|
import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory
|
||||||
import io.element.android.libraries.mediaviewer.impl.R
|
import io.element.android.libraries.mediaviewer.impl.R
|
||||||
import io.element.android.libraries.mediaviewer.impl.datasource.FakeMediaGalleryDataSource
|
import io.element.android.libraries.mediaviewer.impl.datasource.FakeMediaGalleryDataSource
|
||||||
import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource
|
import io.element.android.libraries.mediaviewer.impl.datasource.MediaGalleryDataSource
|
||||||
|
|
@ -78,12 +79,13 @@ class MediaViewerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state null Event`() = runTest {
|
fun `present - initial state null Event`() = runTest {
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
baseRoom = FakeBaseRoom(
|
baseRoom = FakeBaseRoom(
|
||||||
canRedactOwnResult = { Result.success(true) },
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.listData).isEmpty()
|
assertThat(initialState.listData).isEmpty()
|
||||||
|
|
@ -97,13 +99,14 @@ class MediaViewerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state cannot show info`() = runTest {
|
fun `present - initial state cannot show info`() = runTest {
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
canShowInfo = false,
|
canShowInfo = false,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
baseRoom = FakeBaseRoom(
|
baseRoom = FakeBaseRoom(
|
||||||
canRedactOwnResult = { Result.success(true) },
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.listData).isEmpty()
|
assertThat(initialState.listData).isEmpty()
|
||||||
|
|
@ -117,13 +120,14 @@ class MediaViewerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state Event`() = runTest {
|
fun `present - initial state Event`() = runTest {
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
baseRoom = FakeBaseRoom(
|
baseRoom = FakeBaseRoom(
|
||||||
canRedactOwnResult = { Result.success(true) },
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.listData).isEmpty()
|
assertThat(initialState.listData).isEmpty()
|
||||||
|
|
@ -137,14 +141,15 @@ class MediaViewerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state Event from other`() = runTest {
|
fun `present - initial state Event from other`() = runTest {
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
baseRoom = FakeBaseRoom(
|
baseRoom = FakeBaseRoom(
|
||||||
sessionId = A_SESSION_ID_2,
|
sessionId = A_SESSION_ID_2,
|
||||||
canRedactOtherResult = { Result.success(false) },
|
canRedactOtherResult = { Result.success(false) },
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(initialState.listData).isEmpty()
|
assertThat(initialState.listData).isEmpty()
|
||||||
|
|
@ -161,6 +166,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage()
|
val anImage = aMediaItemImage()
|
||||||
|
|
@ -192,6 +198,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -224,10 +231,13 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
room = FakeJoinedRoom(baseRoom = FakeBaseRoom(
|
room = FakeJoinedRoom(
|
||||||
canRedactOwnResult = { Result.success(true) },
|
baseRoom = FakeBaseRoom(
|
||||||
))
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
mediaSourceUrl = aUrl,
|
mediaSourceUrl = aUrl,
|
||||||
|
|
@ -266,6 +276,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -298,6 +309,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -330,6 +342,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -362,6 +375,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -394,6 +408,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -441,6 +456,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
liveTimeline = timeline,
|
liveTimeline = timeline,
|
||||||
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
|
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
|
||||||
|
|
@ -498,6 +514,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -549,6 +566,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mode = mode,
|
mode = mode,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
|
|
@ -620,6 +638,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mode = mode,
|
mode = mode,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
|
|
@ -674,6 +693,7 @@ class MediaViewerPresenterTest {
|
||||||
startLambda = { },
|
startLambda = { },
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
|
|
@ -714,6 +734,7 @@ class MediaViewerPresenterTest {
|
||||||
loadMoreLambda = loadMoreLambda,
|
loadMoreLambda = loadMoreLambda,
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaGalleryDataSource = mediaGalleryDataSource,
|
mediaGalleryDataSource = mediaGalleryDataSource,
|
||||||
)
|
)
|
||||||
val anImage = aMediaItemImage(
|
val anImage = aMediaItemImage(
|
||||||
|
|
@ -744,6 +765,7 @@ class MediaViewerPresenterTest {
|
||||||
onViewInTimelineClickLambda = onViewInTimelineClickLambda,
|
onViewInTimelineClickLambda = onViewInTimelineClickLambda,
|
||||||
)
|
)
|
||||||
val presenter = createMediaViewerPresenter(
|
val presenter = createMediaViewerPresenter(
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
mediaViewerNavigator = navigator,
|
mediaViewerNavigator = navigator,
|
||||||
room = FakeJoinedRoom(
|
room = FakeJoinedRoom(
|
||||||
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
|
baseRoom = FakeBaseRoom(canRedactOwnResult = { Result.success(true) }),
|
||||||
|
|
@ -764,42 +786,53 @@ class MediaViewerPresenterTest {
|
||||||
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
||||||
return awaitItem()
|
return awaitItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createMediaViewerPresenter(
|
|
||||||
eventId: EventId? = null,
|
|
||||||
mode: MediaViewerEntryPoint.MediaViewerMode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
|
||||||
matrixMediaLoader: FakeMatrixMediaLoader = FakeMatrixMediaLoader(),
|
|
||||||
localMediaActions: FakeLocalMediaActions = FakeLocalMediaActions(),
|
|
||||||
mediaGalleryDataSource: MediaGalleryDataSource = FakeMediaGalleryDataSource(
|
|
||||||
startLambda = { },
|
|
||||||
),
|
|
||||||
canShowInfo: Boolean = true,
|
|
||||||
mediaViewerNavigator: MediaViewerNavigator = FakeMediaViewerNavigator(),
|
|
||||||
room: JoinedRoom = FakeJoinedRoom(
|
|
||||||
liveTimeline = FakeTimeline(),
|
|
||||||
),
|
|
||||||
): MediaViewerPresenter {
|
|
||||||
return MediaViewerPresenter(
|
|
||||||
inputs = MediaViewerEntryPoint.Params(
|
|
||||||
mode = mode,
|
|
||||||
eventId = eventId,
|
|
||||||
mediaInfo = TESTED_MEDIA_INFO,
|
|
||||||
mediaSource = aMediaSource(),
|
|
||||||
thumbnailSource = null,
|
|
||||||
canShowInfo = canShowInfo,
|
|
||||||
),
|
|
||||||
navigator = mediaViewerNavigator,
|
|
||||||
dataSource = MediaViewerDataSource(
|
|
||||||
mode = mode,
|
|
||||||
dispatcher = testCoroutineDispatchers().computation,
|
|
||||||
galleryDataSource = mediaGalleryDataSource,
|
|
||||||
mediaLoader = matrixMediaLoader,
|
|
||||||
localMediaFactory = localMediaFactory,
|
|
||||||
systemClock = FakeSystemClock(),
|
|
||||||
pagerKeysHandler = PagerKeysHandler(),
|
|
||||||
),
|
|
||||||
room = room,
|
|
||||||
localMediaActions = localMediaActions,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun TestScope.createMediaViewerPresenter(
|
||||||
|
localMediaFactory: LocalMediaFactory,
|
||||||
|
eventId: EventId? = null,
|
||||||
|
mode: MediaViewerEntryPoint.MediaViewerMode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
||||||
|
matrixMediaLoader: FakeMatrixMediaLoader = FakeMatrixMediaLoader(),
|
||||||
|
localMediaActions: FakeLocalMediaActions = FakeLocalMediaActions(),
|
||||||
|
mediaGalleryDataSource: MediaGalleryDataSource = FakeMediaGalleryDataSource(
|
||||||
|
startLambda = { },
|
||||||
|
),
|
||||||
|
canShowInfo: Boolean = true,
|
||||||
|
mediaViewerNavigator: MediaViewerNavigator = FakeMediaViewerNavigator(),
|
||||||
|
room: JoinedRoom = FakeJoinedRoom(
|
||||||
|
liveTimeline = FakeTimeline(),
|
||||||
|
),
|
||||||
|
): MediaViewerPresenter {
|
||||||
|
return MediaViewerPresenter(
|
||||||
|
inputs = createMediaViewerEntryPointParams(
|
||||||
|
eventId = eventId,
|
||||||
|
mode = mode,
|
||||||
|
canShowInfo = canShowInfo,
|
||||||
|
),
|
||||||
|
navigator = mediaViewerNavigator,
|
||||||
|
dataSource = MediaViewerDataSource(
|
||||||
|
mode = mode,
|
||||||
|
dispatcher = testCoroutineDispatchers().computation,
|
||||||
|
galleryDataSource = mediaGalleryDataSource,
|
||||||
|
mediaLoader = matrixMediaLoader,
|
||||||
|
localMediaFactory = localMediaFactory,
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
|
pagerKeysHandler = PagerKeysHandler(),
|
||||||
|
),
|
||||||
|
room = room,
|
||||||
|
localMediaActions = localMediaActions,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun createMediaViewerEntryPointParams(
|
||||||
|
eventId: EventId? = null,
|
||||||
|
mode: MediaViewerEntryPoint.MediaViewerMode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
||||||
|
canShowInfo: Boolean = true,
|
||||||
|
) = MediaViewerEntryPoint.Params(
|
||||||
|
mode = mode,
|
||||||
|
eventId = eventId,
|
||||||
|
mediaInfo = TESTED_MEDIA_INFO,
|
||||||
|
mediaSource = aMediaSource(),
|
||||||
|
thumbnailSource = null,
|
||||||
|
canShowInfo = canShowInfo,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ class SingleMediaGalleryDataSourceTest {
|
||||||
assertThat(resultData.fileItems).isEmpty()
|
assertThat(resultData.fileItems).isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun aMediaViewerEntryPointParams(
|
internal fun aMediaViewerEntryPointParams(
|
||||||
mediaInfo: MediaInfo,
|
mediaInfo: MediaInfo,
|
||||||
) = MediaViewerEntryPoint.Params(
|
) = MediaViewerEntryPoint.Params(
|
||||||
mode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
mode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class RoomSelectPresenter(
|
||||||
private val dataSource: RoomSelectSearchDataSource,
|
private val dataSource: RoomSelectSearchDataSource,
|
||||||
) : Presenter<RoomSelectState> {
|
) : Presenter<RoomSelectState> {
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
interface Factory {
|
fun interface Factory {
|
||||||
fun create(mode: RoomSelectMode): RoomSelectPresenter
|
fun create(mode: RoomSelectMode): RoomSelectPresenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.roomselect.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.roomselect.api.RoomSelectEntryPoint
|
||||||
|
import io.element.android.libraries.roomselect.api.RoomSelectMode
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultRoomSelectEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() = runTest {
|
||||||
|
val entryPoint = DefaultRoomSelectEntryPoint()
|
||||||
|
val testMode = RoomSelectMode.Share
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
RoomSelectNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenterFactory = { mode ->
|
||||||
|
assertThat(mode).isEqualTo(testMode)
|
||||||
|
createRoomSelectPresenter(mode)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : RoomSelectEntryPoint.Callback {
|
||||||
|
override fun onRoomSelected(roomIds: List<RoomId>) = lambdaError()
|
||||||
|
override fun onCancel() = lambdaError()
|
||||||
|
}
|
||||||
|
val params = RoomSelectEntryPoint.Params(testMode)
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.params(params)
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(RoomSelectNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(RoomSelectNode.Inputs(params.mode))
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -111,15 +111,15 @@ class RoomSelectPresenterTest {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createRoomSelectPresenter(
|
|
||||||
mode: RoomSelectMode = RoomSelectMode.Forward,
|
|
||||||
roomListService: RoomListService = FakeRoomListService(),
|
|
||||||
) = RoomSelectPresenter(
|
|
||||||
mode = mode,
|
|
||||||
dataSource = RoomSelectSearchDataSource(
|
|
||||||
roomListService = roomListService,
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun TestScope.createRoomSelectPresenter(
|
||||||
|
mode: RoomSelectMode = RoomSelectMode.Forward,
|
||||||
|
roomListService: RoomListService = FakeRoomListService(),
|
||||||
|
) = RoomSelectPresenter(
|
||||||
|
mode = mode,
|
||||||
|
dataSource = RoomSelectSearchDataSource(
|
||||||
|
roomListService = roomListService,
|
||||||
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.troubleshoot.impl
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.troubleshoot.api.NotificationTroubleShootEntryPoint
|
||||||
|
import io.element.android.services.analytics.test.FakeScreenTracker
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultNotificationTroubleShootEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultNotificationTroubleShootEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
TroubleshootNotificationsNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = createTroubleshootNotificationsPresenter(),
|
||||||
|
screenTracker = FakeScreenTracker(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : NotificationTroubleShootEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(TroubleshootNotificationsNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -97,23 +97,23 @@ class TroubleshootNotificationsPresenterTest {
|
||||||
assertThat(stateAfterStart.testSuiteState.mainState).isEqualTo(AsyncAction.Loading)
|
assertThat(stateAfterStart.testSuiteState.mainState).isEqualTo(AsyncAction.Loading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun createTroubleshootTestSuite(
|
|
||||||
tests: Set<NotificationTroubleshootTest> = emptySet(),
|
private fun createTroubleshootTestSuite(
|
||||||
currentPushProvider: String? = null,
|
tests: Set<NotificationTroubleshootTest> = emptySet(),
|
||||||
): TroubleshootTestSuite {
|
currentPushProvider: String? = null,
|
||||||
return TroubleshootTestSuite(
|
): TroubleshootTestSuite {
|
||||||
notificationTroubleshootTests = tests,
|
return TroubleshootTestSuite(
|
||||||
getCurrentPushProvider = FakeGetCurrentPushProvider(currentPushProvider),
|
notificationTroubleshootTests = tests,
|
||||||
analyticsService = FakeAnalyticsService(),
|
getCurrentPushProvider = FakeGetCurrentPushProvider(currentPushProvider),
|
||||||
)
|
analyticsService = FakeAnalyticsService(),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
private fun createTroubleshootNotificationsPresenter(
|
|
||||||
troubleshootTestSuite: TroubleshootTestSuite = createTroubleshootTestSuite(),
|
internal fun createTroubleshootNotificationsPresenter(
|
||||||
): TroubleshootNotificationsPresenter {
|
troubleshootTestSuite: TroubleshootTestSuite = createTroubleshootTestSuite(),
|
||||||
return TroubleshootNotificationsPresenter(
|
): TroubleshootNotificationsPresenter {
|
||||||
troubleshootTestSuite = troubleshootTestSuite,
|
return TroubleshootNotificationsPresenter(
|
||||||
)
|
troubleshootTestSuite = troubleshootTestSuite,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025 New Vector 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.troubleshoot.impl.history
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.bumble.appyx.core.modality.BuildContext
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.push.test.FakePushService
|
||||||
|
import io.element.android.libraries.troubleshoot.api.PushHistoryEntryPoint
|
||||||
|
import io.element.android.services.analytics.test.FakeScreenTracker
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.node.TestParentNode
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class DefaultPushHistoryEntryPointTest {
|
||||||
|
@Test
|
||||||
|
fun `test node builder`() {
|
||||||
|
val entryPoint = DefaultPushHistoryEntryPoint()
|
||||||
|
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||||
|
PushHistoryNode(
|
||||||
|
buildContext = buildContext,
|
||||||
|
plugins = plugins,
|
||||||
|
presenter = PushHistoryPresenter(
|
||||||
|
pushService = FakePushService(),
|
||||||
|
),
|
||||||
|
screenTracker = FakeScreenTracker(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val callback = object : PushHistoryEntryPoint.Callback {
|
||||||
|
override fun onDone() = lambdaError()
|
||||||
|
override fun onItemClick(sessionId: SessionId, roomId: RoomId, eventId: EventId) = lambdaError()
|
||||||
|
}
|
||||||
|
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null))
|
||||||
|
.callback(callback)
|
||||||
|
.build()
|
||||||
|
assertThat(result).isInstanceOf(PushHistoryNode::class.java)
|
||||||
|
assertThat(result.plugins).contains(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue