create room : fix tests and remove auto-fill alias for now.
This commit is contained in:
parent
5255b03aca
commit
06bea47864
10 changed files with 169 additions and 123 deletions
|
|
@ -46,6 +46,7 @@ class CreateRoomDataStore @Inject constructor(
|
||||||
|
|
||||||
fun setRoomName(roomName: String) {
|
fun setRoomName(roomName: String) {
|
||||||
createRoomConfigFlow.getAndUpdate { config ->
|
createRoomConfigFlow.getAndUpdate { config ->
|
||||||
|
/*
|
||||||
val newVisibility = when (config.roomVisibility) {
|
val newVisibility = when (config.roomVisibility) {
|
||||||
is RoomVisibilityState.Public -> {
|
is RoomVisibilityState.Public -> {
|
||||||
val roomAddress = config.roomVisibility.roomAddress
|
val roomAddress = config.roomVisibility.roomAddress
|
||||||
|
|
@ -59,9 +60,9 @@ class CreateRoomDataStore @Inject constructor(
|
||||||
}
|
}
|
||||||
else -> config.roomVisibility
|
else -> config.roomVisibility
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
config.copy(
|
config.copy(
|
||||||
roomName = roomName.takeIf { it.isNotEmpty() },
|
roomName = roomName.takeIf { it.isNotEmpty() },
|
||||||
roomVisibility = newVisibility,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.selection.selectable
|
import androidx.compose.foundation.selection.selectable
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
|
@ -36,13 +35,13 @@ fun RoomAccessOption(
|
||||||
isSelected: Boolean = false,
|
isSelected: Boolean = false,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier
|
modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.selectable(
|
.selectable(
|
||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
onClick = { onOptionClick(roomAccessItem) },
|
onClick = { onOptionClick(roomAccessItem) },
|
||||||
role = Role.RadioButton,
|
role = Role.RadioButton,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -59,8 +58,8 @@ fun RoomAccessOption(
|
||||||
}
|
}
|
||||||
RadioButton(
|
RadioButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
.size(48.dp),
|
.size(48.dp),
|
||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
// null recommended for accessibility with screenreaders
|
// null recommended for accessibility with screenreaders
|
||||||
onClick = null
|
onClick = null
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ fun RoomVisibilityOption(
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = Modifier
|
||||||
.size(30.dp)
|
.size(30.dp)
|
||||||
.clip(RoundedCornerShape(8.dp))
|
.clip(RoundedCornerShape(8.dp))
|
||||||
.background(ElementTheme.colors.bgSubtleSecondary)
|
.background(ElementTheme.colors.bgSubtleSecondary)
|
||||||
|
|
@ -60,7 +60,7 @@ fun RoomVisibilityOption(
|
||||||
Icon(
|
Icon(
|
||||||
resourceId = roomPrivacyItem.icon,
|
resourceId = roomPrivacyItem.icon,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = if(isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary,
|
tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(Modifier.size(16.dp))
|
Spacer(Modifier.size(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import io.element.android.features.createroom.impl.CreateRoomConfig
|
|
||||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
|
|
||||||
|
|
@ -18,7 +17,7 @@ sealed interface ConfigureRoomEvents {
|
||||||
data class RoomAccessChanged(val roomAccess: RoomAccessItem) : ConfigureRoomEvents
|
data class RoomAccessChanged(val roomAccess: RoomAccessItem) : ConfigureRoomEvents
|
||||||
data class RoomAddressChanged(val roomAddress: String) : ConfigureRoomEvents
|
data class RoomAddressChanged(val roomAddress: String) : ConfigureRoomEvents
|
||||||
data class RemoveUserFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents
|
data class RemoveUserFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents
|
||||||
data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents
|
data object CreateRoom : ConfigureRoomEvents
|
||||||
data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents
|
data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents
|
||||||
data object CancelCreateRoom : ConfigureRoomEvents
|
data object CancelCreateRoom : ConfigureRoomEvents
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,13 @@ import io.element.android.features.createroom.impl.CreateRoomConfig
|
||||||
import io.element.android.features.createroom.impl.CreateRoomDataStore
|
import io.element.android.features.createroom.impl.CreateRoomDataStore
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.architecture.runUpdatingState
|
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
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.createroom.CreateRoomParameters
|
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
|
||||||
import io.element.android.libraries.matrix.api.createroom.JoinRuleOverride
|
|
||||||
import io.element.android.libraries.matrix.api.createroom.RoomPreset
|
import io.element.android.libraries.matrix.api.createroom.RoomPreset
|
||||||
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
|
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
|
|
@ -61,7 +60,7 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
val cameraPermissionState = cameraPermissionPresenter.present()
|
val cameraPermissionState = cameraPermissionPresenter.present()
|
||||||
val createRoomConfig = dataStore.createRoomConfig.collectAsState(CreateRoomConfig())
|
val createRoomConfig = dataStore.createRoomConfig.collectAsState(CreateRoomConfig())
|
||||||
val homeserverName = remember { matrixClient.userIdServerName() }
|
val homeserverName = remember { matrixClient.userIdServerName() }
|
||||||
val isKnockFeatureEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock).collectAsState(initial = false)
|
val isKnockFeatureEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock).collectAsState(initial = false)
|
||||||
|
|
||||||
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(
|
||||||
onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) },
|
onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) },
|
||||||
|
|
@ -103,7 +102,7 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
is ConfigureRoomEvents.RemoveUserFromSelection -> dataStore.selectedUserListDataStore.removeUserFromSelection(event.matrixUser)
|
is ConfigureRoomEvents.RemoveUserFromSelection -> dataStore.selectedUserListDataStore.removeUserFromSelection(event.matrixUser)
|
||||||
is ConfigureRoomEvents.RoomAccessChanged -> dataStore.setRoomAccess(event.roomAccess)
|
is ConfigureRoomEvents.RoomAccessChanged -> dataStore.setRoomAccess(event.roomAccess)
|
||||||
is ConfigureRoomEvents.RoomAddressChanged -> dataStore.setRoomAddress(event.roomAddress)
|
is ConfigureRoomEvents.RoomAddressChanged -> dataStore.setRoomAddress(event.roomAddress)
|
||||||
is ConfigureRoomEvents.CreateRoom -> createRoom(event.config)
|
is ConfigureRoomEvents.CreateRoom -> createRoom(createRoomConfig.value)
|
||||||
is ConfigureRoomEvents.HandleAvatarAction -> {
|
is ConfigureRoomEvents.HandleAvatarAction -> {
|
||||||
when (event.action) {
|
when (event.action) {
|
||||||
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
|
AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
|
||||||
|
|
@ -118,7 +117,6 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = AsyncAction.Uninitialized
|
ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = AsyncAction.Uninitialized
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,20 +135,33 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
config: CreateRoomConfig,
|
config: CreateRoomConfig,
|
||||||
createRoomAction: MutableState<AsyncAction<RoomId>>
|
createRoomAction: MutableState<AsyncAction<RoomId>>
|
||||||
) = launch {
|
) = launch {
|
||||||
runUpdatingState(createRoomAction) {
|
suspend {
|
||||||
val avatarUrl = config.avatarUri?.let { uploadAvatar(it) }
|
val avatarUrl = config.avatarUri?.let { uploadAvatar(it) }
|
||||||
val params = CreateRoomParameters(
|
val params = if (config.roomVisibility is RoomVisibilityState.Public) {
|
||||||
name = config.roomName,
|
CreateRoomParameters(
|
||||||
topic = config.topic,
|
name = config.roomName,
|
||||||
isEncrypted = config.roomVisibility is RoomVisibilityState.Private,
|
topic = config.topic,
|
||||||
isDirect = false,
|
isEncrypted = false,
|
||||||
visibility = if (config.roomVisibility is RoomVisibilityState.Public) RoomVisibility.PUBLIC else RoomVisibility.PRIVATE,
|
isDirect = false,
|
||||||
joinRuleOverride = if (config.roomVisibility is RoomVisibilityState.Public) config.roomVisibility.roomAccess.toJoinRule() else JoinRuleOverride.None,
|
visibility = RoomVisibility.PUBLIC,
|
||||||
preset = if (config.roomVisibility is RoomVisibilityState.Public) RoomPreset.PUBLIC_CHAT else RoomPreset.PRIVATE_CHAT,
|
joinRuleOverride = config.roomVisibility.roomAccess.toJoinRule(),
|
||||||
invite = config.invites.map { it.userId },
|
preset = RoomPreset.PUBLIC_CHAT,
|
||||||
avatar = avatarUrl,
|
invite = config.invites.map { it.userId },
|
||||||
canonicalAlias = config.roomVisibility.roomAddress()
|
avatar = avatarUrl,
|
||||||
)
|
canonicalAlias = config.roomVisibility.roomAddress()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
CreateRoomParameters(
|
||||||
|
name = config.roomName,
|
||||||
|
topic = config.topic,
|
||||||
|
isEncrypted = config.roomVisibility is RoomVisibilityState.Private,
|
||||||
|
isDirect = false,
|
||||||
|
visibility = RoomVisibility.PRIVATE,
|
||||||
|
preset = RoomPreset.PRIVATE_CHAT,
|
||||||
|
invite = config.invites.map { it.userId },
|
||||||
|
avatar = avatarUrl,
|
||||||
|
)
|
||||||
|
}
|
||||||
matrixClient.createRoom(params)
|
matrixClient.createRoom(params)
|
||||||
.onFailure { failure ->
|
.onFailure { failure ->
|
||||||
Timber.e(failure, "Failed to create room")
|
Timber.e(failure, "Failed to create room")
|
||||||
|
|
@ -159,7 +170,8 @@ class ConfigureRoomPresenter @Inject constructor(
|
||||||
dataStore.clearCachedData()
|
dataStore.clearCachedData()
|
||||||
analyticsService.capture(CreatedRoom(isDM = false))
|
analyticsService.capture(CreatedRoom(isDM = false))
|
||||||
}
|
}
|
||||||
}
|
.getOrThrow()
|
||||||
|
}.runCatchingUpdatingState(createRoomAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun uploadAvatar(avatarUri: Uri): String {
|
private suspend fun uploadAvatar(avatarUri: Uri): String {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
import io.element.android.libraries.permissions.api.PermissionsState
|
import io.element.android.libraries.permissions.api.PermissionsState
|
||||||
import io.element.android.libraries.permissions.api.aPermissionsState
|
import io.element.android.libraries.permissions.api.aPermissionsState
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
||||||
open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomState> {
|
open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomState> {
|
||||||
|
|
@ -23,6 +22,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aConfigureRoomState(),
|
aConfigureRoomState(),
|
||||||
aConfigureRoomState(
|
aConfigureRoomState(
|
||||||
|
isKnockFeatureEnabled = false,
|
||||||
config = CreateRoomConfig(
|
config = CreateRoomConfig(
|
||||||
roomName = "Room 101",
|
roomName = "Room 101",
|
||||||
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
||||||
|
|
@ -35,7 +35,6 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
aConfigureRoomState(
|
aConfigureRoomState(
|
||||||
isKnockFeatureEnabled = false,
|
|
||||||
config = CreateRoomConfig(
|
config = CreateRoomConfig(
|
||||||
roomName = "Room 101",
|
roomName = "Room 101",
|
||||||
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldn’t be more than 3 lines",
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ import io.element.android.libraries.designsystem.components.async.AsyncActionVie
|
||||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||||
import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap
|
import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
|
||||||
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
import io.element.android.libraries.designsystem.theme.components.Scaffold
|
||||||
|
|
@ -82,7 +81,7 @@ fun ConfigureRoomView(
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
onNextClick = {
|
onNextClick = {
|
||||||
focusManager.clearFocus()
|
focusManager.clearFocus()
|
||||||
state.eventSink(ConfigureRoomEvents.CreateRoom(state.config))
|
state.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +163,7 @@ fun ConfigureRoomView(
|
||||||
},
|
},
|
||||||
onSuccess = { onCreateRoomSuccess(it) },
|
onSuccess = { onCreateRoomSuccess(it) },
|
||||||
errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) },
|
errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) },
|
||||||
onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) },
|
onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) },
|
||||||
onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
|
onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -326,7 +325,7 @@ private fun RoomAddressField(
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
text = "Room address",
|
text = "Room address",
|
||||||
)
|
)
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
value = address.value,
|
value = address.value,
|
||||||
|
|
@ -359,7 +358,6 @@ private fun RoomAddressField(
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@PreviewWithLargeHeight
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ConfigureRoomViewPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = ElementPreview {
|
internal fun ConfigureRoomViewPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = ElementPreview {
|
||||||
ConfigureRoomView(
|
ConfigureRoomView(
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ package io.element.android.features.createroom.impl.configureroom
|
||||||
import io.element.android.libraries.matrix.api.createroom.JoinRuleOverride
|
import io.element.android.libraries.matrix.api.createroom.JoinRuleOverride
|
||||||
|
|
||||||
enum class RoomAccess {
|
enum class RoomAccess {
|
||||||
Anyone, Knocking
|
Anyone,
|
||||||
|
Knocking
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RoomAccess.toJoinRule(): JoinRuleOverride {
|
fun RoomAccess.toJoinRule(): JoinRuleOverride {
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,3 @@ enum class RoomAccessItem(
|
||||||
description = CommonStrings.screen_create_room_access_section_knocking_option_description,
|
description = CommonStrings.screen_create_room_access_section_knocking_option_description,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,16 @@
|
||||||
package io.element.android.features.createroom.impl.configureroom
|
package io.element.android.features.createroom.impl.configureroom
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import app.cash.molecule.RecompositionMode
|
import app.cash.turbine.TurbineTestContext
|
||||||
import app.cash.molecule.moleculeFlow
|
|
||||||
import app.cash.turbine.test
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
import io.element.android.features.createroom.impl.CreateRoomConfig
|
import io.element.android.features.createroom.impl.CreateRoomConfig
|
||||||
import io.element.android.features.createroom.impl.CreateRoomDataStore
|
import io.element.android.features.createroom.impl.CreateRoomDataStore
|
||||||
import io.element.android.features.createroom.impl.userlist.UserListDataStore
|
import io.element.android.features.createroom.impl.userlist.UserListDataStore
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
|
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
|
||||||
import io.element.android.libraries.matrix.test.A_MESSAGE
|
import io.element.android.libraries.matrix.test.A_MESSAGE
|
||||||
|
|
@ -25,13 +26,18 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||||
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
import io.element.android.libraries.matrix.ui.media.AvatarAction
|
||||||
|
import io.element.android.libraries.mediapickers.api.PickerProvider
|
||||||
import io.element.android.libraries.mediapickers.test.FakePickerProvider
|
import io.element.android.libraries.mediapickers.test.FakePickerProvider
|
||||||
|
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||||
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
import io.element.android.libraries.mediaupload.api.MediaUploadInfo
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
|
import io.element.android.libraries.permissions.api.PermissionsPresenter
|
||||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenter
|
import io.element.android.libraries.permissions.test.FakePermissionsPresenter
|
||||||
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
|
import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
import io.element.android.tests.testutils.test
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
|
|
@ -56,33 +62,8 @@ class ConfigureRoomPresenterTest {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
private lateinit var presenter: ConfigureRoomPresenter
|
|
||||||
private lateinit var userListDataStore: UserListDataStore
|
|
||||||
private lateinit var createRoomDataStore: CreateRoomDataStore
|
|
||||||
private lateinit var fakeMatrixClient: FakeMatrixClient
|
|
||||||
private lateinit var fakePickerProvider: FakePickerProvider
|
|
||||||
private lateinit var fakeMediaPreProcessor: FakeMediaPreProcessor
|
|
||||||
private lateinit var fakeAnalyticsService: FakeAnalyticsService
|
|
||||||
private lateinit var fakePermissionsPresenter: FakePermissionsPresenter
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
fakeMatrixClient = FakeMatrixClient()
|
|
||||||
userListDataStore = UserListDataStore()
|
|
||||||
createRoomDataStore = CreateRoomDataStore(userListDataStore)
|
|
||||||
fakePickerProvider = FakePickerProvider()
|
|
||||||
fakeMediaPreProcessor = FakeMediaPreProcessor()
|
|
||||||
fakeAnalyticsService = FakeAnalyticsService()
|
|
||||||
fakePermissionsPresenter = FakePermissionsPresenter()
|
|
||||||
presenter = ConfigureRoomPresenter(
|
|
||||||
dataStore = createRoomDataStore,
|
|
||||||
matrixClient = fakeMatrixClient,
|
|
||||||
mediaPickerProvider = fakePickerProvider,
|
|
||||||
mediaPreProcessor = fakeMediaPreProcessor,
|
|
||||||
analyticsService = fakeAnalyticsService,
|
|
||||||
permissionsPresenterFactory = FakePermissionsPresenterFactory(fakePermissionsPresenter),
|
|
||||||
)
|
|
||||||
|
|
||||||
mockkStatic(File::readBytes)
|
mockkStatic(File::readBytes)
|
||||||
every { any<File>().readBytes() } returns byteArrayOf()
|
every { any<File>().readBytes() } returns byteArrayOf()
|
||||||
}
|
}
|
||||||
|
|
@ -94,50 +75,56 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state`() = runTest {
|
fun `present - initial state`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val presenter = createConfigureRoomPresenter()
|
||||||
presenter.present()
|
presenter.test {
|
||||||
}.test {
|
val initialState = initialState()
|
||||||
val initialState = awaitItem()
|
|
||||||
assertThat(initialState.config).isEqualTo(CreateRoomConfig())
|
assertThat(initialState.config).isEqualTo(CreateRoomConfig())
|
||||||
assertThat(initialState.config.roomName).isNull()
|
assertThat(initialState.config.roomName).isNull()
|
||||||
assertThat(initialState.config.topic).isNull()
|
assertThat(initialState.config.topic).isNull()
|
||||||
assertThat(initialState.config.invites).isEmpty()
|
assertThat(initialState.config.invites).isEmpty()
|
||||||
assertThat(initialState.config.avatarUri).isNull()
|
assertThat(initialState.config.avatarUri).isNull()
|
||||||
assertThat(initialState.config.roomVisibility).isEqualTo(RoomVisibilityState.Private)
|
assertThat(initialState.config.roomVisibility).isEqualTo(RoomVisibilityState.Private)
|
||||||
|
assertThat(initialState.createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
|
assertThat(initialState.homeserverName).isEqualTo("matrix.org")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - create room button is enabled only if the required fields are completed`() = runTest {
|
fun `present - create room button is enabled only if the required fields are completed`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val presenter = createConfigureRoomPresenter()
|
||||||
presenter.present()
|
presenter.test {
|
||||||
}.test {
|
val initialState = initialState()
|
||||||
val initialState = awaitItem()
|
|
||||||
var config = initialState.config
|
var config = initialState.config
|
||||||
assertThat(initialState.isCreateButtonEnabled).isFalse()
|
assertThat(initialState.config.isValid).isFalse()
|
||||||
|
|
||||||
// Room name not empty
|
// Room name not empty
|
||||||
initialState.eventSink(ConfigureRoomEvents.RoomNameChanged(A_ROOM_NAME))
|
initialState.eventSink(ConfigureRoomEvents.RoomNameChanged(A_ROOM_NAME))
|
||||||
var newState: ConfigureRoomState = awaitItem()
|
var newState: ConfigureRoomState = awaitItem()
|
||||||
config = config.copy(roomName = A_ROOM_NAME)
|
config = config.copy(roomName = A_ROOM_NAME)
|
||||||
assertThat(newState.config).isEqualTo(config)
|
assertThat(newState.config).isEqualTo(config)
|
||||||
assertThat(newState.isCreateButtonEnabled).isTrue()
|
assertThat(newState.config.isValid).isTrue()
|
||||||
|
|
||||||
// Clear room name
|
// Clear room name
|
||||||
newState.eventSink(ConfigureRoomEvents.RoomNameChanged(""))
|
newState.eventSink(ConfigureRoomEvents.RoomNameChanged(""))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
config = config.copy(roomName = null)
|
config = config.copy(roomName = null)
|
||||||
assertThat(newState.config).isEqualTo(config)
|
assertThat(newState.config).isEqualTo(config)
|
||||||
assertThat(newState.isCreateButtonEnabled).isFalse()
|
assertThat(newState.config.isValid).isFalse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - state is updated when fields are changed`() = runTest {
|
fun `present - state is updated when fields are changed`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val userListDataStore = UserListDataStore()
|
||||||
presenter.present()
|
val pickerProvider = FakePickerProvider()
|
||||||
}.test {
|
val permissionsPresenter = FakePermissionsPresenter()
|
||||||
val initialState = awaitItem()
|
val presenter = createConfigureRoomPresenter(
|
||||||
|
createRoomDataStore = CreateRoomDataStore(userListDataStore),
|
||||||
|
pickerProvider = pickerProvider,
|
||||||
|
permissionsPresenter = permissionsPresenter,
|
||||||
|
)
|
||||||
|
presenter.test {
|
||||||
|
val initialState = initialState()
|
||||||
var expectedConfig = CreateRoomConfig()
|
var expectedConfig = CreateRoomConfig()
|
||||||
assertThat(initialState.config).isEqualTo(expectedConfig)
|
assertThat(initialState.config).isEqualTo(expectedConfig)
|
||||||
|
|
||||||
|
|
@ -165,22 +152,22 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
// Room avatar
|
// Room avatar
|
||||||
// Pick avatar
|
// Pick avatar
|
||||||
fakePickerProvider.givenResult(null)
|
pickerProvider.givenResult(null)
|
||||||
// From gallery
|
// From gallery
|
||||||
val uriFromGallery = Uri.parse(AN_URI_FROM_GALLERY)
|
val uriFromGallery = Uri.parse(AN_URI_FROM_GALLERY)
|
||||||
fakePickerProvider.givenResult(uriFromGallery)
|
pickerProvider.givenResult(uriFromGallery)
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery)
|
expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery)
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
// From camera
|
// From camera
|
||||||
val uriFromCamera = Uri.parse(AN_URI_FROM_CAMERA)
|
val uriFromCamera = Uri.parse(AN_URI_FROM_CAMERA)
|
||||||
fakePickerProvider.givenResult(uriFromCamera)
|
pickerProvider.givenResult(uriFromCamera)
|
||||||
assertThat(newState.cameraPermissionState.permissionGranted).isFalse()
|
assertThat(newState.cameraPermissionState.permissionGranted).isFalse()
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
assertThat(newState.cameraPermissionState.showDialog).isTrue()
|
assertThat(newState.cameraPermissionState.showDialog).isTrue()
|
||||||
fakePermissionsPresenter.setPermissionGranted()
|
permissionsPresenter.setPermissionGranted()
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
assertThat(newState.cameraPermissionState.permissionGranted).isTrue()
|
assertThat(newState.cameraPermissionState.permissionGranted).isTrue()
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
|
|
@ -188,7 +175,7 @@ class ConfigureRoomPresenterTest {
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
// Do it again, no permission is requested
|
// Do it again, no permission is requested
|
||||||
val uriFromCamera2 = Uri.parse(AN_URI_FROM_CAMERA_2)
|
val uriFromCamera2 = Uri.parse(AN_URI_FROM_CAMERA_2)
|
||||||
fakePickerProvider.givenResult(uriFromCamera2)
|
pickerProvider.givenResult(uriFromCamera2)
|
||||||
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera2)
|
expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera2)
|
||||||
|
|
@ -200,9 +187,15 @@ class ConfigureRoomPresenterTest {
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
|
|
||||||
// Room privacy
|
// Room privacy
|
||||||
newState.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(RoomVisibilityState.Public))
|
newState.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(RoomVisibilityItem.Public))
|
||||||
newState = awaitItem()
|
newState = awaitItem()
|
||||||
expectedConfig = expectedConfig.copy(roomVisibility = RoomVisibilityState.Public)
|
expectedConfig = expectedConfig.copy(
|
||||||
|
roomVisibility = RoomVisibilityState.Public(
|
||||||
|
roomAddress = RoomAddress.AutoFilled(expectedConfig.roomName ?: ""),
|
||||||
|
roomAddressErrorState = RoomAddressErrorState.None,
|
||||||
|
roomAccess = RoomAccess.Anyone,
|
||||||
|
)
|
||||||
|
)
|
||||||
assertThat(newState.config).isEqualTo(expectedConfig)
|
assertThat(newState.config).isEqualTo(expectedConfig)
|
||||||
|
|
||||||
// Remove user
|
// Remove user
|
||||||
|
|
@ -215,15 +208,17 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - trigger create room action`() = runTest {
|
fun `present - trigger create room action`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val matrixClient = createMatrixClient()
|
||||||
presenter.present()
|
val presenter = createConfigureRoomPresenter(
|
||||||
}.test {
|
matrixClient = matrixClient
|
||||||
val initialState = awaitItem()
|
)
|
||||||
|
presenter.test {
|
||||||
|
val initialState = initialState()
|
||||||
val createRoomResult = Result.success(RoomId("!createRoomResult:domain"))
|
val createRoomResult = Result.success(RoomId("!createRoomResult:domain"))
|
||||||
|
|
||||||
fakeMatrixClient.givenCreateRoomResult(createRoomResult)
|
matrixClient.givenCreateRoomResult(createRoomResult)
|
||||||
|
|
||||||
initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
initialState.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
val stateAfterCreateRoom = awaitItem()
|
val stateAfterCreateRoom = awaitItem()
|
||||||
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
|
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
|
||||||
|
|
@ -233,18 +228,22 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - record analytics when creating room`() = runTest {
|
fun `present - record analytics when creating room`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val matrixClient = createMatrixClient()
|
||||||
presenter.present()
|
val analyticsService = FakeAnalyticsService()
|
||||||
}.test {
|
val presenter = createConfigureRoomPresenter(
|
||||||
val initialState = awaitItem()
|
matrixClient = matrixClient,
|
||||||
|
analyticsService = analyticsService
|
||||||
|
)
|
||||||
|
presenter.test {
|
||||||
|
val initialState = initialState()
|
||||||
val createRoomResult = Result.success(RoomId("!createRoomResult:domain"))
|
val createRoomResult = Result.success(RoomId("!createRoomResult:domain"))
|
||||||
|
|
||||||
fakeMatrixClient.givenCreateRoomResult(createRoomResult)
|
matrixClient.givenCreateRoomResult(createRoomResult)
|
||||||
|
|
||||||
initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
initialState.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
skipItems(2)
|
skipItems(2)
|
||||||
|
|
||||||
val analyticsEvent = fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>().firstOrNull()
|
val analyticsEvent = analyticsService.capturedEvents.filterIsInstance<CreatedRoom>().firstOrNull()
|
||||||
assertThat(analyticsEvent).isNotNull()
|
assertThat(analyticsEvent).isNotNull()
|
||||||
assertThat(analyticsEvent?.isDM).isFalse()
|
assertThat(analyticsEvent?.isDM).isFalse()
|
||||||
}
|
}
|
||||||
|
|
@ -252,23 +251,31 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - trigger create room with upload error and retry`() = runTest {
|
fun `present - trigger create room with upload error and retry`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val matrixClient = createMatrixClient()
|
||||||
presenter.present()
|
val analyticsService = FakeAnalyticsService()
|
||||||
}.test {
|
val mediaPreProcessor = FakeMediaPreProcessor()
|
||||||
skipItems(1)
|
val createRoomDataStore = CreateRoomDataStore(UserListDataStore())
|
||||||
|
val presenter = createConfigureRoomPresenter(
|
||||||
|
createRoomDataStore = createRoomDataStore,
|
||||||
|
mediaPreProcessor = mediaPreProcessor,
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
analyticsService = analyticsService
|
||||||
|
)
|
||||||
|
presenter.test {
|
||||||
|
val initialState = initialState()
|
||||||
createRoomDataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY))
|
createRoomDataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY))
|
||||||
fakeMediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), mockk())))
|
skipItems(1)
|
||||||
fakeMatrixClient.givenUploadMediaResult(Result.failure(A_THROWABLE))
|
mediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), mockk())))
|
||||||
|
matrixClient.givenUploadMediaResult(Result.failure(A_THROWABLE))
|
||||||
|
|
||||||
val initialState = awaitItem()
|
initialState.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
val stateAfterCreateRoom = awaitItem()
|
val stateAfterCreateRoom = awaitItem()
|
||||||
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
|
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
|
assertThat(analyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()
|
||||||
|
|
||||||
fakeMatrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL))
|
matrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL))
|
||||||
stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
|
||||||
|
|
@ -277,23 +284,25 @@ class ConfigureRoomPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - trigger retry and cancel actions`() = runTest {
|
fun `present - trigger retry and cancel actions`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
val fakeMatrixClient = createMatrixClient()
|
||||||
presenter.present()
|
val presenter = createConfigureRoomPresenter(
|
||||||
}.test {
|
matrixClient = fakeMatrixClient
|
||||||
val initialState = awaitItem()
|
)
|
||||||
|
presenter.test {
|
||||||
|
val initialState = initialState()
|
||||||
val createRoomResult = Result.failure<RoomId>(A_THROWABLE)
|
val createRoomResult = Result.failure<RoomId>(A_THROWABLE)
|
||||||
|
|
||||||
fakeMatrixClient.givenCreateRoomResult(createRoomResult)
|
fakeMatrixClient.givenCreateRoomResult(createRoomResult)
|
||||||
|
|
||||||
// Create
|
// Create
|
||||||
initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
initialState.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
val stateAfterCreateRoom = awaitItem()
|
val stateAfterCreateRoom = awaitItem()
|
||||||
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
|
assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||||
assertThat((stateAfterCreateRoom.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
|
assertThat((stateAfterCreateRoom.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
|
||||||
|
|
||||||
// Retry
|
// Retry
|
||||||
stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
|
stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
val stateAfterRetry = awaitItem()
|
val stateAfterRetry = awaitItem()
|
||||||
|
|
@ -305,4 +314,33 @@ class ConfigureRoomPresenterTest {
|
||||||
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun TurbineTestContext<ConfigureRoomState>.initialState(): ConfigureRoomState {
|
||||||
|
skipItems(1)
|
||||||
|
return awaitItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createMatrixClient() = FakeMatrixClient(
|
||||||
|
userIdServerNameLambda = { "matrix.org" },
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun createConfigureRoomPresenter(
|
||||||
|
createRoomDataStore: CreateRoomDataStore = CreateRoomDataStore(UserListDataStore()),
|
||||||
|
matrixClient: MatrixClient = createMatrixClient(),
|
||||||
|
pickerProvider: PickerProvider = FakePickerProvider(),
|
||||||
|
mediaPreProcessor: MediaPreProcessor = FakeMediaPreProcessor(),
|
||||||
|
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||||
|
permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(),
|
||||||
|
isKnockFeatureEnabled: Boolean = true,
|
||||||
|
) = ConfigureRoomPresenter(
|
||||||
|
dataStore = createRoomDataStore,
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
mediaPickerProvider = pickerProvider,
|
||||||
|
mediaPreProcessor = mediaPreProcessor,
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter),
|
||||||
|
featureFlagService = FakeFeatureFlagService(
|
||||||
|
mapOf(FeatureFlags.Knock.key to isKnockFeatureEnabled)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue