Hide Element Call entry point if Element Call service is not available. (#4783)
* Hide Element Call entry point if Element Call service is not available. * No need to preview the case RoomCallState.Unavailable * Hide start call action from user profile if Element Call is not available. * Add mising `use` and cover the problem by a test. * Update screenshots * Update enterprise submodule ref. * Ensure `enterpriseService.isElementCallAvailable()` is not called several times. And fix unit tests on CI --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
@@ -13,6 +13,8 @@ import io.element.android.features.roomcall.api.RoomCallState.StandBy
|
||||
|
||||
@Immutable
|
||||
sealed interface RoomCallState {
|
||||
data object Unavailable : RoomCallState
|
||||
|
||||
data class StandBy(
|
||||
val canStartCall: Boolean,
|
||||
) : RoomCallState
|
||||
@@ -25,6 +27,7 @@ sealed interface RoomCallState {
|
||||
}
|
||||
|
||||
fun RoomCallState.hasPermissionToJoin() = when (this) {
|
||||
RoomCallState.Unavailable -> false
|
||||
is StandBy -> canStartCall
|
||||
is OnGoing -> canJoinCall
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ open class RoomCallStateProvider : PreviewParameterProvider<RoomCallState> {
|
||||
anOngoingCallState(),
|
||||
anOngoingCallState(canJoinCall = false),
|
||||
anOngoingCallState(canJoinCall = true, isUserInTheCall = true),
|
||||
RoomCallState.Unavailable,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ dependencies {
|
||||
api(projects.features.roomcall.api)
|
||||
implementation(libs.kotlinx.collections.immutable)
|
||||
implementation(projects.features.call.api)
|
||||
implementation(projects.features.enterprise.api)
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.matrix.api)
|
||||
implementation(projects.libraries.matrixui)
|
||||
@@ -32,6 +33,7 @@ dependencies {
|
||||
testImplementation(libs.test.turbine)
|
||||
testImplementation(projects.libraries.matrix.test)
|
||||
testImplementation(projects.features.call.test)
|
||||
testImplementation(projects.features.enterprise.test)
|
||||
testImplementation(projects.tests.testutils)
|
||||
testImplementation(libs.androidx.compose.ui.test.junit)
|
||||
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
|
||||
@@ -11,9 +11,11 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import io.element.android.features.call.api.CurrentCall
|
||||
import io.element.android.features.call.api.CurrentCallService
|
||||
import io.element.android.features.enterprise.api.EnterpriseService
|
||||
import io.element.android.features.roomcall.api.RoomCallState
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
@@ -23,9 +25,13 @@ import javax.inject.Inject
|
||||
class RoomCallStatePresenter @Inject constructor(
|
||||
private val room: JoinedRoom,
|
||||
private val currentCallService: CurrentCallService,
|
||||
private val enterpriseService: EnterpriseService,
|
||||
) : Presenter<RoomCallState> {
|
||||
@Composable
|
||||
override fun present(): RoomCallState {
|
||||
val isAvailable by produceState(false) {
|
||||
value = enterpriseService.isElementCallAvailable()
|
||||
}
|
||||
val roomInfo by room.roomInfoFlow.collectAsState()
|
||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
val canJoinCall by room.canCall(updateKey = syncUpdateFlow.value)
|
||||
@@ -41,6 +47,7 @@ class RoomCallStatePresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
val callState = when {
|
||||
isAvailable.not() -> RoomCallState.Unavailable
|
||||
roomInfo.hasRoomCall -> RoomCallState.OnGoing(
|
||||
canJoinCall = canJoinCall,
|
||||
isUserInTheCall = isUserInTheCall,
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.call.api.CurrentCall
|
||||
import io.element.android.features.call.api.CurrentCallService
|
||||
import io.element.android.features.call.test.FakeCurrentCallService
|
||||
import io.element.android.features.enterprise.test.FakeEnterpriseService
|
||||
import io.element.android.features.roomcall.api.RoomCallState
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
||||
@@ -25,12 +26,13 @@ class RoomCallStatePresenterTest {
|
||||
@Test
|
||||
fun `present - initial state`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(false) },
|
||||
)
|
||||
)
|
||||
val presenter = createRoomCallStatePresenter(joinedRoom = room)
|
||||
presenter.test {
|
||||
skipItems(1)
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
RoomCallState.StandBy(
|
||||
@@ -40,10 +42,29 @@ class RoomCallStatePresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - element call not available`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(false) },
|
||||
)
|
||||
)
|
||||
val presenter = createRoomCallStatePresenter(
|
||||
joinedRoom = room,
|
||||
isElementCallAvailable = false,
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState).isEqualTo(
|
||||
RoomCallState.Unavailable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - initial state - user can join call`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
)
|
||||
)
|
||||
@@ -69,6 +90,7 @@ class RoomCallStatePresenterTest {
|
||||
)
|
||||
val presenter = createRoomCallStatePresenter(joinedRoom = room)
|
||||
presenter.test {
|
||||
skipItems(1)
|
||||
assertThat(awaitItem()).isEqualTo(
|
||||
RoomCallState.OnGoing(
|
||||
canJoinCall = false,
|
||||
@@ -83,15 +105,15 @@ class RoomCallStatePresenterTest {
|
||||
fun `present - user has joined the call on another session`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
val presenter = createRoomCallStatePresenter(joinedRoom = room)
|
||||
presenter.test {
|
||||
@@ -110,15 +132,15 @@ class RoomCallStatePresenterTest {
|
||||
fun `present - user has joined the call locally`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
val presenter = createRoomCallStatePresenter(
|
||||
joinedRoom = room,
|
||||
@@ -140,15 +162,15 @@ class RoomCallStatePresenterTest {
|
||||
fun `present - user leaves the call`() = runTest {
|
||||
val room = FakeJoinedRoom(
|
||||
baseRoom = FakeBaseRoom(
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
canUserJoinCallResult = { Result.success(true) },
|
||||
).apply {
|
||||
givenRoomInfo(
|
||||
aRoomInfo(
|
||||
hasRoomCall = true,
|
||||
activeRoomCallParticipants = listOf(sessionId),
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
val currentCall = MutableStateFlow<CurrentCall>(CurrentCall.RoomCall(room.roomId))
|
||||
val currentCallService = FakeCurrentCallService(currentCall = currentCall)
|
||||
@@ -203,10 +225,14 @@ class RoomCallStatePresenterTest {
|
||||
private fun createRoomCallStatePresenter(
|
||||
joinedRoom: JoinedRoom,
|
||||
currentCallService: CurrentCallService = FakeCurrentCallService(),
|
||||
isElementCallAvailable: Boolean = true,
|
||||
): RoomCallStatePresenter {
|
||||
return RoomCallStatePresenter(
|
||||
room = joinedRoom,
|
||||
currentCallService = currentCallService,
|
||||
enterpriseService = FakeEnterpriseService(
|
||||
isElementCallAvailableResult = { isElementCallAvailable },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user