Rework FakeMatrixRoom so that it contains only lambdas. (#3229)
* Upgrade lint to 8.7.0-alpha01 * FakeMatrixRoom: lambda everywhere Fix test compilation issues
This commit is contained in:
parent
8cb5e9e75b
commit
5bda29ca7e
30 changed files with 1253 additions and 818 deletions
|
|
@ -123,7 +123,9 @@ class JoinRoomLoadedFlowNodeTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given a room flow node when initialized then it loads messages entry point`() = runTest {
|
fun `given a room flow node when initialized then it loads messages entry point`() = runTest {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { }
|
||||||
|
)
|
||||||
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
|
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
|
||||||
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())
|
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())
|
||||||
val roomFlowNode = createJoinedRoomLoadedFlowNode(
|
val roomFlowNode = createJoinedRoomLoadedFlowNode(
|
||||||
|
|
@ -144,7 +146,9 @@ class JoinRoomLoadedFlowNodeTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given a room flow node when callback on room details is triggered then it loads room details entry point`() = runTest {
|
fun `given a room flow node when callback on room details is triggered then it loads room details entry point`() = runTest {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { }
|
||||||
|
)
|
||||||
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
|
val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
|
||||||
val fakeRoomDetailsEntryPoint = FakeRoomDetailsEntryPoint()
|
val fakeRoomDetailsEntryPoint = FakeRoomDetailsEntryPoint()
|
||||||
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())
|
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Messages())
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class) class SendQueuesTest {
|
@OptIn(ExperimentalCoroutinesApi::class) class SendQueuesTest {
|
||||||
private val matrixClient = FakeMatrixClient()
|
private val matrixClient = FakeMatrixClient()
|
||||||
private val room = FakeMatrixRoom()
|
|
||||||
private val networkMonitor = FakeNetworkMonitor()
|
private val networkMonitor = FakeNetworkMonitor()
|
||||||
private val sut = SendQueues(matrixClient, networkMonitor)
|
private val sut = SendQueues(matrixClient, networkMonitor)
|
||||||
|
|
||||||
|
|
@ -43,11 +42,11 @@ import org.junit.Test
|
||||||
val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> }
|
val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> }
|
||||||
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
|
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
|
||||||
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
|
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
|
||||||
matrixClient.givenGetRoomResult(room.roomId, room)
|
|
||||||
|
|
||||||
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
|
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
|
||||||
room.setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
|
val room = FakeMatrixRoom(
|
||||||
|
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
|
||||||
|
)
|
||||||
|
matrixClient.givenGetRoomResult(room.roomId, room)
|
||||||
sut.launchIn(backgroundScope)
|
sut.launchIn(backgroundScope)
|
||||||
|
|
||||||
sendQueueDisabledFlow.emit(room.roomId)
|
sendQueueDisabledFlow.emit(room.roomId)
|
||||||
|
|
@ -72,10 +71,11 @@ import org.junit.Test
|
||||||
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
|
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
|
||||||
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
|
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
|
||||||
networkMonitor.connectivity.value = NetworkStatus.Offline
|
networkMonitor.connectivity.value = NetworkStatus.Offline
|
||||||
matrixClient.givenGetRoomResult(room.roomId, room)
|
|
||||||
|
|
||||||
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
|
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
|
||||||
room.setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
|
val room = FakeMatrixRoom(
|
||||||
|
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
|
||||||
|
)
|
||||||
|
matrixClient.givenGetRoomResult(room.roomId, room)
|
||||||
|
|
||||||
sut.launchIn(backgroundScope)
|
sut.launchIn(backgroundScope)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@ class DefaultCallWidgetProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getWidget - fails if it can't generate the URL for the widget`() = runTest {
|
fun `getWidget - fails if it can't generate the URL for the widget`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenGenerateWidgetWebViewUrlResult(Result.failure(Exception("Can't generate URL for widget")))
|
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.failure(Exception("Can't generate URL for widget")) }
|
||||||
}
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
}
|
}
|
||||||
|
|
@ -66,10 +66,10 @@ class DefaultCallWidgetProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getWidget - fails if it can't get the widget driver`() = runTest {
|
fun `getWidget - fails if it can't get the widget driver`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenGenerateWidgetWebViewUrlResult(Result.success("url"))
|
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
|
||||||
givenGetWidgetDriverResult(Result.failure(Exception("Can't get a widget driver")))
|
getWidgetDriverResult = { Result.failure(Exception("Can't get a widget driver")) }
|
||||||
}
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
}
|
}
|
||||||
|
|
@ -79,10 +79,10 @@ class DefaultCallWidgetProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getWidget - returns a widget driver when all steps are successful`() = runTest {
|
fun `getWidget - returns a widget driver when all steps are successful`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenGenerateWidgetWebViewUrlResult(Result.success("url"))
|
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
|
||||||
givenGetWidgetDriverResult(Result.success(FakeMatrixWidgetDriver()))
|
getWidgetDriverResult = { Result.success(FakeMatrixWidgetDriver()) },
|
||||||
}
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
}
|
}
|
||||||
|
|
@ -92,10 +92,10 @@ class DefaultCallWidgetProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getWidget - will use a custom base url if it exists`() = runTest {
|
fun `getWidget - will use a custom base url if it exists`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenGenerateWidgetWebViewUrlResult(Result.success("url"))
|
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
|
||||||
givenGetWidgetDriverResult(Result.success(FakeMatrixWidgetDriver()))
|
getWidgetDriverResult = { Result.success(FakeMatrixWidgetDriver()) },
|
||||||
}
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
}
|
}
|
||||||
|
|
@ -120,10 +120,10 @@ class DefaultCallWidgetProviderTest {
|
||||||
val elementCallBaseUrlProvider = FakeElementCallBaseUrlProvider { matrixClient ->
|
val elementCallBaseUrlProvider = FakeElementCallBaseUrlProvider { matrixClient ->
|
||||||
providesLambda(matrixClient)
|
providesLambda(matrixClient)
|
||||||
}
|
}
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenGenerateWidgetWebViewUrlResult(Result.success("url"))
|
generateWidgetWebViewUrlResult = { _, _, _, _ -> Result.success("url") },
|
||||||
givenGetWidgetDriverResult(Result.success(FakeMatrixWidgetDriver()))
|
getWidgetDriverResult = { Result.success(FakeMatrixWidgetDriver()) },
|
||||||
}
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,9 +92,9 @@ class AcceptDeclineInvitePresenterTest {
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom(
|
||||||
leaveRoomLambda = declineInviteFailure
|
leaveRoomLambda = declineInviteFailure
|
||||||
}
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val presenter = createAcceptDeclineInvitePresenter(client = client)
|
val presenter = createAcceptDeclineInvitePresenter(client = client)
|
||||||
|
|
@ -142,9 +142,9 @@ class AcceptDeclineInvitePresenterTest {
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom(
|
||||||
leaveRoomLambda = declineInviteSuccess
|
leaveRoomLambda = declineInviteSuccess
|
||||||
}
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val presenter = createAcceptDeclineInvitePresenter(
|
val presenter = createAcceptDeclineInvitePresenter(
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,9 @@ class DefaultLeaveRoomPresenterTest {
|
||||||
client = FakeMatrixClient().apply {
|
client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom(),
|
result = FakeMatrixRoom(
|
||||||
|
leaveRoomLambda = { Result.success(Unit) }
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
roomMembershipObserver = roomMembershipObserver
|
roomMembershipObserver = roomMembershipObserver
|
||||||
|
|
@ -162,9 +164,9 @@ class DefaultLeaveRoomPresenterTest {
|
||||||
client = FakeMatrixClient().apply {
|
client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom(
|
||||||
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
||||||
},
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -186,7 +188,9 @@ class DefaultLeaveRoomPresenterTest {
|
||||||
client = FakeMatrixClient().apply {
|
client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom(),
|
result = FakeMatrixRoom(
|
||||||
|
leaveRoomLambda = { Result.success(Unit) }
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -208,9 +212,9 @@ class DefaultLeaveRoomPresenterTest {
|
||||||
client = FakeMatrixClient().apply {
|
client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(
|
givenGetRoomResult(
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
result = FakeMatrixRoom().apply {
|
result = FakeMatrixRoom(
|
||||||
this.leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
leaveRoomLambda = { Result.failure(RuntimeException("Blimey!")) }
|
||||||
},
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,15 @@ import io.element.android.features.location.impl.common.permissions.PermissionsE
|
||||||
import io.element.android.features.location.impl.common.permissions.PermissionsPresenter
|
import io.element.android.features.location.impl.common.permissions.PermissionsPresenter
|
||||||
import io.element.android.features.location.impl.common.permissions.PermissionsState
|
import io.element.android.features.location.impl.common.permissions.PermissionsState
|
||||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||||
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.room.SendLocationInvocation
|
|
||||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||||
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.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
|
|
@ -46,16 +48,18 @@ class SendLocationPresenterTest {
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
private val fakePermissionsPresenter = FakePermissionsPresenter()
|
private val fakePermissionsPresenter = FakePermissionsPresenter()
|
||||||
private val fakeMatrixRoom = FakeMatrixRoom()
|
|
||||||
private val fakeAnalyticsService = FakeAnalyticsService()
|
private val fakeAnalyticsService = FakeAnalyticsService()
|
||||||
private val fakeMessageComposerContext = FakeMessageComposerContext()
|
private val fakeMessageComposerContext = FakeMessageComposerContext()
|
||||||
private val fakeLocationActions = FakeLocationActions()
|
private val fakeLocationActions = FakeLocationActions()
|
||||||
private val fakeBuildMeta = aBuildMeta(applicationName = "app name")
|
private val fakeBuildMeta = aBuildMeta(applicationName = "app name")
|
||||||
private val sendLocationPresenter: SendLocationPresenter = SendLocationPresenter(
|
|
||||||
|
private fun createSendLocationPresenter(
|
||||||
|
matrixRoom: MatrixRoom = FakeMatrixRoom(),
|
||||||
|
): SendLocationPresenter = SendLocationPresenter(
|
||||||
permissionsPresenterFactory = object : PermissionsPresenter.Factory {
|
permissionsPresenterFactory = object : PermissionsPresenter.Factory {
|
||||||
override fun create(permissions: List<String>): PermissionsPresenter = fakePermissionsPresenter
|
override fun create(permissions: List<String>): PermissionsPresenter = fakePermissionsPresenter
|
||||||
},
|
},
|
||||||
room = fakeMatrixRoom,
|
room = matrixRoom,
|
||||||
analyticsService = fakeAnalyticsService,
|
analyticsService = fakeAnalyticsService,
|
||||||
messageComposerContext = fakeMessageComposerContext,
|
messageComposerContext = fakeMessageComposerContext,
|
||||||
locationActions = fakeLocationActions,
|
locationActions = fakeLocationActions,
|
||||||
|
|
@ -64,6 +68,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initial state with permissions granted`() = runTest {
|
fun `initial state with permissions granted`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.AllGranted,
|
permissions = PermissionsState.Permissions.AllGranted,
|
||||||
|
|
@ -90,6 +95,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initial state with permissions partially granted`() = runTest {
|
fun `initial state with permissions partially granted`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.SomeGranted,
|
permissions = PermissionsState.Permissions.SomeGranted,
|
||||||
|
|
@ -116,6 +122,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initial state with permissions denied`() = runTest {
|
fun `initial state with permissions denied`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -142,6 +149,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initial state with permissions denied once`() = runTest {
|
fun `initial state with permissions denied once`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -168,6 +176,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `rationale dialog dismiss`() = runTest {
|
fun `rationale dialog dismiss`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -199,6 +208,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `rationale dialog continue`() = runTest {
|
fun `rationale dialog continue`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -227,6 +237,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `permission denied dialog dismiss`() = runTest {
|
fun `permission denied dialog dismiss`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -258,6 +269,13 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `share sender location`() = runTest {
|
fun `share sender location`() = runTest {
|
||||||
|
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendLocationResult = sendLocationResult,
|
||||||
|
)
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.AllGranted,
|
permissions = PermissionsState.Permissions.AllGranted,
|
||||||
|
|
@ -289,16 +307,14 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
delay(1) // Wait for the coroutine to finish
|
delay(1) // Wait for the coroutine to finish
|
||||||
|
|
||||||
assertThat(fakeMatrixRoom.sentLocations.size).isEqualTo(1)
|
sendLocationResult.assertions().isCalledOnce()
|
||||||
assertThat(fakeMatrixRoom.sentLocations.last()).isEqualTo(
|
.with(
|
||||||
SendLocationInvocation(
|
value("Location was shared at geo:3.0,4.0;u=5.0"),
|
||||||
body = "Location was shared at geo:3.0,4.0;u=5.0",
|
value("geo:3.0,4.0;u=5.0"),
|
||||||
geoUri = "geo:3.0,4.0;u=5.0",
|
value(null),
|
||||||
description = null,
|
value(15),
|
||||||
zoomLevel = 15,
|
value(AssetType.SENDER),
|
||||||
assetType = AssetType.SENDER
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
|
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.last()).isEqualTo(
|
assertThat(fakeAnalyticsService.capturedEvents.last()).isEqualTo(
|
||||||
|
|
@ -314,6 +330,13 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `share pin location`() = runTest {
|
fun `share pin location`() = runTest {
|
||||||
|
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendLocationResult = sendLocationResult,
|
||||||
|
)
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -345,16 +368,14 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
delay(1) // Wait for the coroutine to finish
|
delay(1) // Wait for the coroutine to finish
|
||||||
|
|
||||||
assertThat(fakeMatrixRoom.sentLocations.size).isEqualTo(1)
|
sendLocationResult.assertions().isCalledOnce()
|
||||||
assertThat(fakeMatrixRoom.sentLocations.last()).isEqualTo(
|
.with(
|
||||||
SendLocationInvocation(
|
value("Location was shared at geo:0.0,1.0"),
|
||||||
body = "Location was shared at geo:0.0,1.0",
|
value("geo:0.0,1.0"),
|
||||||
geoUri = "geo:0.0,1.0",
|
value(null),
|
||||||
description = null,
|
value(15),
|
||||||
zoomLevel = 15,
|
value(AssetType.PIN),
|
||||||
assetType = AssetType.PIN
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
|
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(1)
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.last()).isEqualTo(
|
assertThat(fakeAnalyticsService.capturedEvents.last()).isEqualTo(
|
||||||
|
|
@ -370,6 +391,13 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `composer context passes through analytics`() = runTest {
|
fun `composer context passes through analytics`() = runTest {
|
||||||
|
val sendLocationResult = lambdaRecorder<String, String, String?, Int?, AssetType?, Result<Unit>> { _, _, _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendLocationResult = sendLocationResult,
|
||||||
|
)
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter(matrixRoom)
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -418,6 +446,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `open settings activity`() = runTest {
|
fun `open settings activity`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
fakePermissionsPresenter.givenState(
|
fakePermissionsPresenter.givenState(
|
||||||
aPermissionsState(
|
aPermissionsState(
|
||||||
permissions = PermissionsState.Permissions.NoneGranted,
|
permissions = PermissionsState.Permissions.NoneGranted,
|
||||||
|
|
@ -452,6 +481,7 @@ class SendLocationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `application name is in state`() = runTest {
|
fun `application name is in state`() = runTest {
|
||||||
|
val sendLocationPresenter = createSendLocationPresenter()
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
sendLocationPresenter.present()
|
sendLocationPresenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
|
@ -103,6 +104,7 @@ import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||||
import io.element.android.tests.testutils.consumeItemsUntilTimeout
|
import io.element.android.tests.testutils.consumeItemsUntilTimeout
|
||||||
import io.element.android.tests.testutils.lambda.assert
|
import io.element.android.tests.testutils.lambda.assert
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.element.android.tests.testutils.lambda.value
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
|
|
@ -136,7 +138,7 @@ class MessagesPresenterTest {
|
||||||
assertThat(initialState.roomAvatar)
|
assertThat(initialState.roomAvatar)
|
||||||
.isEqualTo(AsyncData.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)))
|
.isEqualTo(AsyncData.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)))
|
||||||
assertThat(initialState.userHasPermissionToSendMessage).isTrue()
|
assertThat(initialState.userHasPermissionToSendMessage).isTrue()
|
||||||
assertThat(initialState.userHasPermissionToRedactOwn).isFalse()
|
assertThat(initialState.userHasPermissionToRedactOwn).isTrue()
|
||||||
assertThat(initialState.hasNetworkConnection).isTrue()
|
assertThat(initialState.hasNetworkConnection).isTrue()
|
||||||
assertThat(initialState.snackbarMessage).isNull()
|
assertThat(initialState.snackbarMessage).isNull()
|
||||||
assertThat(initialState.inviteProgress).isEqualTo(AsyncData.Uninitialized)
|
assertThat(initialState.inviteProgress).isEqualTo(AsyncData.Uninitialized)
|
||||||
|
|
@ -147,7 +149,13 @@ class MessagesPresenterTest {
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@Test
|
@Test
|
||||||
fun `present - check that the room's unread flag is removed`() = runTest {
|
fun `present - check that the room's unread flag is removed`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
assertThat(room.markAsReadCalls).isEmpty()
|
assertThat(room.markAsReadCalls).isEmpty()
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -161,8 +169,13 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest {
|
fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanUserJoinCall(Result.success(false))
|
canUserJoinCallResult = { Result.success(false) },
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
).apply {
|
||||||
givenRoomInfo(aRoomInfo(hasRoomCall = true))
|
givenRoomInfo(aRoomInfo(hasRoomCall = true))
|
||||||
}
|
}
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
|
|
@ -183,7 +196,14 @@ class MessagesPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
}
|
}
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -213,7 +233,14 @@ class MessagesPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
}
|
}
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -266,6 +293,11 @@ class MessagesPresenterTest {
|
||||||
val event = aMessageEvent()
|
val event = aMessageEvent()
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
eventPermalinkResult = { Result.success("a link") },
|
eventPermalinkResult = { Result.success("a link") },
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(
|
val presenter = createMessagesPresenter(
|
||||||
clipboardHelper = clipboardHelper,
|
clipboardHelper = clipboardHelper,
|
||||||
|
|
@ -448,7 +480,14 @@ class MessagesPresenterTest {
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
|
|
||||||
val liveTimeline = FakeTimeline()
|
val liveTimeline = FakeTimeline()
|
||||||
val matrixRoom = FakeMatrixRoom(liveTimeline = liveTimeline)
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
liveTimeline = liveTimeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
|
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) }
|
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) }
|
||||||
liveTimeline.redactEventLambda = redactEventLambda
|
liveTimeline.redactEventLambda = redactEventLambda
|
||||||
|
|
@ -513,7 +552,16 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - shows prompt to reinvite users in DM`() = runTest {
|
fun `present - shows prompt to reinvite users in DM`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID, isDirect = true, activeMemberCount = 1L)
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
isDirect = true,
|
||||||
|
activeMemberCount = 1L,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -539,7 +587,16 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - doesn't show reinvite prompt in non-direct room`() = runTest {
|
fun `present - doesn't show reinvite prompt in non-direct room`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID, isDirect = false, activeMemberCount = 1L)
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
isDirect = false,
|
||||||
|
activeMemberCount = 1L,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -554,7 +611,16 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - doesn't show reinvite prompt if other party is present`() = runTest {
|
fun `present - doesn't show reinvite prompt if other party is present`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID, isDirect = true, activeMemberCount = 2L)
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
isDirect = true,
|
||||||
|
activeMemberCount = 2L,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -569,7 +635,16 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle reinviting other user when memberlist is ready`() = runTest {
|
fun `present - handle reinviting other user when memberlist is ready`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
inviteUserResult = inviteUserResult,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
|
|
@ -589,13 +664,22 @@ class MessagesPresenterTest {
|
||||||
assertThat(loadingState.inviteProgress.isLoading()).isTrue()
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue()
|
||||||
val newState = awaitItem()
|
val newState = awaitItem()
|
||||||
assertThat(newState.inviteProgress.isSuccess()).isTrue()
|
assertThat(newState.inviteProgress.isSuccess()).isTrue()
|
||||||
assertThat(room.invitedUserId).isEqualTo(A_SESSION_ID_2)
|
inviteUserResult.assertions().isCalledOnce().with(value(A_SESSION_ID_2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle reinviting other user when memberlist is error`() = runTest {
|
fun `present - handle reinviting other user when memberlist is error`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
val inviteUserResult = lambdaRecorder { _: UserId -> Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
inviteUserResult = inviteUserResult,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Error(
|
MatrixRoomMembersState.Error(
|
||||||
failure = Throwable(),
|
failure = Throwable(),
|
||||||
|
|
@ -618,13 +702,20 @@ class MessagesPresenterTest {
|
||||||
assertThat(loadingState.inviteProgress.isLoading()).isTrue()
|
assertThat(loadingState.inviteProgress.isLoading()).isTrue()
|
||||||
val newState = awaitItem()
|
val newState = awaitItem()
|
||||||
assertThat(newState.inviteProgress.isSuccess()).isTrue()
|
assertThat(newState.inviteProgress.isSuccess()).isTrue()
|
||||||
assertThat(room.invitedUserId).isEqualTo(A_SESSION_ID_2)
|
inviteUserResult.assertions().isCalledOnce().with(value(A_SESSION_ID_2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle reinviting other user when memberlist is not ready`() = runTest {
|
fun `present - handle reinviting other user when memberlist is not ready`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
room.givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
room.givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -642,7 +733,15 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle reinviting other user when inviting fails`() = runTest {
|
fun `present - handle reinviting other user when inviting fails`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
val room = FakeMatrixRoom(
|
||||||
|
sessionId = A_SESSION_ID,
|
||||||
|
inviteUserResult = { Result.failure(Throwable("Oops!")) },
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
|
|
@ -651,7 +750,6 @@ class MessagesPresenterTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
room.givenInviteUserResult(Result.failure(Throwable("Oops!")))
|
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -671,8 +769,19 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - permission to post`() = runTest {
|
fun `present - permission to post`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom()
|
val matrixRoom = FakeMatrixRoom(
|
||||||
matrixRoom.givenCanSendEventResult(MessageEventType.ROOM_MESSAGE, Result.success(true))
|
canUserSendMessageResult = { _, messageEventType ->
|
||||||
|
when (messageEventType) {
|
||||||
|
MessageEventType.ROOM_MESSAGE -> Result.success(true)
|
||||||
|
MessageEventType.REACTION -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -684,8 +793,19 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - no permission to post`() = runTest {
|
fun `present - no permission to post`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom()
|
val matrixRoom = FakeMatrixRoom(
|
||||||
matrixRoom.givenCanSendEventResult(MessageEventType.ROOM_MESSAGE, Result.success(false))
|
canUserSendMessageResult = { _, messageEventType ->
|
||||||
|
when (messageEventType) {
|
||||||
|
MessageEventType.ROOM_MESSAGE -> Result.success(false)
|
||||||
|
MessageEventType.REACTION -> Result.success(false)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -700,7 +820,13 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - permission to redact own`() = runTest {
|
fun `present - permission to redact own`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom(canRedactOwn = true)
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(false) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -714,7 +840,13 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - permission to redact other`() = runTest {
|
fun `present - permission to redact other`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom(canRedactOther = true)
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(false) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -754,7 +886,13 @@ class MessagesPresenterTest {
|
||||||
|
|
||||||
private fun TestScope.createMessagesPresenter(
|
private fun TestScope.createMessagesPresenter(
|
||||||
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||||
matrixRoom: MatrixRoom = FakeMatrixRoom().apply {
|
matrixRoom: MatrixRoom = FakeMatrixRoom(
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
canRedactOwnResult = { Result.success(true) },
|
||||||
|
canRedactOtherResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
).apply {
|
||||||
givenRoomInfo(aRoomInfo(id = roomId, name = ""))
|
givenRoomInfo(aRoomInfo(id = roomId, name = ""))
|
||||||
},
|
},
|
||||||
navigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
navigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewEvents
|
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewEvents
|
||||||
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewPresenter
|
import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewPresenter
|
||||||
import io.element.android.features.messages.impl.attachments.preview.SendActionState
|
import io.element.android.features.messages.impl.attachments.preview.SendActionState
|
||||||
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||||
import io.element.android.libraries.mediaupload.api.MediaSender
|
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||||
|
|
@ -34,6 +36,7 @@ import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||||
import io.element.android.libraries.mediaviewer.test.viewer.aLocalMedia
|
import io.element.android.libraries.mediaviewer.test.viewer.aLocalMedia
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
|
@ -49,13 +52,16 @@ class AttachmentsPreviewPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - send media success scenario`() = runTest {
|
fun `present - send media success scenario`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val sendMediaResult = lambdaRecorder<ProgressCallback?, Result<FakeMediaUploadHandler>> {
|
||||||
room.givenProgressCallbackValues(
|
Result.success(FakeMediaUploadHandler())
|
||||||
listOf(
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
progressCallbackValues = listOf(
|
||||||
Pair(0, 10),
|
Pair(0, 10),
|
||||||
Pair(5, 10),
|
Pair(5, 10),
|
||||||
Pair(10, 10)
|
Pair(10, 10)
|
||||||
)
|
),
|
||||||
|
sendMediaResult = sendMediaResult,
|
||||||
)
|
)
|
||||||
val presenter = createAttachmentsPreviewPresenter(room = room)
|
val presenter = createAttachmentsPreviewPresenter(room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -70,15 +76,19 @@ class AttachmentsPreviewPresenterTest {
|
||||||
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(1f))
|
assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Uploading(1f))
|
||||||
val successState = awaitItem()
|
val successState = awaitItem()
|
||||||
assertThat(successState.sendActionState).isEqualTo(SendActionState.Done)
|
assertThat(successState.sendActionState).isEqualTo(SendActionState.Done)
|
||||||
assertThat(room.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - send media failure scenario`() = runTest {
|
fun `present - send media failure scenario`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
|
||||||
val failure = MediaPreProcessor.Failure(null)
|
val failure = MediaPreProcessor.Failure(null)
|
||||||
room.givenSendMediaResult(Result.failure(failure))
|
val sendMediaResult = lambdaRecorder<ProgressCallback?, Result<FakeMediaUploadHandler>> {
|
||||||
|
Result.failure(failure)
|
||||||
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
sendMediaResult = sendMediaResult,
|
||||||
|
)
|
||||||
val presenter = createAttachmentsPreviewPresenter(room = room)
|
val presenter = createAttachmentsPreviewPresenter(room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -90,7 +100,7 @@ class AttachmentsPreviewPresenterTest {
|
||||||
assertThat(loadingState.sendActionState).isEqualTo(SendActionState.Sending.Processing)
|
assertThat(loadingState.sendActionState).isEqualTo(SendActionState.Sending.Processing)
|
||||||
val failureState = awaitItem()
|
val failureState = awaitItem()
|
||||||
assertThat(failureState.sendActionState).isEqualTo(SendActionState.Failure(failure))
|
assertThat(failureState.sendActionState).isEqualTo(SendActionState.Failure(failure))
|
||||||
assertThat(room.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
failureState.eventSink(AttachmentsPreviewEvents.ClearSendState)
|
failureState.eventSink(AttachmentsPreviewEvents.ClearSendState)
|
||||||
val clearedState = awaitItem()
|
val clearedState = awaitItem()
|
||||||
assertThat(clearedState.sendActionState).isEqualTo(SendActionState.Idle)
|
assertThat(clearedState.sendActionState).isEqualTo(SendActionState.Idle)
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,14 @@ import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
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.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
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.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -81,7 +84,12 @@ class ReportMessagePresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `presenter - handle successful report and block user`() = runTest {
|
fun `presenter - handle successful report and block user`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
reportContentResult = reportContentResult
|
||||||
|
)
|
||||||
val presenter = createReportMessagePresenter(matrixRoom = room)
|
val presenter = createReportMessagePresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -92,13 +100,18 @@ class ReportMessagePresenterTest {
|
||||||
initialState.eventSink(ReportMessageEvents.Report)
|
initialState.eventSink(ReportMessageEvents.Report)
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
|
||||||
assertThat(room.reportedContentCount).isEqualTo(1)
|
reportContentResult.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `presenter - handle successful report`() = runTest {
|
fun `presenter - handle successful report`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
reportContentResult = reportContentResult
|
||||||
|
)
|
||||||
val presenter = createReportMessagePresenter(matrixRoom = room)
|
val presenter = createReportMessagePresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -107,15 +120,18 @@ class ReportMessagePresenterTest {
|
||||||
initialState.eventSink(ReportMessageEvents.Report)
|
initialState.eventSink(ReportMessageEvents.Report)
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
|
||||||
assertThat(room.reportedContentCount).isEqualTo(1)
|
reportContentResult.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `presenter - handle failed report`() = runTest {
|
fun `presenter - handle failed report`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val reportContentResult = lambdaRecorder<EventId, String, UserId?, Result<Unit>> { _, _, _ ->
|
||||||
givenReportContentResult(Result.failure(Exception("Failed to report content")))
|
Result.failure(Exception("Failed to report content"))
|
||||||
}
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
reportContentResult = reportContentResult
|
||||||
|
)
|
||||||
val presenter = createReportMessagePresenter(matrixRoom = room)
|
val presenter = createReportMessagePresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -125,7 +141,7 @@ class ReportMessagePresenterTest {
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItem()
|
||||||
assertThat(resultState.result).isInstanceOf(AsyncAction.Failure::class.java)
|
assertThat(resultState.result).isInstanceOf(AsyncAction.Failure::class.java)
|
||||||
assertThat(room.reportedContentCount).isEqualTo(1)
|
reportContentResult.assertions().isCalledOnce()
|
||||||
|
|
||||||
resultState.eventSink(ReportMessageEvents.ClearError)
|
resultState.eventSink(ReportMessageEvents.ClearError)
|
||||||
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
assertThat(awaitItem().result).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ 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.featureflag.test.FakeFeatureFlagService
|
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
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.core.TransactionId
|
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||||
import io.element.android.libraries.matrix.api.media.ImageInfo
|
import io.element.android.libraries.matrix.api.media.ImageInfo
|
||||||
|
|
@ -67,6 +68,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID_3
|
import io.element.android.libraries.matrix.test.A_USER_ID_3
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID_4
|
import io.element.android.libraries.matrix.test.A_USER_ID_4
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
|
import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder
|
||||||
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
|
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
|
|
@ -297,7 +299,13 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - send message with rich text enabled`() = runTest {
|
fun `present - send message with rich text enabled`() = runTest {
|
||||||
val presenter = createPresenter(this)
|
val presenter = createPresenter(
|
||||||
|
coroutineScope = this,
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
remember(state, state.textEditorState.messageHtml()) { state }
|
remember(state, state.textEditorState.messageHtml()) { state }
|
||||||
|
|
@ -324,7 +332,14 @@ class MessageComposerPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - send message with plain text enabled`() = runTest {
|
fun `present - send message with plain text enabled`() = runTest {
|
||||||
val permalinkBuilder = FakePermalinkBuilder(permalinkForUserLambda = { Result.success("") })
|
val permalinkBuilder = FakePermalinkBuilder(permalinkForUserLambda = { Result.success("") })
|
||||||
val presenter = createPresenter(this, isRichTextEditorEnabled = false)
|
val presenter = createPresenter(
|
||||||
|
coroutineScope = this,
|
||||||
|
isRichTextEditorEnabled = false,
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
val state = presenter.present()
|
val state = presenter.present()
|
||||||
val messageMarkdown = state.textEditorState.messageMarkdown(permalinkBuilder)
|
val messageMarkdown = state.textEditorState.messageMarkdown(permalinkBuilder)
|
||||||
|
|
@ -358,7 +373,10 @@ class MessageComposerPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.editMessageLambda = editMessageLambda
|
this.editMessageLambda = editMessageLambda
|
||||||
}
|
}
|
||||||
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
|
val fakeMatrixRoom = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
fakeMatrixRoom,
|
fakeMatrixRoom,
|
||||||
|
|
@ -407,7 +425,10 @@ class MessageComposerPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.editMessageLambda = editMessageLambda
|
this.editMessageLambda = editMessageLambda
|
||||||
}
|
}
|
||||||
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
|
val fakeMatrixRoom = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
fakeMatrixRoom,
|
fakeMatrixRoom,
|
||||||
|
|
@ -456,7 +477,10 @@ class MessageComposerPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.replyMessageLambda = replyMessageLambda
|
this.replyMessageLambda = replyMessageLambda
|
||||||
}
|
}
|
||||||
val fakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline)
|
val fakeMatrixRoom = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
fakeMatrixRoom,
|
fakeMatrixRoom,
|
||||||
|
|
@ -524,7 +548,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Pick image from gallery`() = runTest {
|
fun `present - Pick image from gallery`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
pickerProvider.givenMimeType(MimeTypes.Images)
|
pickerProvider.givenMimeType(MimeTypes.Images)
|
||||||
mediaPreProcessor.givenResult(
|
mediaPreProcessor.givenResult(
|
||||||
|
|
@ -557,7 +583,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Pick video from gallery`() = runTest {
|
fun `present - Pick video from gallery`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
pickerProvider.givenMimeType(MimeTypes.Videos)
|
pickerProvider.givenMimeType(MimeTypes.Videos)
|
||||||
mediaPreProcessor.givenResult(
|
mediaPreProcessor.givenResult(
|
||||||
|
|
@ -607,13 +635,17 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Pick file from storage`() = runTest {
|
fun `present - Pick file from storage`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val sendMediaResult = lambdaRecorder { _: ProgressCallback? ->
|
||||||
room.givenProgressCallbackValues(
|
Result.success(FakeMediaUploadHandler())
|
||||||
listOf(
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
progressCallbackValues = listOf(
|
||||||
Pair(0, 10),
|
Pair(0, 10),
|
||||||
Pair(5, 10),
|
Pair(5, 10),
|
||||||
Pair(10, 10)
|
Pair(10, 10)
|
||||||
)
|
),
|
||||||
|
sendMediaResult = sendMediaResult,
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
)
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -629,13 +661,15 @@ class MessageComposerPresenterTest {
|
||||||
assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(1f))
|
assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(1f))
|
||||||
val sentState = awaitItem()
|
val sentState = awaitItem()
|
||||||
assertThat(sentState.attachmentsState).isEqualTo(AttachmentsState.None)
|
assertThat(sentState.attachmentsState).isEqualTo(AttachmentsState.None)
|
||||||
assertThat(room.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - create poll`() = runTest {
|
fun `present - create poll`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -652,7 +686,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - share location`() = runTest {
|
fun `present - share location`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -669,7 +705,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Take photo`() = runTest {
|
fun `present - Take photo`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
|
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
|
|
@ -689,7 +727,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Take photo with permission request`() = runTest {
|
fun `present - Take photo with permission request`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val permissionPresenter = FakePermissionsPresenter()
|
val permissionPresenter = FakePermissionsPresenter()
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
|
|
@ -714,7 +754,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Record video`() = runTest {
|
fun `present - Record video`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
|
val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() }
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
|
|
@ -734,7 +776,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Record video with permission request`() = runTest {
|
fun `present - Record video with permission request`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val permissionPresenter = FakePermissionsPresenter()
|
val permissionPresenter = FakePermissionsPresenter()
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
this,
|
this,
|
||||||
|
|
@ -759,9 +803,10 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Uploading media failure can be recovered from`() = runTest {
|
fun `present - Uploading media failure can be recovered from`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenSendMediaResult(Result.failure(Exception()))
|
sendMediaResult = { Result.failure(Exception()) },
|
||||||
}
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(this, room = room)
|
val presenter = createPresenter(this, room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -842,15 +887,17 @@ class MessageComposerPresenterTest {
|
||||||
val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE)
|
val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE)
|
||||||
val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN)
|
val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN)
|
||||||
val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN)
|
val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN)
|
||||||
|
var canUserTriggerRoomNotificationResult = true
|
||||||
val room = FakeMatrixRoom(
|
val room = FakeMatrixRoom(
|
||||||
isDirect = false,
|
isDirect = false,
|
||||||
|
canUserTriggerRoomNotificationResult = { Result.success(canUserTriggerRoomNotificationResult) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
).apply {
|
).apply {
|
||||||
givenRoomMembersState(
|
givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(currentUser, invitedUser, bob, david),
|
persistentListOf(currentUser, invitedUser, bob, david),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
givenCanTriggerRoomNotification(Result.success(true))
|
|
||||||
}
|
}
|
||||||
val flagsService = FakeFeatureFlagService(
|
val flagsService = FakeFeatureFlagService(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
|
@ -890,13 +937,10 @@ class MessageComposerPresenterTest {
|
||||||
assertThat(awaitItem().memberSuggestions).isEmpty()
|
assertThat(awaitItem().memberSuggestions).isEmpty()
|
||||||
|
|
||||||
// If user has no permission to send `@room` mentions, `RoomMemberSuggestion.Room` is not returned
|
// If user has no permission to send `@room` mentions, `RoomMemberSuggestion.Room` is not returned
|
||||||
room.givenCanTriggerRoomNotification(Result.success(false))
|
canUserTriggerRoomNotificationResult = false
|
||||||
initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "")))
|
initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "")))
|
||||||
assertThat(awaitItem().memberSuggestions)
|
assertThat(awaitItem().memberSuggestions)
|
||||||
.containsExactly(ResolvedMentionSuggestion.Member(bob), ResolvedMentionSuggestion.Member(david))
|
.containsExactly(ResolvedMentionSuggestion.Member(bob), ResolvedMentionSuggestion.Member(david))
|
||||||
|
|
||||||
// If room is a DM, `RoomMemberSuggestion.Room` is not returned
|
|
||||||
room.givenCanTriggerRoomNotification(Result.success(true))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -910,13 +954,14 @@ class MessageComposerPresenterTest {
|
||||||
isDirect = true,
|
isDirect = true,
|
||||||
activeMemberCount = 2,
|
activeMemberCount = 2,
|
||||||
isEncrypted = true,
|
isEncrypted = true,
|
||||||
|
canUserTriggerRoomNotificationResult = { Result.success(true) },
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
).apply {
|
).apply {
|
||||||
givenRoomMembersState(
|
givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(currentUser, invitedUser, bob, david),
|
persistentListOf(currentUser, invitedUser, bob, david),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
givenCanTriggerRoomNotification(Result.success(true))
|
|
||||||
}
|
}
|
||||||
val flagsService = FakeFeatureFlagService(
|
val flagsService = FakeFeatureFlagService(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
|
@ -973,7 +1018,14 @@ class MessageComposerPresenterTest {
|
||||||
this.replyMessageLambda = replyMessageLambda
|
this.replyMessageLambda = replyMessageLambda
|
||||||
this.editMessageLambda = editMessageLambda
|
this.editMessageLambda = editMessageLambda
|
||||||
}
|
}
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
val sendMessageResult = lambdaRecorder { _: String, _: String?, _: List<Mention> ->
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
sendMessageResult = sendMessageResult,
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
val presenter = createPresenter(room = room, coroutineScope = this)
|
val presenter = createPresenter(room = room, coroutineScope = this)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -993,7 +1045,8 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
assertThat(room.sendMessageMentions).isEqualTo(listOf(Mention.User(A_USER_ID)))
|
sendMessageResult.assertions().isCalledOnce()
|
||||||
|
.with(value(A_MESSAGE), any(), value(listOf(Mention.User(A_USER_ID))))
|
||||||
|
|
||||||
// Check intentional mentions on reply sent
|
// Check intentional mentions on reply sent
|
||||||
initialState.eventSink(MessageComposerEvents.SetMode(aReplyMode()))
|
initialState.eventSink(MessageComposerEvents.SetMode(aReplyMode()))
|
||||||
|
|
@ -1049,22 +1102,32 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle typing notice event`() = runTest {
|
fun `present - handle typing notice event`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val typingNoticeResult = lambdaRecorder<Boolean, Result<Unit>> { Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = typingNoticeResult
|
||||||
|
)
|
||||||
val presenter = createPresenter(room = room, coroutineScope = this)
|
val presenter = createPresenter(room = room, coroutineScope = this)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(room.typingRecord).isEmpty()
|
typingNoticeResult.assertions().isNeverCalled()
|
||||||
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true))
|
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true))
|
||||||
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false))
|
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false))
|
||||||
assertThat(room.typingRecord).isEqualTo(listOf(true, false))
|
typingNoticeResult.assertions().isCalledExactly(2)
|
||||||
|
.withSequence(
|
||||||
|
listOf(value(true)),
|
||||||
|
listOf(value(false)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle typing notice event when sending typing notice is disabled`() = runTest {
|
fun `present - handle typing notice event when sending typing notice is disabled`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val typingNoticeResult = lambdaRecorder<Boolean, Result<Unit>> { Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = typingNoticeResult
|
||||||
|
)
|
||||||
val store = InMemorySessionPreferencesStore(
|
val store = InMemorySessionPreferencesStore(
|
||||||
isSendTypingNotificationsEnabled = false
|
isSendTypingNotificationsEnabled = false
|
||||||
)
|
)
|
||||||
|
|
@ -1073,10 +1136,10 @@ class MessageComposerPresenterTest {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
assertThat(room.typingRecord).isEmpty()
|
typingNoticeResult.assertions().isNeverCalled()
|
||||||
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true))
|
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true))
|
||||||
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false))
|
initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false))
|
||||||
assertThat(room.typingRecord).isEmpty()
|
typingNoticeResult.assertions().isNeverCalled()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1215,7 +1278,10 @@ class MessageComposerPresenterTest {
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.loadReplyDetailsLambda = loadReplyDetailsLambda
|
this.loadReplyDetailsLambda = loadReplyDetailsLambda
|
||||||
}
|
}
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
|
)
|
||||||
val permalinkBuilder = FakePermalinkBuilder()
|
val permalinkBuilder = FakePermalinkBuilder()
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
room = room,
|
room = room,
|
||||||
|
|
@ -1352,7 +1418,9 @@ class MessageComposerPresenterTest {
|
||||||
|
|
||||||
private fun createPresenter(
|
private fun createPresenter(
|
||||||
coroutineScope: CoroutineScope,
|
coroutineScope: CoroutineScope,
|
||||||
room: MatrixRoom = FakeMatrixRoom(),
|
room: MatrixRoom = FakeMatrixRoom(
|
||||||
|
typingNoticeResult = { Result.success(Unit) }
|
||||||
|
),
|
||||||
pickerProvider: PickerProvider = this.pickerProvider,
|
pickerProvider: PickerProvider = this.pickerProvider,
|
||||||
featureFlagService: FeatureFlagService = this.featureFlagService,
|
featureFlagService: FeatureFlagService = this.featureFlagService,
|
||||||
sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(),
|
sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(),
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import io.element.android.libraries.matrix.test.A_UNIQUE_ID
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
@ -38,9 +39,9 @@ class TimelineControllerTest {
|
||||||
val liveTimeline = FakeTimeline(name = "live")
|
val liveTimeline = FakeTimeline(name = "live")
|
||||||
val detachedTimeline = FakeTimeline(name = "detached")
|
val detachedTimeline = FakeTimeline(name = "detached")
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
timelineFocusedOnEventResult = { Result.success(detachedTimeline) }
|
||||||
)
|
)
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline))
|
|
||||||
val sut = TimelineController(matrixRoom)
|
val sut = TimelineController(matrixRoom)
|
||||||
|
|
||||||
sut.activeTimelineFlow().test {
|
sut.activeTimelineFlow().test {
|
||||||
|
|
@ -68,8 +69,17 @@ class TimelineControllerTest {
|
||||||
val liveTimeline = FakeTimeline(name = "live")
|
val liveTimeline = FakeTimeline(name = "live")
|
||||||
val detachedTimeline1 = FakeTimeline(name = "detached 1")
|
val detachedTimeline1 = FakeTimeline(name = "detached 1")
|
||||||
val detachedTimeline2 = FakeTimeline(name = "detached 2")
|
val detachedTimeline2 = FakeTimeline(name = "detached 2")
|
||||||
|
var callNumber = 0
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
timelineFocusedOnEventResult = {
|
||||||
|
callNumber++
|
||||||
|
when (callNumber) {
|
||||||
|
1 -> Result.success(detachedTimeline1)
|
||||||
|
2 -> Result.success(detachedTimeline2)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
val sut = TimelineController(matrixRoom)
|
val sut = TimelineController(matrixRoom)
|
||||||
|
|
||||||
|
|
@ -77,7 +87,6 @@ class TimelineControllerTest {
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state).isEqualTo(liveTimeline)
|
assertThat(state).isEqualTo(liveTimeline)
|
||||||
}
|
}
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline1))
|
|
||||||
sut.focusOnEvent(AN_EVENT_ID)
|
sut.focusOnEvent(AN_EVENT_ID)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state).isEqualTo(detachedTimeline1)
|
assertThat(state).isEqualTo(detachedTimeline1)
|
||||||
|
|
@ -85,7 +94,6 @@ class TimelineControllerTest {
|
||||||
assertThat(detachedTimeline1.closeCounter).isEqualTo(0)
|
assertThat(detachedTimeline1.closeCounter).isEqualTo(0)
|
||||||
assertThat(detachedTimeline2.closeCounter).isEqualTo(0)
|
assertThat(detachedTimeline2.closeCounter).isEqualTo(0)
|
||||||
// Focus on another event should close the previous detached timeline
|
// Focus on another event should close the previous detached timeline
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline2))
|
|
||||||
sut.focusOnEvent(AN_EVENT_ID)
|
sut.focusOnEvent(AN_EVENT_ID)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state).isEqualTo(detachedTimeline2)
|
assertThat(state).isEqualTo(detachedTimeline2)
|
||||||
|
|
@ -117,11 +125,10 @@ class TimelineControllerTest {
|
||||||
val liveTimeline = FakeTimeline(name = "live")
|
val liveTimeline = FakeTimeline(name = "live")
|
||||||
val detachedTimeline = FakeTimeline(name = "detached")
|
val detachedTimeline = FakeTimeline(name = "detached")
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
timelineFocusedOnEventResult = { Result.success(detachedTimeline) }
|
||||||
)
|
)
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline))
|
|
||||||
val sut = TimelineController(matrixRoom)
|
val sut = TimelineController(matrixRoom)
|
||||||
|
|
||||||
sut.activeTimelineFlow().test {
|
sut.activeTimelineFlow().test {
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state).isEqualTo(liveTimeline)
|
assertThat(state).isEqualTo(liveTimeline)
|
||||||
|
|
@ -168,9 +175,9 @@ class TimelineControllerTest {
|
||||||
sendMessageLambda = lambdaForDetached
|
sendMessageLambda = lambdaForDetached
|
||||||
}
|
}
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
timelineFocusedOnEventResult = { Result.success(detachedTimeline) }
|
||||||
)
|
)
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline))
|
|
||||||
val sut = TimelineController(matrixRoom)
|
val sut = TimelineController(matrixRoom)
|
||||||
sut.activeTimelineFlow().test {
|
sut.activeTimelineFlow().test {
|
||||||
sut.focusOnEvent(AN_EVENT_ID)
|
sut.focusOnEvent(AN_EVENT_ID)
|
||||||
|
|
@ -193,9 +200,9 @@ class TimelineControllerTest {
|
||||||
val liveTimeline = FakeTimeline(name = "live")
|
val liveTimeline = FakeTimeline(name = "live")
|
||||||
val detachedTimeline = FakeTimeline(name = "detached")
|
val detachedTimeline = FakeTimeline(name = "detached")
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
timelineFocusedOnEventResult = { Result.success(detachedTimeline) }
|
||||||
)
|
)
|
||||||
matrixRoom.givenTimelineFocusedOnEventResult(Result.success(detachedTimeline))
|
|
||||||
val sut = TimelineController(matrixRoom)
|
val sut = TimelineController(matrixRoom)
|
||||||
|
|
||||||
sut.activeTimelineFlow().test {
|
sut.activeTimelineFlow().test {
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,10 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline)
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val sessionPreferencesStore = InMemorySessionPreferencesStore(isSendPublicReadReceiptsEnabled = false)
|
val sessionPreferencesStore = InMemorySessionPreferencesStore(isSendPublicReadReceiptsEnabled = false)
|
||||||
val presenter = createTimelinePresenter(
|
val presenter = createTimelinePresenter(
|
||||||
timeline = timeline,
|
timeline = timeline,
|
||||||
|
|
@ -482,9 +485,9 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
)
|
)
|
||||||
val room = FakeMatrixRoom(
|
val room = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline,
|
liveTimeline = liveTimeline,
|
||||||
).apply {
|
timelineFocusedOnEventResult = { Result.success(detachedTimeline) },
|
||||||
givenTimelineFocusedOnEventResult(Result.success(detachedTimeline))
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
}
|
)
|
||||||
val presenter = createTimelinePresenter(
|
val presenter = createTimelinePresenter(
|
||||||
room = room,
|
room = room,
|
||||||
)
|
)
|
||||||
|
|
@ -529,6 +532,7 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
),
|
),
|
||||||
timelineItemIndexer = timelineItemIndexer,
|
timelineItemIndexer = timelineItemIndexer,
|
||||||
)
|
)
|
||||||
|
|
@ -551,9 +555,9 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
liveTimeline = FakeTimeline(
|
liveTimeline = FakeTimeline(
|
||||||
timelineItems = flowOf(emptyList()),
|
timelineItems = flowOf(emptyList()),
|
||||||
),
|
),
|
||||||
).apply {
|
timelineFocusedOnEventResult = { Result.failure(Throwable("An error")) },
|
||||||
givenTimelineFocusedOnEventResult(Result.failure(Throwable("An error")))
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
},
|
)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -594,7 +598,10 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val room = FakeMatrixRoom(liveTimeline = timeline).apply {
|
val room = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -626,7 +633,10 @@ private const val FAKE_UNIQUE_ID_2 = "FAKE_UNIQUE_ID_2"
|
||||||
|
|
||||||
private fun TestScope.createTimelinePresenter(
|
private fun TestScope.createTimelinePresenter(
|
||||||
timeline: Timeline = FakeTimeline(),
|
timeline: Timeline = FakeTimeline(),
|
||||||
room: FakeMatrixRoom = FakeMatrixRoom(liveTimeline = timeline),
|
room: FakeMatrixRoom = FakeMatrixRoom(
|
||||||
|
liveTimeline = timeline,
|
||||||
|
canUserSendMessageResult = { _, _ -> Result.success(true) }
|
||||||
|
),
|
||||||
timelineItemsFactory: TimelineItemsFactory = aTimelineItemsFactory(),
|
timelineItemsFactory: TimelineItemsFactory = aTimelineItemsFactory(),
|
||||||
redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(),
|
redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(),
|
||||||
messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,9 @@ import com.google.common.truth.Truth.assertThat
|
||||||
import im.vector.app.features.analytics.plan.Composer
|
import im.vector.app.features.analytics.plan.Composer
|
||||||
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
|
import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
|
||||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||||
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails
|
||||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||||
|
|
@ -45,6 +47,7 @@ import io.element.android.libraries.textcomposer.model.VoiceMessageState
|
||||||
import io.element.android.libraries.voicerecorder.test.FakeVoiceRecorder
|
import io.element.android.libraries.voicerecorder.test.FakeVoiceRecorder
|
||||||
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.lambda.lambdaRecorder
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
|
@ -63,7 +66,10 @@ class VoiceMessageComposerPresenterTest {
|
||||||
recordingDuration = RECORDING_DURATION
|
recordingDuration = RECORDING_DURATION
|
||||||
)
|
)
|
||||||
private val analyticsService = FakeAnalyticsService()
|
private val analyticsService = FakeAnalyticsService()
|
||||||
private val matrixRoom = FakeMatrixRoom()
|
private val sendMediaResult = lambdaRecorder<ProgressCallback?, Result<FakeMediaUploadHandler>> { Result.success(FakeMediaUploadHandler()) }
|
||||||
|
private val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendMediaResult = sendMediaResult
|
||||||
|
)
|
||||||
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
|
private val mediaPreProcessor = FakeMediaPreProcessor().apply { givenAudioResult() }
|
||||||
private val mediaSender = MediaSender(mediaPreProcessor, matrixRoom)
|
private val mediaSender = MediaSender(mediaPreProcessor, matrixRoom)
|
||||||
private val messageComposerContext = FakeMessageComposerContext()
|
private val messageComposerContext = FakeMessageComposerContext()
|
||||||
|
|
@ -295,7 +301,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
|
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
||||||
|
|
||||||
testPauseAndDestroy(finalState)
|
testPauseAndDestroy(finalState)
|
||||||
|
|
@ -346,7 +352,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
|
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
||||||
|
|
||||||
testPauseAndDestroy(finalState)
|
testPauseAndDestroy(finalState)
|
||||||
|
|
@ -369,7 +375,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
|
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
||||||
|
|
||||||
testPauseAndDestroy(finalState)
|
testPauseAndDestroy(finalState)
|
||||||
|
|
@ -393,7 +399,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
|
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(aPreviewState(isSending = true))
|
assertThat(finalState.voiceMessageState).isEqualTo(aPreviewState(isSending = true))
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isNeverCalled()
|
||||||
assertThat(analyticsService.trackedErrors).hasSize(0)
|
assertThat(analyticsService.trackedErrors).hasSize(0)
|
||||||
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 0)
|
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 0)
|
||||||
|
|
||||||
|
|
@ -418,13 +424,13 @@ class VoiceMessageComposerPresenterTest {
|
||||||
|
|
||||||
ensureAllEventsConsumed()
|
ensureAllEventsConsumed()
|
||||||
assertThat(previewState.voiceMessageState).isEqualTo(aPreviewState())
|
assertThat(previewState.voiceMessageState).isEqualTo(aPreviewState())
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isNeverCalled()
|
||||||
|
|
||||||
mediaPreProcessor.givenAudioResult()
|
mediaPreProcessor.givenAudioResult()
|
||||||
previewState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
previewState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
||||||
val finalState = awaitItem()
|
val finalState = awaitItem()
|
||||||
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(1)
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1)
|
||||||
|
|
||||||
testPauseAndDestroy(finalState)
|
testPauseAndDestroy(finalState)
|
||||||
|
|
@ -461,7 +467,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
assertThat(showSendFailureDialog).isFalse()
|
assertThat(showSendFailureDialog).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isNeverCalled()
|
||||||
testPauseAndDestroy(finalState)
|
testPauseAndDestroy(finalState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -477,7 +483,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
initialState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
initialState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage)
|
||||||
|
|
||||||
assertThat(initialState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
assertThat(initialState.voiceMessageState).isEqualTo(VoiceMessageState.Idle)
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isNeverCalled()
|
||||||
assertThat(analyticsService.trackedErrors).hasSize(1)
|
assertThat(analyticsService.trackedErrors).hasSize(1)
|
||||||
voiceRecorder.assertCalls(started = 0)
|
voiceRecorder.assertCalls(started = 0)
|
||||||
|
|
||||||
|
|
@ -496,7 +502,7 @@ class VoiceMessageComposerPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start))
|
initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start))
|
||||||
|
|
||||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
sendMediaResult.assertions().isNeverCalled()
|
||||||
assertThat(analyticsService.trackedErrors).containsExactly(
|
assertThat(analyticsService.trackedErrors).containsExactly(
|
||||||
VoiceMessageException.PermissionMissing(message = "Expected permission to record but none", cause = exception)
|
VoiceMessageException.PermissionMissing(message = "Expected permission to record but none", cause = exception)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.room.SavePollInvocation
|
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider
|
import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
|
|
@ -51,9 +50,9 @@ import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class) class CreatePollPresenterTest {
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@get:Rule
|
class CreatePollPresenterTest {
|
||||||
val warmUpRule = WarmUpRule()
|
@get:Rule val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
private val pollEventId = AN_EVENT_ID
|
private val pollEventId = AN_EVENT_ID
|
||||||
private var navUpInvocationsCount = 0
|
private var navUpInvocationsCount = 0
|
||||||
|
|
@ -128,7 +127,13 @@ import org.junit.Test
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create poll sends a poll start event`() = runTest {
|
fun `create poll sends a poll start event`() = runTest {
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.NewPoll)
|
val createPollResult = lambdaRecorder<String, List<String>, Int, PollKind, Result<Unit>> { _, _, _, _ -> Result.success(Unit) }
|
||||||
|
val presenter = createCreatePollPresenter(
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
createPollResult = createPollResult
|
||||||
|
),
|
||||||
|
mode = CreatePollMode.NewPoll,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -139,15 +144,13 @@ import org.junit.Test
|
||||||
skipItems(3)
|
skipItems(3)
|
||||||
initial.eventSink(CreatePollEvents.Save)
|
initial.eventSink(CreatePollEvents.Save)
|
||||||
delay(1) // Wait for the coroutine to finish
|
delay(1) // Wait for the coroutine to finish
|
||||||
assertThat(fakeMatrixRoom.createPollInvocations.size).isEqualTo(1)
|
createPollResult.assertions().isCalledOnce()
|
||||||
assertThat(fakeMatrixRoom.createPollInvocations.last()).isEqualTo(
|
.with(
|
||||||
SavePollInvocation(
|
value("A question?"),
|
||||||
question = "A question?",
|
value(listOf("Answer 1", "Answer 2")),
|
||||||
answers = listOf("Answer 1", "Answer 2"),
|
value(1),
|
||||||
maxSelections = 1,
|
value(PollKind.Disclosed),
|
||||||
pollKind = PollKind.Disclosed
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(2)
|
assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(2)
|
||||||
assertThat(fakeAnalyticsService.capturedEvents[0]).isEqualTo(
|
assertThat(fakeAnalyticsService.capturedEvents[0]).isEqualTo(
|
||||||
Composer(
|
Composer(
|
||||||
|
|
@ -170,8 +173,15 @@ import org.junit.Test
|
||||||
@Test
|
@Test
|
||||||
fun `when poll creation fails, error is tracked`() = runTest {
|
fun `when poll creation fails, error is tracked`() = runTest {
|
||||||
val error = Exception("cause")
|
val error = Exception("cause")
|
||||||
fakeMatrixRoom.givenCreatePollResult(Result.failure(error))
|
val createPollResult = lambdaRecorder<String, List<String>, Int, PollKind, Result<Unit>> { _, _, _, _ ->
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.NewPoll)
|
Result.failure(error)
|
||||||
|
}
|
||||||
|
val presenter = createCreatePollPresenter(
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
createPollResult = createPollResult
|
||||||
|
),
|
||||||
|
mode = CreatePollMode.NewPoll,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -180,7 +190,7 @@ import org.junit.Test
|
||||||
awaitItem().eventSink(CreatePollEvents.SetAnswer(1, "Answer 2"))
|
awaitItem().eventSink(CreatePollEvents.SetAnswer(1, "Answer 2"))
|
||||||
awaitItem().eventSink(CreatePollEvents.Save)
|
awaitItem().eventSink(CreatePollEvents.Save)
|
||||||
delay(1) // Wait for the coroutine to finish
|
delay(1) // Wait for the coroutine to finish
|
||||||
assertThat(fakeMatrixRoom.createPollInvocations).hasSize(1)
|
createPollResult.assertions().isCalledOnce()
|
||||||
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
|
assertThat(fakeAnalyticsService.capturedEvents).isEmpty()
|
||||||
assertThat(fakeAnalyticsService.trackedErrors).hasSize(1)
|
assertThat(fakeAnalyticsService.trackedErrors).hasSize(1)
|
||||||
assertThat(fakeAnalyticsService.trackedErrors).containsExactly(
|
assertThat(fakeAnalyticsService.trackedErrors).containsExactly(
|
||||||
|
|
@ -252,14 +262,22 @@ import org.junit.Test
|
||||||
@Test
|
@Test
|
||||||
fun `when edit poll fails, error is tracked`() = runTest {
|
fun `when edit poll fails, error is tracked`() = runTest {
|
||||||
val error = Exception("cause")
|
val error = Exception("cause")
|
||||||
|
val editPollResult = lambdaRecorder { _: EventId, _: String, _: List<String>, _: Int, _: PollKind ->
|
||||||
|
Result.failure<Unit>(error)
|
||||||
|
}
|
||||||
|
val presenter = createCreatePollPresenter(
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
editPollResult = editPollResult,
|
||||||
|
liveTimeline = timeline,
|
||||||
|
),
|
||||||
|
mode = CreatePollMode.EditPoll(pollEventId),
|
||||||
|
)
|
||||||
val editPollLambda = lambdaRecorder { _: EventId, _: String, _: List<String>, _: Int, _: PollKind ->
|
val editPollLambda = lambdaRecorder { _: EventId, _: String, _: List<String>, _: Int, _: PollKind ->
|
||||||
Result.failure<Unit>(error)
|
Result.failure<Unit>(error)
|
||||||
}
|
}
|
||||||
timeline.apply {
|
timeline.apply {
|
||||||
this.editPollLambda = editPollLambda
|
this.editPollLambda = editPollLambda
|
||||||
}
|
}
|
||||||
fakeMatrixRoom.givenEditPollResult(Result.failure(error))
|
|
||||||
val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId))
|
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,15 @@
|
||||||
package io.element.android.features.roomdetails
|
package io.element.android.features.roomdetails
|
||||||
|
|
||||||
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.core.UserId
|
||||||
|
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||||
|
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||||
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomInfo
|
import io.element.android.libraries.matrix.test.room.aRoomInfo
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
||||||
fun aMatrixRoom(
|
fun aMatrixRoom(
|
||||||
roomId: RoomId = A_ROOM_ID,
|
roomId: RoomId = A_ROOM_ID,
|
||||||
|
|
@ -34,6 +38,16 @@ fun aMatrixRoom(
|
||||||
isDirect: Boolean = false,
|
isDirect: Boolean = false,
|
||||||
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
||||||
emitRoomInfo: Boolean = false,
|
emitRoomInfo: Boolean = false,
|
||||||
|
canInviteResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
canSendStateResult: (UserId, StateEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
|
||||||
|
userDisplayNameResult: () -> Result<String?> = { lambdaError() },
|
||||||
|
userAvatarUrlResult: () -> Result<String?> = { lambdaError() },
|
||||||
|
setNameResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
|
setTopicResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
|
updateAvatarResult: (String, ByteArray) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
removeAvatarResult: () -> Result<Unit> = { lambdaError() },
|
||||||
|
canUserJoinCallResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
getUpdatedMemberResult: (UserId) -> Result<RoomMember> = { lambdaError() },
|
||||||
) = FakeMatrixRoom(
|
) = FakeMatrixRoom(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
displayName = displayName,
|
displayName = displayName,
|
||||||
|
|
@ -42,7 +56,17 @@ fun aMatrixRoom(
|
||||||
isEncrypted = isEncrypted,
|
isEncrypted = isEncrypted,
|
||||||
isPublic = isPublic,
|
isPublic = isPublic,
|
||||||
isDirect = isDirect,
|
isDirect = isDirect,
|
||||||
notificationSettingsService = notificationSettingsService
|
notificationSettingsService = notificationSettingsService,
|
||||||
|
canInviteResult = canInviteResult,
|
||||||
|
canSendStateResult = canSendStateResult,
|
||||||
|
userDisplayNameResult = userDisplayNameResult,
|
||||||
|
userAvatarUrlResult = userAvatarUrlResult,
|
||||||
|
setNameResult = setNameResult,
|
||||||
|
setTopicResult = setTopicResult,
|
||||||
|
updateAvatarResult = updateAvatarResult,
|
||||||
|
removeAvatarResult = removeAvatarResult,
|
||||||
|
canUserJoinCallResult = canUserJoinCallResult,
|
||||||
|
getUpdatedMemberResult = getUpdatedMemberResult,
|
||||||
).apply {
|
).apply {
|
||||||
if (emitRoomInfo) {
|
if (emitRoomInfo) {
|
||||||
givenRoomInfo(
|
givenRoomInfo(
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.FakeLifecycleOwner
|
import io.element.android.tests.testutils.FakeLifecycleOwner
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import io.element.android.tests.testutils.withFakeLifecycleOwner
|
import io.element.android.tests.testutils.withFakeLifecycleOwner
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
@ -110,7 +113,11 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state is created from room if roomInfo is null`() = runTest {
|
fun `present - initial state is created from room if roomInfo is null`() = runTest {
|
||||||
val room = aMatrixRoom()
|
val room = aMatrixRoom(
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
@ -128,7 +135,11 @@ class RoomDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state is updated with roomInfo if it exists`() = runTest {
|
fun `present - initial state is updated with roomInfo if it exists`() = runTest {
|
||||||
val roomInfo = aRoomInfo(name = "A room name", topic = "A topic", avatarUrl = "https://matrix.org/avatar.jpg")
|
val roomInfo = aRoomInfo(name = "A room name", topic = "A topic", avatarUrl = "https://matrix.org/avatar.jpg")
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
).apply {
|
||||||
givenRoomInfo(roomInfo)
|
givenRoomInfo(roomInfo)
|
||||||
}
|
}
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
|
|
@ -145,7 +156,12 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state with no room name`() = runTest {
|
fun `present - initial state with no room name`() = runTest {
|
||||||
val room = aMatrixRoom(displayName = "")
|
val room = aMatrixRoom(
|
||||||
|
displayName = "",
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
|
|
@ -162,6 +178,16 @@ class RoomDetailsPresenterTest {
|
||||||
val room = aMatrixRoom(
|
val room = aMatrixRoom(
|
||||||
isEncrypted = true,
|
isEncrypted = true,
|
||||||
isDirect = true,
|
isDirect = true,
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
getUpdatedMemberResult = { userId ->
|
||||||
|
when (userId) {
|
||||||
|
A_SESSION_ID -> Result.success(myRoomMember)
|
||||||
|
A_USER_ID_2 -> Result.success(otherRoomMember)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
).apply {
|
).apply {
|
||||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||||
|
|
@ -181,9 +207,11 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when user can invite others to room`() = runTest {
|
fun `present - initial state when user can invite others to room`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanInviteResult(Result.success(true))
|
canInviteResult = { Result.success(true) },
|
||||||
}
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
val presenter = createRoomDetailsPresenter(room, dispatchers = testCoroutineDispatchers())
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// Initially false
|
// Initially false
|
||||||
|
|
@ -197,9 +225,11 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when user can not invite others to room`() = runTest {
|
fun `present - initial state when user can not invite others to room`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanInviteResult(Result.success(false))
|
canInviteResult = { Result.success(false) },
|
||||||
}
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
assertThat(awaitItem().canInvite).isFalse()
|
assertThat(awaitItem().canInvite).isFalse()
|
||||||
|
|
@ -210,9 +240,11 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when canInvite errors`() = runTest {
|
fun `present - initial state when canInvite errors`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanInviteResult(Result.failure(Throwable("Whoops")))
|
canInviteResult = { Result.failure(Throwable("Whoops")) },
|
||||||
}
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
assertThat(awaitItem().canInvite).isFalse()
|
assertThat(awaitItem().canInvite).isFalse()
|
||||||
|
|
@ -223,12 +255,18 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when user can edit one attribute`() = runTest {
|
fun `present - initial state when user can edit one attribute`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(false))
|
when (stateEventType) {
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Whelp")))
|
StateEventType.ROOM_TOPIC -> Result.success(true)
|
||||||
givenCanInviteResult(Result.success(false))
|
StateEventType.ROOM_NAME -> Result.success(false)
|
||||||
}
|
StateEventType.ROOM_AVATAR -> Result.failure(Throwable("Whelp"))
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = { Result.success(false) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// Initially false
|
// Initially false
|
||||||
|
|
@ -247,14 +285,26 @@ class RoomDetailsPresenterTest {
|
||||||
val room = aMatrixRoom(
|
val room = aMatrixRoom(
|
||||||
isEncrypted = true,
|
isEncrypted = true,
|
||||||
isDirect = true,
|
isDirect = true,
|
||||||
|
canSendStateResult = { _, stateEventType ->
|
||||||
|
when (stateEventType) {
|
||||||
|
StateEventType.ROOM_TOPIC -> Result.success(true)
|
||||||
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
|
StateEventType.ROOM_AVATAR -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = { Result.success(false) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
getUpdatedMemberResult = { userId ->
|
||||||
|
when (userId) {
|
||||||
|
A_SESSION_ID -> Result.success(myRoomMember)
|
||||||
|
A_USER_ID_2 -> Result.success(otherRoomMember)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
).apply {
|
).apply {
|
||||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||||
|
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(true))
|
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
|
||||||
givenCanInviteResult(Result.success(false))
|
|
||||||
}
|
}
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
|
|
@ -278,12 +328,28 @@ class RoomDetailsPresenterTest {
|
||||||
isEncrypted = true,
|
isEncrypted = true,
|
||||||
isDirect = true,
|
isDirect = true,
|
||||||
topic = null,
|
topic = null,
|
||||||
|
canSendStateResult = { _, stateEventType ->
|
||||||
|
when (stateEventType) {
|
||||||
|
StateEventType.ROOM_AVATAR,
|
||||||
|
StateEventType.ROOM_TOPIC,
|
||||||
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
getUpdatedMemberResult = { userId ->
|
||||||
|
when (userId) {
|
||||||
|
A_SESSION_ID -> Result.success(myRoomMember)
|
||||||
|
A_USER_ID_2 -> Result.success(otherRoomMember)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
).apply {
|
).apply {
|
||||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||||
|
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
@ -297,12 +363,20 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when user can edit all attributes`() = runTest {
|
fun `present - initial state when user can edit all attributes`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(true))
|
when (stateEventType) {
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
StateEventType.ROOM_TOPIC -> Result.success(true)
|
||||||
givenCanInviteResult(Result.success(false))
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
}
|
StateEventType.ROOM_AVATAR -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = {
|
||||||
|
Result.success(false)
|
||||||
|
},
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// Initially false
|
// Initially false
|
||||||
|
|
@ -316,12 +390,20 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state when user can edit no attributes`() = runTest {
|
fun `present - initial state when user can edit no attributes`() = runTest {
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(false))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(false))
|
when (stateEventType) {
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false))
|
StateEventType.ROOM_TOPIC -> Result.success(false)
|
||||||
givenCanInviteResult(Result.success(false))
|
StateEventType.ROOM_NAME -> Result.success(false)
|
||||||
}
|
StateEventType.ROOM_AVATAR -> Result.success(false)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = {
|
||||||
|
Result.success(false)
|
||||||
|
},
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// Initially false, and no further events
|
// Initially false, and no further events
|
||||||
|
|
@ -333,11 +415,21 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - topic state is hidden when no topic and user has no permission`() = runTest {
|
fun `present - topic state is hidden when no topic and user has no permission`() = runTest {
|
||||||
val room = aMatrixRoom(topic = null).apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(false))
|
topic = null,
|
||||||
givenCanInviteResult(Result.success(false))
|
canSendStateResult = { _, stateEventType ->
|
||||||
}
|
when (stateEventType) {
|
||||||
|
StateEventType.ROOM_AVATAR,
|
||||||
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
|
StateEventType.ROOM_TOPIC -> Result.success(false)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = {
|
||||||
|
Result.success(false)
|
||||||
|
},
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// The initial state is "hidden" and no further state changes happen
|
// The initial state is "hidden" and no further state changes happen
|
||||||
|
|
@ -349,12 +441,23 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - topic state is 'can add topic' when no topic and user has permission`() = runTest {
|
fun `present - topic state is 'can add topic' when no topic and user has permission`() = runTest {
|
||||||
val room = aMatrixRoom(topic = null).apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
topic = null,
|
||||||
givenCanInviteResult(Result.success(false))
|
canSendStateResult = { _, stateEventType ->
|
||||||
|
when (stateEventType) {
|
||||||
|
StateEventType.ROOM_AVATAR,
|
||||||
|
StateEventType.ROOM_TOPIC,
|
||||||
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canInviteResult = {
|
||||||
|
Result.success(false)
|
||||||
|
},
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
).apply {
|
||||||
givenRoomInfo(aRoomInfo(topic = null))
|
givenRoomInfo(aRoomInfo(topic = null))
|
||||||
}
|
}
|
||||||
|
|
||||||
val presenter = createRoomDetailsPresenter(room)
|
val presenter = createRoomDetailsPresenter(room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
// Ignore the initial state
|
// Ignore the initial state
|
||||||
|
|
@ -370,7 +473,11 @@ class RoomDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - leave room event is passed on to leave room presenter`() = runTest {
|
fun `present - leave room event is passed on to leave room presenter`() = runTest {
|
||||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||||
val room = aMatrixRoom()
|
val room = aMatrixRoom(
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(
|
val presenter = createRoomDetailsPresenter(
|
||||||
room = room,
|
room = room,
|
||||||
leaveRoomPresenter = leaveRoomPresenter,
|
leaveRoomPresenter = leaveRoomPresenter,
|
||||||
|
|
@ -379,7 +486,11 @@ class RoomDetailsPresenterTest {
|
||||||
presenter.test {
|
presenter.test {
|
||||||
awaitItem().eventSink(RoomDetailsEvent.LeaveRoom)
|
awaitItem().eventSink(RoomDetailsEvent.LeaveRoom)
|
||||||
|
|
||||||
assertThat(leaveRoomPresenter.events).contains(LeaveRoomEvent.ShowConfirmation(room.roomId))
|
assertThat(leaveRoomPresenter.events).contains(
|
||||||
|
LeaveRoomEvent.ShowConfirmation(
|
||||||
|
room.roomId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
|
|
@ -389,33 +500,54 @@ class RoomDetailsPresenterTest {
|
||||||
fun `present - notification mode changes`() = runTest {
|
fun `present - notification mode changes`() = runTest {
|
||||||
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
val leaveRoomPresenter = FakeLeaveRoomPresenter()
|
||||||
val notificationSettingsService = FakeNotificationSettingsService()
|
val notificationSettingsService = FakeNotificationSettingsService()
|
||||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
val room = aMatrixRoom(
|
||||||
|
notificationSettingsService = notificationSettingsService,
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(
|
val presenter = createRoomDetailsPresenter(
|
||||||
room = room,
|
room = room,
|
||||||
leaveRoomPresenter = leaveRoomPresenter,
|
leaveRoomPresenter = leaveRoomPresenter,
|
||||||
notificationSettingsService = notificationSettingsService,
|
notificationSettingsService = notificationSettingsService,
|
||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
notificationSettingsService.setRoomNotificationMode(room.roomId, RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
notificationSettingsService.setRoomNotificationMode(
|
||||||
|
room.roomId,
|
||||||
|
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
|
||||||
|
)
|
||||||
val updatedState = consumeItemsUntilPredicate {
|
val updatedState = consumeItemsUntilPredicate {
|
||||||
it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
|
it.roomNotificationSettings?.mode == RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
|
||||||
}.last()
|
}.last()
|
||||||
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(
|
||||||
|
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY
|
||||||
|
)
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - mute room notifications`() = runTest {
|
fun `present - mute room notifications`() = runTest {
|
||||||
val notificationSettingsService = FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
val notificationSettingsService =
|
||||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
FakeNotificationSettingsService(initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY)
|
||||||
val presenter = createRoomDetailsPresenter(room = room, notificationSettingsService = notificationSettingsService)
|
val room = aMatrixRoom(
|
||||||
|
notificationSettingsService = notificationSettingsService,
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
|
val presenter = createRoomDetailsPresenter(
|
||||||
|
room = room,
|
||||||
|
notificationSettingsService = notificationSettingsService
|
||||||
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
awaitItem().eventSink(RoomDetailsEvent.MuteNotification)
|
awaitItem().eventSink(RoomDetailsEvent.MuteNotification)
|
||||||
val updatedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) {
|
val updatedState = consumeItemsUntilPredicate(timeout = 250.milliseconds) {
|
||||||
it.roomNotificationSettings?.mode == RoomNotificationMode.MUTE
|
it.roomNotificationSettings?.mode == RoomNotificationMode.MUTE
|
||||||
}.last()
|
}.last()
|
||||||
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.MUTE)
|
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(
|
||||||
|
RoomNotificationMode.MUTE
|
||||||
|
)
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -426,29 +558,50 @@ class RoomDetailsPresenterTest {
|
||||||
initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
initialRoomMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
||||||
initialEncryptedGroupDefaultMode = RoomNotificationMode.ALL_MESSAGES
|
initialEncryptedGroupDefaultMode = RoomNotificationMode.ALL_MESSAGES
|
||||||
)
|
)
|
||||||
val room = aMatrixRoom(notificationSettingsService = notificationSettingsService)
|
val room = aMatrixRoom(
|
||||||
val presenter = createRoomDetailsPresenter(room = room, notificationSettingsService = notificationSettingsService)
|
notificationSettingsService = notificationSettingsService,
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
|
val presenter = createRoomDetailsPresenter(
|
||||||
|
room = room,
|
||||||
|
notificationSettingsService = notificationSettingsService
|
||||||
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
awaitItem().eventSink(RoomDetailsEvent.UnmuteNotification)
|
awaitItem().eventSink(RoomDetailsEvent.UnmuteNotification)
|
||||||
val updatedState = consumeItemsUntilPredicate {
|
val updatedState = consumeItemsUntilPredicate {
|
||||||
it.roomNotificationSettings?.mode == RoomNotificationMode.ALL_MESSAGES
|
it.roomNotificationSettings?.mode == RoomNotificationMode.ALL_MESSAGES
|
||||||
}.last()
|
}.last()
|
||||||
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(RoomNotificationMode.ALL_MESSAGES)
|
assertThat(updatedState.roomNotificationSettings?.mode).isEqualTo(
|
||||||
|
RoomNotificationMode.ALL_MESSAGES
|
||||||
|
)
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
|
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val setIsFavoriteResult = lambdaRecorder<Boolean, Result<Unit>> { _ -> Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
setIsFavoriteResult = setIsFavoriteResult,
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val presenter = createRoomDetailsPresenter(room = room, analyticsService = analyticsService)
|
val presenter =
|
||||||
|
createRoomDetailsPresenter(room = room, analyticsService = analyticsService)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEvent.SetFavorite(true))
|
initialState.eventSink(RoomDetailsEvent.SetFavorite(true))
|
||||||
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true))
|
setIsFavoriteResult.assertions().isCalledOnce().with(value(true))
|
||||||
initialState.eventSink(RoomDetailsEvent.SetFavorite(false))
|
initialState.eventSink(RoomDetailsEvent.SetFavorite(false))
|
||||||
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true, false))
|
setIsFavoriteResult.assertions().isCalledExactly(2)
|
||||||
|
.withSequence(
|
||||||
|
listOf(value(true)),
|
||||||
|
listOf(value(false)),
|
||||||
|
)
|
||||||
assertThat(analyticsService.capturedEvents).containsExactly(
|
assertThat(analyticsService.capturedEvents).containsExactly(
|
||||||
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle),
|
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle),
|
||||||
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle)
|
Interaction(name = Interaction.Name.MobileRoomFavouriteToggle)
|
||||||
|
|
@ -459,7 +612,11 @@ class RoomDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - changes in room info updates the is favorite flag`() = runTest {
|
fun `present - changes in room info updates the is favorite flag`() = runTest {
|
||||||
val room = aMatrixRoom()
|
val room = aMatrixRoom(
|
||||||
|
canInviteResult = { Result.success(true) },
|
||||||
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsPresenter(room = room)
|
val presenter = createRoomDetailsPresenter(room = room)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
room.givenRoomInfo(aRoomInfo(isFavorite = true))
|
room.givenRoomInfo(aRoomInfo(isFavorite = true))
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ 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.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
|
|
@ -98,6 +101,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = A_ROOM_NAME,
|
displayName = A_ROOM_NAME,
|
||||||
rawName = A_ROOM_RAW_NAME,
|
rawName = A_ROOM_RAW_NAME,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -120,11 +124,17 @@ class RoomDetailsEditPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - sets canChangeName if user has permission`() = runTest {
|
fun `present - sets canChangeName if user has permission`() = runTest {
|
||||||
val room = aMatrixRoom(avatarUrl = AN_AVATAR_URL).apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(true))
|
avatarUrl = AN_AVATAR_URL,
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(false))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.failure(Throwable("Oops")))
|
when (stateEventType) {
|
||||||
}
|
StateEventType.ROOM_NAME -> Result.success(true)
|
||||||
|
StateEventType.ROOM_AVATAR -> Result.success(false)
|
||||||
|
StateEventType.ROOM_TOPIC -> Result.failure(Throwable("Oops"))
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -144,11 +154,17 @@ class RoomDetailsEditPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - sets canChangeAvatar if user has permission`() = runTest {
|
fun `present - sets canChangeAvatar if user has permission`() = runTest {
|
||||||
val room = aMatrixRoom(avatarUrl = AN_AVATAR_URL).apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(false))
|
avatarUrl = AN_AVATAR_URL,
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.failure(Throwable("Oops")))
|
when (stateEventType) {
|
||||||
}
|
StateEventType.ROOM_NAME -> Result.success(false)
|
||||||
|
StateEventType.ROOM_AVATAR -> Result.success(true)
|
||||||
|
StateEventType.ROOM_TOPIC -> Result.failure(Throwable("Oops"))
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -168,11 +184,17 @@ class RoomDetailsEditPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - sets canChangeTopic if user has permission`() = runTest {
|
fun `present - sets canChangeTopic if user has permission`() = runTest {
|
||||||
val room = aMatrixRoom(avatarUrl = AN_AVATAR_URL).apply {
|
val room = aMatrixRoom(
|
||||||
givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(false))
|
avatarUrl = AN_AVATAR_URL,
|
||||||
givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.failure(Throwable("Oops")))
|
canSendStateResult = { _, stateEventType ->
|
||||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
when (stateEventType) {
|
||||||
}
|
StateEventType.ROOM_NAME -> Result.success(false)
|
||||||
|
StateEventType.ROOM_AVATAR -> Result.failure(Throwable("Oops"))
|
||||||
|
StateEventType.ROOM_TOPIC -> Result.success(true)
|
||||||
|
else -> lambdaError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -197,6 +219,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -240,6 +263,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
|
|
@ -262,6 +286,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||||
val fakePermissionsPresenter = FakePermissionsPresenter()
|
val fakePermissionsPresenter = FakePermissionsPresenter()
|
||||||
|
|
@ -298,6 +323,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
fakePickerProvider.givenResult(roomAvatarUri)
|
fakePickerProvider.givenResult(roomAvatarUri)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
|
|
@ -346,6 +372,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "fallback",
|
displayName = "fallback",
|
||||||
avatarUrl = null,
|
avatarUrl = null,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
fakePickerProvider.givenResult(roomAvatarUri)
|
fakePickerProvider.givenResult(roomAvatarUri)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
|
|
@ -389,11 +416,18 @@ class RoomDetailsEditPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save changes room details if different`() = runTest {
|
fun `present - save changes room details if different`() = runTest {
|
||||||
|
val setNameResult = lambdaRecorder { _: String -> Result.success(Unit) }
|
||||||
|
val setTopicResult = lambdaRecorder { _: String -> Result.success(Unit) }
|
||||||
|
val removeAvatarResult = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
|
||||||
val room = aMatrixRoom(
|
val room = aMatrixRoom(
|
||||||
topic = "My topic",
|
topic = "My topic",
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
|
setNameResult = setNameResult,
|
||||||
|
setTopicResult = setTopicResult,
|
||||||
|
removeAvatarResult = removeAvatarResult,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
)
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -405,16 +439,20 @@ class RoomDetailsEditPresenterTest {
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
skipItems(5)
|
skipItems(5)
|
||||||
assertThat(room.newName).isEqualTo("New name")
|
setNameResult.assertions().isCalledOnce().with(value("New name"))
|
||||||
assertThat(room.newTopic).isEqualTo("New topic")
|
setTopicResult.assertions().isCalledOnce().with(value("New topic"))
|
||||||
assertThat(room.newAvatarData).isNull()
|
removeAvatarResult.assertions().isCalledOnce()
|
||||||
assertThat(room.removedAvatar).isTrue()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save doesn't change room details if they're the same trimmed`() = runTest {
|
fun `present - save doesn't change room details if they're the same trimmed`() = runTest {
|
||||||
val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
val room = aMatrixRoom(
|
||||||
|
topic = "My topic",
|
||||||
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -423,17 +461,18 @@ class RoomDetailsEditPresenterTest {
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(" Name "))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(" Name "))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(" My topic "))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(" My topic "))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
assertThat(room.newName).isNull()
|
|
||||||
assertThat(room.newTopic).isNull()
|
|
||||||
assertThat(room.newAvatarData).isNull()
|
|
||||||
assertThat(room.removedAvatar).isFalse()
|
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save doesn't change topic if it was unset and is now blank`() = runTest {
|
fun `present - save doesn't change topic if it was unset and is now blank`() = runTest {
|
||||||
val room = aMatrixRoom(topic = null, displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
val room = aMatrixRoom(
|
||||||
|
topic = null,
|
||||||
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -441,17 +480,18 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(""))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(""))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
assertThat(room.newName).isNull()
|
|
||||||
assertThat(room.newTopic).isNull()
|
|
||||||
assertThat(room.newAvatarData).isNull()
|
|
||||||
assertThat(room.removedAvatar).isFalse()
|
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save doesn't change name if it's now empty`() = runTest {
|
fun `present - save doesn't change name if it's now empty`() = runTest {
|
||||||
val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
val room = aMatrixRoom(
|
||||||
|
topic = "My topic",
|
||||||
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -459,17 +499,20 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(""))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(""))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
assertThat(room.newName).isNull()
|
|
||||||
assertThat(room.newTopic).isNull()
|
|
||||||
assertThat(room.newAvatarData).isNull()
|
|
||||||
assertThat(room.removedAvatar).isFalse()
|
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save processes and sets avatar when processor returns successfully`() = runTest {
|
fun `present - save processes and sets avatar when processor returns successfully`() = runTest {
|
||||||
val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
val updateAvatarResult = lambdaRecorder { _: String, _: ByteArray -> Result.success(Unit) }
|
||||||
|
val room = aMatrixRoom(
|
||||||
|
topic = "My topic",
|
||||||
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
updateAvatarResult = updateAvatarResult,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
givenPickerReturnsFile()
|
givenPickerReturnsFile()
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -478,17 +521,19 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
skipItems(3)
|
skipItems(4)
|
||||||
assertThat(room.newName).isNull()
|
updateAvatarResult.assertions().isCalledOnce().with(value("image/jpeg"), value(fakeFileContents))
|
||||||
assertThat(room.newTopic).isNull()
|
|
||||||
assertThat(room.newAvatarData).isSameInstanceAs(fakeFileContents)
|
|
||||||
assertThat(room.removedAvatar).isFalse()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - save does not set avatar data if processor fails`() = runTest {
|
fun `present - save does not set avatar data if processor fails`() = runTest {
|
||||||
val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL)
|
val room = aMatrixRoom(
|
||||||
|
topic = "My topic",
|
||||||
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
fakePickerProvider.givenResult(anotherAvatarUri)
|
fakePickerProvider.givenResult(anotherAvatarUri)
|
||||||
fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no")))
|
fakeMediaPreProcessor.givenResult(Result.failure(Throwable("Oh no")))
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
|
|
@ -498,11 +543,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
skipItems(2)
|
skipItems(3)
|
||||||
assertThat(room.newName).isNull()
|
|
||||||
assertThat(room.newTopic).isNull()
|
|
||||||
assertThat(room.newAvatarData).isNull()
|
|
||||||
assertThat(room.removedAvatar).isFalse()
|
|
||||||
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
|
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -514,9 +555,9 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
).apply {
|
setNameResult = { Result.failure(Throwable("!")) },
|
||||||
givenSetNameResult(Result.failure(Throwable("!")))
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
}
|
)
|
||||||
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomName("New name"))
|
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomName("New name"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,9 +568,9 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
).apply {
|
setTopicResult = { Result.failure(Throwable("!")) },
|
||||||
givenSetTopicResult(Result.failure(Throwable("!")))
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
}
|
)
|
||||||
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomTopic("New topic"))
|
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomTopic("New topic"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -540,9 +581,9 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
).apply {
|
removeAvatarResult = { Result.failure(Throwable("!")) },
|
||||||
givenRemoveAvatarResult(Result.failure(Throwable("!")))
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
}
|
)
|
||||||
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -554,18 +595,22 @@ class RoomDetailsEditPresenterTest {
|
||||||
displayName = "Name",
|
displayName = "Name",
|
||||||
avatarUrl = AN_AVATAR_URL,
|
avatarUrl = AN_AVATAR_URL,
|
||||||
emitRoomInfo = true,
|
emitRoomInfo = true,
|
||||||
).apply {
|
updateAvatarResult = { _, _ -> Result.failure(Throwable("!")) },
|
||||||
givenUpdateAvatarResult(Result.failure(Throwable("!")))
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
}
|
)
|
||||||
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - CancelSaveChanges resets save action state`() = runTest {
|
fun `present - CancelSaveChanges resets save action state`() = runTest {
|
||||||
givenPickerReturnsFile()
|
givenPickerReturnsFile()
|
||||||
val room = aMatrixRoom(topic = "My topic", displayName = "Name", avatarUrl = AN_AVATAR_URL).apply {
|
val room = aMatrixRoom(
|
||||||
givenSetTopicResult(Result.failure(Throwable("!")))
|
topic = "My topic",
|
||||||
}
|
displayName = "Name",
|
||||||
|
avatarUrl = AN_AVATAR_URL,
|
||||||
|
setTopicResult = { Result.failure(Throwable("!")) },
|
||||||
|
canSendStateResult = { _, _ -> Result.success(true) }
|
||||||
|
)
|
||||||
val presenter = createRoomDetailsEditPresenter(room)
|
val presenter = createRoomDetailsEditPresenter(room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -573,7 +618,7 @@ class RoomDetailsEditPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("foo"))
|
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("foo"))
|
||||||
initialState.eventSink(RoomDetailsEditEvents.Save)
|
initialState.eventSink(RoomDetailsEditEvents.Save)
|
||||||
skipItems(2)
|
skipItems(3)
|
||||||
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
|
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
|
||||||
initialState.eventSink(RoomDetailsEditEvents.CancelSaveChanges)
|
initialState.eventSink(RoomDetailsEditEvents.CancelSaveChanges)
|
||||||
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,10 @@ class RoomMemberListPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `member loading is done automatically on start, but is async`() = runTest {
|
fun `member loading is done automatically on start, but is async`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
).apply {
|
||||||
// Needed to avoid discarding the loaded members as a partial and invalid result
|
// Needed to avoid discarding the loaded members as a partial and invalid result
|
||||||
givenRoomInfo(aRoomInfo(joinedMembersCount = 2))
|
givenRoomInfo(aRoomInfo(joinedMembersCount = 2))
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +81,12 @@ class RoomMemberListPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `open search`() = runTest {
|
fun `open search`() = runTest {
|
||||||
val presenter = createPresenter()
|
val presenter = createPresenter(
|
||||||
|
matrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -93,7 +101,12 @@ class RoomMemberListPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `search for something which is not found`() = runTest {
|
fun `search for something which is not found`() = runTest {
|
||||||
val presenter = createPresenter()
|
val presenter = createPresenter(
|
||||||
|
matrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -112,7 +125,12 @@ class RoomMemberListPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `search for something which is found`() = runTest {
|
fun `search for something which is found`() = runTest {
|
||||||
val presenter = createPresenter()
|
val presenter = createPresenter(
|
||||||
|
matrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -134,9 +152,10 @@ class RoomMemberListPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - asynchronously sets canInvite when user has correct power level`() = runTest {
|
fun `present - asynchronously sets canInvite when user has correct power level`() = runTest {
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
matrixRoom = FakeMatrixRoom().apply {
|
matrixRoom = FakeMatrixRoom(
|
||||||
givenCanInviteResult(Result.success(true))
|
canInviteResult = { Result.success(true) },
|
||||||
}
|
updateMembersResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -150,9 +169,10 @@ class RoomMemberListPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest {
|
fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest {
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
matrixRoom = FakeMatrixRoom().apply {
|
matrixRoom = FakeMatrixRoom(
|
||||||
givenCanInviteResult(Result.success(false))
|
canInviteResult = { Result.success(false) },
|
||||||
}
|
updateMembersResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -166,9 +186,10 @@ class RoomMemberListPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - asynchronously sets canInvite when power level check fails`() = runTest {
|
fun `present - asynchronously sets canInvite when power level check fails`() = runTest {
|
||||||
val presenter = createPresenter(
|
val presenter = createPresenter(
|
||||||
matrixRoom = FakeMatrixRoom().apply {
|
matrixRoom = FakeMatrixRoom(
|
||||||
givenCanInviteResult(Result.failure(Throwable("Eek")))
|
canInviteResult = { Result.failure(Throwable("Eek")) },
|
||||||
}
|
updateMembersResult = { Result.success(Unit) }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -183,7 +204,14 @@ class RoomMemberListPresenterTest {
|
||||||
fun `present - RoomMemberSelected by default opens the room member details through the navigator`() = runTest {
|
fun `present - RoomMemberSelected by default opens the room member details through the navigator`() = runTest {
|
||||||
val navigator = FakeRoomMemberListNavigator()
|
val navigator = FakeRoomMemberListNavigator()
|
||||||
val moderationPresenter = FakeRoomMembersModerationPresenter(canDisplayModerationActions = false)
|
val moderationPresenter = FakeRoomMembersModerationPresenter(canDisplayModerationActions = false)
|
||||||
val presenter = createPresenter(moderationPresenter = moderationPresenter, navigator = navigator)
|
val presenter = createPresenter(
|
||||||
|
moderationPresenter = moderationPresenter,
|
||||||
|
navigator = navigator,
|
||||||
|
matrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -205,7 +233,14 @@ class RoomMemberListPresenterTest {
|
||||||
val moderationPresenter = FakeRoomMembersModerationPresenter(canDisplayModerationActions = true).apply {
|
val moderationPresenter = FakeRoomMembersModerationPresenter(canDisplayModerationActions = true).apply {
|
||||||
givenState(capturingState)
|
givenState(capturingState)
|
||||||
}
|
}
|
||||||
val presenter = createPresenter(moderationPresenter = moderationPresenter, navigator = navigator)
|
val presenter = createPresenter(
|
||||||
|
moderationPresenter = moderationPresenter,
|
||||||
|
navigator = navigator,
|
||||||
|
matrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
canInviteResult = { Result.success(true) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -236,10 +271,12 @@ private fun TestScope.createDataSource(
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
private fun TestScope.createPresenter(
|
private fun TestScope.createPresenter(
|
||||||
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true),
|
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true),
|
||||||
matrixRoom: MatrixRoom = FakeMatrixRoom(),
|
matrixRoom: MatrixRoom = FakeMatrixRoom(
|
||||||
|
updateMembersResult = { Result.success(Unit) }
|
||||||
|
),
|
||||||
roomMemberListDataSource: RoomMemberListDataSource = createDataSource(coroutineDispatchers = coroutineDispatchers),
|
roomMemberListDataSource: RoomMemberListDataSource = createDataSource(coroutineDispatchers = coroutineDispatchers),
|
||||||
moderationPresenter: FakeRoomMembersModerationPresenter = FakeRoomMembersModerationPresenter(),
|
moderationPresenter: FakeRoomMembersModerationPresenter = FakeRoomMembersModerationPresenter(),
|
||||||
navigator: RoomMemberListNavigator = object : RoomMemberListNavigator { }
|
navigator: RoomMemberListNavigator = object : RoomMemberListNavigator {}
|
||||||
) = RoomMemberListPresenter(
|
) = RoomMemberListPresenter(
|
||||||
room = matrixRoom,
|
room = matrixRoom,
|
||||||
roomMemberListDataSource = roomMemberListDataSource,
|
roomMemberListDataSource = roomMemberListDataSource,
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||||
|
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.A_THROWABLE
|
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
|
||||||
|
|
@ -53,9 +54,11 @@ class RoomMemberDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - returns the room member's data, then updates it if needed`() = runTest {
|
fun `present - returns the room member's data, then updates it if needed`() = runTest {
|
||||||
val roomMember = aRoomMember(displayName = "Alice")
|
val roomMember = aRoomMember(displayName = "Alice")
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenUserDisplayNameResult(Result.success("A custom name"))
|
userDisplayNameResult = { Result.success("A custom name") },
|
||||||
givenUserAvatarUrlResult(Result.success("A custom avatar"))
|
userAvatarUrlResult = { Result.success("A custom avatar") },
|
||||||
|
getUpdatedMemberResult = { Result.success(roomMember) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||||
}
|
}
|
||||||
val presenter = createRoomMemberDetailsPresenter(
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
|
@ -82,11 +85,14 @@ class RoomMemberDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - will recover when retrieving room member details fails`() = runTest {
|
fun `present - will recover when retrieving room member details fails`() = runTest {
|
||||||
val roomMember = aRoomMember(displayName = "Alice")
|
val roomMember = aRoomMember(displayName = "Alice")
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenUserDisplayNameResult(Result.failure(Throwable()))
|
userDisplayNameResult = { Result.failure(Throwable()) },
|
||||||
givenUserAvatarUrlResult(Result.failure(Throwable()))
|
userAvatarUrlResult = { Result.failure(Throwable()) },
|
||||||
|
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val presenter = createRoomMemberDetailsPresenter(
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
room = room,
|
room = room,
|
||||||
roomMemberId = roomMember.userId
|
roomMemberId = roomMember.userId
|
||||||
|
|
@ -105,9 +111,11 @@ class RoomMemberDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - will fallback to original data if the updated data is null`() = runTest {
|
fun `present - will fallback to original data if the updated data is null`() = runTest {
|
||||||
val roomMember = aRoomMember(displayName = "Alice")
|
val roomMember = aRoomMember(displayName = "Alice")
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenUserDisplayNameResult(Result.success(null))
|
userDisplayNameResult = { Result.success(null) },
|
||||||
givenUserAvatarUrlResult(Result.success(null))
|
userAvatarUrlResult = { Result.success(null) },
|
||||||
|
getUpdatedMemberResult = { Result.success(roomMember) }
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||||
}
|
}
|
||||||
val presenter = createRoomMemberDetailsPresenter(
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
|
@ -128,10 +136,11 @@ class RoomMemberDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - will fallback to user profile if user is not a member of the room`() = runTest {
|
fun `present - will fallback to user profile if user is not a member of the room`() = runTest {
|
||||||
val bobProfile = aMatrixUser("@bob:server.org", "Bob", avatarUrl = "anAvatarUrl")
|
val bobProfile = aMatrixUser("@bob:server.org", "Bob", avatarUrl = "anAvatarUrl")
|
||||||
val room = aMatrixRoom().apply {
|
val room = aMatrixRoom(
|
||||||
givenUserDisplayNameResult(Result.failure(Exception("Not a member!")))
|
userDisplayNameResult = { Result.failure(Exception("Not a member!")) },
|
||||||
givenUserAvatarUrlResult(Result.failure(Exception("Not a member!")))
|
userAvatarUrlResult = { Result.failure(Exception("Not a member!")) },
|
||||||
}
|
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
|
||||||
|
)
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetProfileResult(bobProfile.userId, Result.success(bobProfile))
|
givenGetProfileResult(bobProfile.userId, Result.success(bobProfile))
|
||||||
}
|
}
|
||||||
|
|
@ -154,7 +163,13 @@ class RoomMemberDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - BlockUser needing confirmation displays confirmation dialog`() = runTest {
|
fun `present - BlockUser needing confirmation displays confirmation dialog`() = runTest {
|
||||||
val presenter = createRoomMemberDetailsPresenter()
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -176,6 +191,11 @@ class RoomMemberDetailsPresenterTest {
|
||||||
val client = FakeMatrixClient()
|
val client = FakeMatrixClient()
|
||||||
val roomMember = aRoomMember()
|
val roomMember = aRoomMember()
|
||||||
val presenter = createRoomMemberDetailsPresenter(
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
),
|
||||||
client = client,
|
client = client,
|
||||||
roomMemberId = roomMember.userId
|
roomMemberId = roomMember.userId
|
||||||
)
|
)
|
||||||
|
|
@ -199,13 +219,21 @@ class RoomMemberDetailsPresenterTest {
|
||||||
fun `present - BlockUser with error`() = runTest {
|
fun `present - BlockUser with error`() = runTest {
|
||||||
val matrixClient = FakeMatrixClient()
|
val matrixClient = FakeMatrixClient()
|
||||||
matrixClient.givenIgnoreUserResult(Result.failure(A_THROWABLE))
|
matrixClient.givenIgnoreUserResult(Result.failure(A_THROWABLE))
|
||||||
val presenter = createRoomMemberDetailsPresenter(client = matrixClient)
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
client = matrixClient,
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.success(aRoomMember(displayName = "Alice")) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
initialState.eventSink(UserProfileEvents.BlockUser(needsConfirmation = false))
|
initialState.eventSink(UserProfileEvents.BlockUser(needsConfirmation = false))
|
||||||
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
|
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
|
||||||
|
skipItems(2)
|
||||||
val errorState = awaitItem()
|
val errorState = awaitItem()
|
||||||
assertThat(errorState.isBlocked.errorOrNull()).isEqualTo(A_THROWABLE)
|
assertThat(errorState.isBlocked.errorOrNull()).isEqualTo(A_THROWABLE)
|
||||||
// Clear error
|
// Clear error
|
||||||
|
|
@ -218,13 +246,21 @@ class RoomMemberDetailsPresenterTest {
|
||||||
fun `present - UnblockUser with error`() = runTest {
|
fun `present - UnblockUser with error`() = runTest {
|
||||||
val matrixClient = FakeMatrixClient()
|
val matrixClient = FakeMatrixClient()
|
||||||
matrixClient.givenUnignoreUserResult(Result.failure(A_THROWABLE))
|
matrixClient.givenUnignoreUserResult(Result.failure(A_THROWABLE))
|
||||||
val presenter = createRoomMemberDetailsPresenter(client = matrixClient)
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.success(aRoomMember(displayName = "Alice")) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
),
|
||||||
|
client = matrixClient,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitFirstItem()
|
val initialState = awaitFirstItem()
|
||||||
initialState.eventSink(UserProfileEvents.UnblockUser(needsConfirmation = false))
|
initialState.eventSink(UserProfileEvents.UnblockUser(needsConfirmation = false))
|
||||||
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
|
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
|
||||||
|
skipItems(2)
|
||||||
val errorState = awaitItem()
|
val errorState = awaitItem()
|
||||||
assertThat(errorState.isBlocked.errorOrNull()).isEqualTo(A_THROWABLE)
|
assertThat(errorState.isBlocked.errorOrNull()).isEqualTo(A_THROWABLE)
|
||||||
// Clear error
|
// Clear error
|
||||||
|
|
@ -235,7 +271,13 @@ class RoomMemberDetailsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - UnblockUser needing confirmation displays confirmation dialog`() = runTest {
|
fun `present - UnblockUser needing confirmation displays confirmation dialog`() = runTest {
|
||||||
val presenter = createRoomMemberDetailsPresenter()
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.failure(AN_EXCEPTION) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -255,7 +297,14 @@ class RoomMemberDetailsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - start DM action complete scenario`() = runTest {
|
fun `present - start DM action complete scenario`() = runTest {
|
||||||
val startDMAction = FakeStartDMAction()
|
val startDMAction = FakeStartDMAction()
|
||||||
val presenter = createRoomMemberDetailsPresenter(startDMAction = startDMAction)
|
val presenter = createRoomMemberDetailsPresenter(
|
||||||
|
room = aMatrixRoom(
|
||||||
|
getUpdatedMemberResult = { Result.success(aRoomMember(displayName = "Alice")) },
|
||||||
|
userDisplayNameResult = { Result.success("Alice") },
|
||||||
|
userAvatarUrlResult = { Result.success("anAvatarUrl") },
|
||||||
|
),
|
||||||
|
startDMAction = startDMAction,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -268,6 +317,7 @@ class RoomMemberDetailsPresenterTest {
|
||||||
startDMAction.givenExecuteResult(startDMFailureResult)
|
startDMAction.givenExecuteResult(startDMFailureResult)
|
||||||
initialState.eventSink(UserProfileEvents.StartDM)
|
initialState.eventSink(UserProfileEvents.StartDM)
|
||||||
assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java)
|
assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java)
|
||||||
|
skipItems(2)
|
||||||
awaitItem().also { state ->
|
awaitItem().also { state ->
|
||||||
assertThat(state.startDmActionState).isEqualTo(startDMFailureResult)
|
assertThat(state.startDmActionState).isEqualTo(startDMFailureResult)
|
||||||
state.eventSink(UserProfileEvents.ClearStartDMState)
|
state.eventSink(UserProfileEvents.ClearStartDMState)
|
||||||
|
|
@ -292,8 +342,8 @@ class RoomMemberDetailsPresenterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createRoomMemberDetailsPresenter(
|
private fun createRoomMemberDetailsPresenter(
|
||||||
|
room: MatrixRoom,
|
||||||
client: MatrixClient = FakeMatrixClient(),
|
client: MatrixClient = FakeMatrixClient(),
|
||||||
room: MatrixRoom = aMatrixRoom(),
|
|
||||||
roomMemberId: UserId = UserId("@alice:server.org"),
|
roomMemberId: UserId = UserId("@alice:server.org"),
|
||||||
startDMAction: StartDMAction = FakeStartDMAction()
|
startDMAction: StartDMAction = FakeStartDMAction()
|
||||||
): RoomMemberDetailsPresenter {
|
): RoomMemberDetailsPresenter {
|
||||||
|
|
|
||||||
|
|
@ -54,29 +54,34 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `canDisplayModerationActions - when user can kick other users, FF is enabled and room is not a DM returns true`() = runTest {
|
fun `canDisplayModerationActions - when user can kick other users, FF is enabled and room is not a DM returns true`() = runTest {
|
||||||
val room = FakeMatrixRoom(isDirect = false, activeMemberCount = 10).apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
isDirect = false,
|
||||||
}
|
activeMemberCount = 10,
|
||||||
|
canKickResult = { Result.success(true) },
|
||||||
|
canBanResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
assertThat(presenter.canDisplayModerationActions()).isTrue()
|
assertThat(presenter.canDisplayModerationActions()).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `canDisplayModerationActions - when user can ban other users, FF is enabled and room is not a DM returns true`() = runTest {
|
fun `canDisplayModerationActions - when user can ban other users, FF is enabled and room is not a DM returns true`() = runTest {
|
||||||
val room = FakeMatrixRoom(isDirect = false, activeMemberCount = 10).apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanBanResult(Result.success(true))
|
isDirect = false,
|
||||||
}
|
activeMemberCount = 10,
|
||||||
|
canBanResult = { Result.success(true) },
|
||||||
|
)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
assertThat(presenter.canDisplayModerationActions()).isTrue()
|
assertThat(presenter.canDisplayModerationActions()).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - SelectRoomMember when the current user has permissions displays member actions`() = runTest {
|
fun `present - SelectRoomMember when the current user has permissions displays member actions`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
}
|
)
|
||||||
val selectedMember = aVictor()
|
val selectedMember = aVictor()
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -98,11 +103,12 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - SelectRoomMember displays only view profile if selected member has same power level as the current user`() = runTest {
|
fun `present - SelectRoomMember displays only view profile if selected member has same power level as the current user`() = runTest {
|
||||||
val room = FakeMatrixRoom(sessionId = A_USER_ID).apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
sessionId = A_USER_ID,
|
||||||
givenCanBanResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
canBanResult = { Result.success(true) },
|
||||||
}
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
|
)
|
||||||
val selectedMember = aRoomMember(A_USER_ID_2, powerLevel = 100L)
|
val selectedMember = aRoomMember(A_USER_ID_2, powerLevel = 100L)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -123,11 +129,11 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - SelectRoomMember displays an unban confirmation dialog when the member is banned`() = runTest {
|
fun `present - SelectRoomMember displays an unban confirmation dialog when the member is banned`() = runTest {
|
||||||
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
|
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
}
|
)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -144,11 +150,12 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - Kick removes the user`() = runTest {
|
fun `present - Kick removes the user`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
}
|
kickUserResult = { _, _ -> Result.success(Unit) },
|
||||||
|
)
|
||||||
val selectedMember = aVictor()
|
val selectedMember = aVictor()
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -171,11 +178,12 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - BanUser requires confirmation and then bans the user`() = runTest {
|
fun `present - BanUser requires confirmation and then bans the user`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
}
|
banUserResult = { _, _ -> Result.success(Unit) },
|
||||||
|
)
|
||||||
val selectedMember = aVictor()
|
val selectedMember = aVictor()
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -204,11 +212,13 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
fun `present - UnbanUser requires confirmation and then unbans the user`() = runTest {
|
fun `present - UnbanUser requires confirmation and then unbans the user`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
|
val selectedMember = aRoomMember(A_USER_ID_2, membership = RoomMembershipState.BAN)
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
|
userRoleResult = { Result.success(RoomMember.Role.ADMIN) },
|
||||||
|
unBanUserResult = { _, _ -> Result.success(Unit) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(selectedMember)))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(selectedMember)))
|
||||||
givenUserRoleResult(Result.success(RoomMember.Role.ADMIN))
|
|
||||||
}
|
}
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room, analyticsService = analyticsService)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -231,10 +241,11 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Reset removes the selected user and actions`() = runTest {
|
fun `present - Reset removes the selected user and actions`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
}
|
userRoleResult = { Result.success(RoomMember.Role.USER) },
|
||||||
|
)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -251,13 +262,14 @@ class DefaultRoomMembersModerationPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Reset resets any async actions`() = runTest {
|
fun `present - Reset resets any async actions`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenCanKickResult(Result.success(true))
|
canKickResult = { Result.success(true) },
|
||||||
givenCanBanResult(Result.success(true))
|
canBanResult = { Result.success(true) },
|
||||||
givenKickUserResult(Result.failure(Throwable("Eek")))
|
kickUserResult = { _, _ -> Result.failure(Throwable("Eek")) },
|
||||||
givenBanUserResult(Result.failure(Throwable("Eek")))
|
banUserResult = { _, _ -> Result.failure(Throwable("Eek")) },
|
||||||
givenUnbanUserResult(Result.failure(Throwable("Eek")))
|
unBanUserResult = { _, _ -> Result.failure(Throwable("Eek")) },
|
||||||
}
|
userRoleResult = { Result.success(RoomMember.Role.USER) },
|
||||||
|
)
|
||||||
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevels
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
|
@ -67,7 +68,12 @@ class RolesAndPermissionPresenterTest {
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@Test
|
@Test
|
||||||
fun `present - DemoteSelfTo changes own role to the specified one`() = runTest(StandardTestDispatcher()) {
|
fun `present - DemoteSelfTo changes own role to the specified one`() = runTest(StandardTestDispatcher()) {
|
||||||
val presenter = createRolesAndPermissionsPresenter(dispatchers = testCoroutineDispatchers())
|
val presenter = createRolesAndPermissionsPresenter(
|
||||||
|
dispatchers = testCoroutineDispatchers(),
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
updateUserRoleResult = { Result.success(Unit) }
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -85,9 +91,9 @@ class RolesAndPermissionPresenterTest {
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@Test
|
@Test
|
||||||
fun `present - DemoteSelfTo can handle failures and clean them`() = runTest(StandardTestDispatcher()) {
|
fun `present - DemoteSelfTo can handle failures and clean them`() = runTest(StandardTestDispatcher()) {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenUpdateUserRoleResult(Result.failure(Exception("Failed to update role")))
|
updateUserRoleResult = { Result.failure(Exception("Failed to update role")) }
|
||||||
}
|
)
|
||||||
val presenter = createRolesAndPermissionsPresenter(room = room, dispatchers = testCoroutineDispatchers())
|
val presenter = createRolesAndPermissionsPresenter(room = room, dispatchers = testCoroutineDispatchers())
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -123,7 +129,12 @@ class RolesAndPermissionPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - ResetPermissions needs confirmation, then resets permissions`() = runTest {
|
fun `present - ResetPermissions needs confirmation, then resets permissions`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val presenter = createRolesAndPermissionsPresenter(analyticsService = analyticsService)
|
val presenter = createRolesAndPermissionsPresenter(
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
resetPowerLevelsResult = { Result.success(defaultRoomPowerLevels()) }
|
||||||
|
)
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,10 @@ class ChangeRolesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save will display a confirmation when adding admins`() = runTest {
|
fun `present - Save will display a confirmation when adding admins`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
|
updateUserRoleResult = { Result.success(Unit) },
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
||||||
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
|
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 100)))
|
||||||
}
|
}
|
||||||
|
|
@ -325,7 +328,10 @@ class ChangeRolesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save will just save the data for moderators`() = runTest {
|
fun `present - Save will just save the data for moderators`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
|
updateUserRoleResult = { Result.success(Unit) },
|
||||||
|
updateMembersResult = { Result.success(Unit) },
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
||||||
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
|
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
|
||||||
}
|
}
|
||||||
|
|
@ -351,10 +357,11 @@ class ChangeRolesPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save can handle failures and ClearError clears them`() = runTest {
|
fun `present - Save can handle failures and ClearError clears them`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
|
updateUserRoleResult = { Result.failure(IllegalStateException("Failed")) }
|
||||||
|
).apply {
|
||||||
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList()))
|
||||||
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
|
givenRoomInfo(aRoomInfo(userPowerLevels = persistentMapOf(A_USER_ID to 50)))
|
||||||
givenUpdateUserRoleResult(Result.failure(IllegalStateException("Failed")))
|
|
||||||
}
|
}
|
||||||
val presenter = createChangeRolesPresenter(role = RoomMember.Role.MODERATOR, room = room)
|
val presenter = createChangeRolesPresenter(role = RoomMember.Role.MODERATOR, room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,13 @@ class ChangeRoomPermissionsPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save updates the current permissions and resets hasChanges`() = runTest {
|
fun `present - Save updates the current permissions and resets hasChanges`() = runTest {
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val presenter = createChangeRoomPermissionsPresenter(analyticsService = analyticsService)
|
val presenter = createChangeRoomPermissionsPresenter(
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
room = FakeMatrixRoom(
|
||||||
|
updatePowerLevelsResult = { Result.success(Unit) },
|
||||||
|
powerLevelsResult = { Result.success(defaultPermissions()) }
|
||||||
|
),
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -208,9 +214,9 @@ class ChangeRoomPermissionsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save will fail if there are not current permissions`() = runTest {
|
fun `present - Save will fail if there are not current permissions`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenPowerLevelsResult(Result.failure(IllegalStateException("Failed to load power levels")))
|
powerLevelsResult = { Result.failure(IllegalStateException("Failed to load power levels")) }
|
||||||
}
|
)
|
||||||
val presenter = createChangeRoomPermissionsPresenter(room = room)
|
val presenter = createChangeRoomPermissionsPresenter(room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -225,9 +231,10 @@ class ChangeRoomPermissionsPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - Save can handle failures and they can be cleared`() = runTest {
|
fun `present - Save can handle failures and they can be cleared`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenUpdatePowerLevelsResult(Result.failure(IllegalStateException("Failed to update power levels")))
|
powerLevelsResult = { Result.success(defaultPermissions()) },
|
||||||
}
|
updatePowerLevelsResult = { Result.failure(IllegalStateException("Failed to update power levels")) },
|
||||||
|
)
|
||||||
val presenter = createChangeRoomPermissionsPresenter(room = room)
|
val presenter = createChangeRoomPermissionsPresenter(room = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -292,7 +299,9 @@ class ChangeRoomPermissionsPresenterTest {
|
||||||
|
|
||||||
private fun createChangeRoomPermissionsPresenter(
|
private fun createChangeRoomPermissionsPresenter(
|
||||||
section: ChangeRoomPermissionsSection = ChangeRoomPermissionsSection.RoomDetails,
|
section: ChangeRoomPermissionsSection = ChangeRoomPermissionsSection.RoomDetails,
|
||||||
room: FakeMatrixRoom = FakeMatrixRoom(),
|
room: FakeMatrixRoom = FakeMatrixRoom(
|
||||||
|
powerLevelsResult = { Result.success(defaultPermissions()) }
|
||||||
|
),
|
||||||
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||||
) = ChangeRoomPermissionsPresenter(
|
) = ChangeRoomPermissionsPresenter(
|
||||||
section = section,
|
section = section,
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,10 @@ class RoomListPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
|
fun `present - when set is favorite event is emitted, then the action is called`() = runTest {
|
||||||
val scope = CoroutineScope(coroutineContext + SupervisorJob())
|
val scope = CoroutineScope(coroutineContext + SupervisorJob())
|
||||||
val room = FakeMatrixRoom()
|
val setIsFavoriteResult = lambdaRecorder { _: Boolean -> Result.success(Unit) }
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
setIsFavoriteResult = setIsFavoriteResult
|
||||||
|
)
|
||||||
val analyticsService = FakeAnalyticsService()
|
val analyticsService = FakeAnalyticsService()
|
||||||
val client = FakeMatrixClient().apply {
|
val client = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, room)
|
givenGetRoomResult(A_ROOM_ID, room)
|
||||||
|
|
@ -452,9 +455,13 @@ class RoomListPresenterTest {
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomListEvents.SetRoomIsFavorite(A_ROOM_ID, true))
|
initialState.eventSink(RoomListEvents.SetRoomIsFavorite(A_ROOM_ID, true))
|
||||||
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true))
|
setIsFavoriteResult.assertions().isCalledOnce().with(value(true))
|
||||||
initialState.eventSink(RoomListEvents.SetRoomIsFavorite(A_ROOM_ID, false))
|
initialState.eventSink(RoomListEvents.SetRoomIsFavorite(A_ROOM_ID, false))
|
||||||
assertThat(room.setIsFavoriteCalls).isEqualTo(listOf(true, false))
|
setIsFavoriteResult.assertions().isCalledExactly(2)
|
||||||
|
.withSequence(
|
||||||
|
listOf(value(true)),
|
||||||
|
listOf(value(false)),
|
||||||
|
)
|
||||||
assertThat(analyticsService.capturedEvents).containsExactly(
|
assertThat(analyticsService.capturedEvents).containsExactly(
|
||||||
Interaction(name = Interaction.Name.MobileRoomListRoomContextMenuFavouriteToggle),
|
Interaction(name = Interaction.Name.MobileRoomListRoomContextMenuFavouriteToggle),
|
||||||
Interaction(name = Interaction.Name.MobileRoomListRoomContextMenuFavouriteToggle)
|
Interaction(name = Interaction.Name.MobileRoomListRoomContextMenuFavouriteToggle)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.test.A_MESSAGE
|
import io.element.android.libraries.matrix.test.A_MESSAGE
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
import io.element.android.libraries.mediaupload.api.MediaPreProcessor
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
|
|
@ -92,7 +93,9 @@ class SharePresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - send text ok`() = runTest {
|
fun `present - send text ok`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom()
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendMessageResult = { _, _, _ -> Result.success(Unit) },
|
||||||
|
)
|
||||||
val matrixClient = FakeMatrixClient().apply {
|
val matrixClient = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, matrixRoom)
|
givenGetRoomResult(A_ROOM_ID, matrixRoom)
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +120,9 @@ class SharePresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - send media ok`() = runTest {
|
fun `present - send media ok`() = runTest {
|
||||||
val matrixRoom = FakeMatrixRoom()
|
val matrixRoom = FakeMatrixRoom(
|
||||||
|
sendMediaResult = { Result.success(FakeMediaUploadHandler()) },
|
||||||
|
)
|
||||||
val matrixClient = FakeMatrixClient().apply {
|
val matrixClient = FakeMatrixClient().apply {
|
||||||
givenGetRoomResult(A_ROOM_ID, matrixRoom)
|
givenGetRoomResult(A_ROOM_ID, matrixRoom)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ signing.element.nightly.keyPassword=Secret
|
||||||
|
|
||||||
# Customise the Lint version to use a more recent version than the one bundled with AGP
|
# Customise the Lint version to use a more recent version than the one bundled with AGP
|
||||||
# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html
|
# https://googlesamples.github.io/android-custom-lint-rules/usage/newer-lint.md.html
|
||||||
android.experimental.lint.version=8.5.0-alpha07
|
android.experimental.lint.version=8.7.0-alpha01
|
||||||
|
|
||||||
# Enable test fixture for all modules by default
|
# Enable test fixture for all modules by default
|
||||||
android.experimental.enableTestFixtures=true
|
android.experimental.enableTestFixtures=true
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.matrix.test.widget.FakeMatrixWidgetDriver
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
import io.element.android.tests.testutils.simulateLongTask
|
import io.element.android.tests.testutils.simulateLongTask
|
||||||
import kotlinx.collections.immutable.ImmutableMap
|
import kotlinx.collections.immutable.ImmutableMap
|
||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
|
|
@ -84,126 +84,88 @@ class FakeMatrixRoom(
|
||||||
override val activeMemberCount: Long = 234L,
|
override val activeMemberCount: Long = 234L,
|
||||||
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
|
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
|
||||||
override val liveTimeline: Timeline = FakeTimeline(),
|
override val liveTimeline: Timeline = FakeTimeline(),
|
||||||
private var roomPermalinkResult: () -> Result<String> = { Result.success("room link") },
|
private var roomPermalinkResult: () -> Result<String> = { lambdaError() },
|
||||||
private var eventPermalinkResult: (EventId) -> Result<String> = { Result.success("event link") },
|
private var eventPermalinkResult: (EventId) -> Result<String> = { lambdaError() },
|
||||||
var sendCallNotificationIfNeededResult: () -> Result<Unit> = { Result.success(Unit) },
|
private val sendCallNotificationIfNeededResult: () -> Result<Unit> = { lambdaError() },
|
||||||
canRedactOwn: Boolean = false,
|
private val userDisplayNameResult: () -> Result<String?> = { lambdaError() },
|
||||||
canRedactOther: Boolean = false,
|
private val userAvatarUrlResult: () -> Result<String?> = { lambdaError() },
|
||||||
|
private val userRoleResult: () -> Result<RoomMember.Role> = { lambdaError() },
|
||||||
|
private val getUpdatedMemberResult: (UserId) -> Result<RoomMember> = { lambdaError() },
|
||||||
|
private val joinRoomResult: () -> Result<Unit> = { lambdaError() },
|
||||||
|
private val inviteUserResult: (UserId) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val canInviteResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canKickResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canBanResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canRedactOwnResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canRedactOtherResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canSendStateResult: (UserId, StateEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
|
||||||
|
private val canUserSendMessageResult: (UserId, MessageEventType) -> Result<Boolean> = { _, _ -> lambdaError() },
|
||||||
|
private val sendMediaResult: (ProgressCallback?) -> Result<FakeMediaUploadHandler> = { lambdaError() },
|
||||||
|
private val setNameResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val setTopicResult: (String) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val updateAvatarResult: (String, ByteArray) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val removeAvatarResult: () -> Result<Unit> = { lambdaError() },
|
||||||
|
private val sendMessageResult: (String, String?, List<Mention>) -> Result<Unit> = { _, _, _ -> lambdaError() },
|
||||||
|
private val updateUserRoleResult: () -> Result<Unit> = { lambdaError() },
|
||||||
|
private val toggleReactionResult: (String, EventId) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val retrySendMessageResult: (TransactionId) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val cancelSendResult: (TransactionId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val forwardEventResult: (EventId, List<RoomId>) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val reportContentResult: (EventId, String, UserId?) -> Result<Unit> = { _, _, _ -> lambdaError() },
|
||||||
|
private val kickUserResult: (UserId, String?) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val banUserResult: (UserId, String?) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val unBanUserResult: (UserId, String?) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val sendLocationResult: (String, String, String?, Int?, AssetType?) -> Result<Unit> = { _, _, _, _, _ -> lambdaError() },
|
||||||
|
private val createPollResult: (String, List<String>, Int, PollKind) -> Result<Unit> = { _, _, _, _ -> lambdaError() },
|
||||||
|
private val editPollResult: (EventId, String, List<String>, Int, PollKind) -> Result<Unit> = { _, _, _, _, _ -> lambdaError() },
|
||||||
|
private val sendPollResponseResult: (EventId, List<String>) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val endPollResult: (EventId, String) -> Result<Unit> = { _, _ -> lambdaError() },
|
||||||
|
private val progressCallbackValues: List<Pair<Long, Long>> = emptyList(),
|
||||||
|
private val generateWidgetWebViewUrlResult: (MatrixWidgetSettings, String, String?, String?) -> Result<String> = { _, _, _, _ -> lambdaError() },
|
||||||
|
private val getWidgetDriverResult: (MatrixWidgetSettings) -> Result<MatrixWidgetDriver> = { lambdaError() },
|
||||||
|
private val canUserTriggerRoomNotificationResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val canUserJoinCallResult: (UserId) -> Result<Boolean> = { lambdaError() },
|
||||||
|
private val setIsFavoriteResult: (Boolean) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val powerLevelsResult: () -> Result<MatrixRoomPowerLevels> = { lambdaError() },
|
||||||
|
private val updatePowerLevelsResult: () -> Result<Unit> = { lambdaError() },
|
||||||
|
private val resetPowerLevelsResult: () -> Result<MatrixRoomPowerLevels> = { lambdaError() },
|
||||||
|
private val typingNoticeResult: (Boolean) -> Result<Unit> = { lambdaError() },
|
||||||
|
private val leaveRoomLambda: () -> Result<Unit> = { lambdaError() },
|
||||||
|
private val updateMembersResult: () -> Unit = { lambdaError() },
|
||||||
|
private val getMembersResult: (Int) -> Result<List<RoomMember>> = { lambdaError() },
|
||||||
|
private val timelineFocusedOnEventResult: (EventId) -> Result<Timeline> = { lambdaError() },
|
||||||
|
private val setSendQueueEnabledLambda: (Boolean) -> Unit = { _: Boolean -> },
|
||||||
|
private val saveComposerDraftLambda: (ComposerDraft) -> Result<Unit> = { _: ComposerDraft -> Result.success(Unit) },
|
||||||
|
private val loadComposerDraftLambda: () -> Result<ComposerDraft?> = { Result.success<ComposerDraft?>(null) },
|
||||||
|
private val clearComposerDraftLambda: () -> Result<Unit> = { Result.success(Unit) },
|
||||||
) : MatrixRoom {
|
) : MatrixRoom {
|
||||||
private var ignoreResult: Result<Unit> = Result.success(Unit)
|
|
||||||
private var unignoreResult: Result<Unit> = Result.success(Unit)
|
|
||||||
private var userDisplayNameResult = Result.success<String?>(null)
|
|
||||||
private var userAvatarUrlResult = Result.success<String?>(null)
|
|
||||||
private var userRoleResult = Result.success(RoomMember.Role.USER)
|
|
||||||
private var getRoomMemberResult = Result.failure<RoomMember>(IllegalStateException("Member not found"))
|
|
||||||
private var joinRoomResult = Result.success(Unit)
|
|
||||||
private var inviteUserResult = Result.success(Unit)
|
|
||||||
private var canInviteResult = Result.success(true)
|
|
||||||
private var canKickResult = Result.success(false)
|
|
||||||
private var canBanResult = Result.success(false)
|
|
||||||
private var canRedactOwnResult = Result.success(canRedactOwn)
|
|
||||||
private var canRedactOtherResult = Result.success(canRedactOther)
|
|
||||||
private val canSendStateResults = mutableMapOf<StateEventType, Result<Boolean>>()
|
|
||||||
private val canSendEventResults = mutableMapOf<MessageEventType, Result<Boolean>>()
|
|
||||||
private var sendMediaResult = Result.success(FakeMediaUploadHandler())
|
|
||||||
private var setNameResult = Result.success(Unit)
|
|
||||||
private var setTopicResult = Result.success(Unit)
|
|
||||||
private var updateAvatarResult = Result.success(Unit)
|
|
||||||
private var removeAvatarResult = Result.success(Unit)
|
|
||||||
private var updateUserRoleResult = Result.success(Unit)
|
|
||||||
private var toggleReactionResult = Result.success(Unit)
|
|
||||||
private var retrySendMessageResult = Result.success(Unit)
|
|
||||||
private var cancelSendResult = Result.success(true)
|
|
||||||
private var forwardEventResult = Result.success(Unit)
|
|
||||||
private var reportContentResult = Result.success(Unit)
|
|
||||||
private var kickUserResult = Result.success(Unit)
|
|
||||||
private var banUserResult = Result.success(Unit)
|
|
||||||
private var unBanUserResult = Result.success(Unit)
|
|
||||||
private var sendLocationResult = Result.success(Unit)
|
|
||||||
private var createPollResult = Result.success(Unit)
|
|
||||||
private var editPollResult = Result.success(Unit)
|
|
||||||
private var sendPollResponseResult = Result.success(Unit)
|
|
||||||
private var endPollResult = Result.success(Unit)
|
|
||||||
private var progressCallbackValues = emptyList<Pair<Long, Long>>()
|
|
||||||
private var generateWidgetWebViewUrlResult = Result.success("https://call.element.io")
|
|
||||||
private var getWidgetDriverResult: Result<MatrixWidgetDriver> = Result.success(FakeMatrixWidgetDriver())
|
|
||||||
private var canUserTriggerRoomNotificationResult: Result<Boolean> = Result.success(true)
|
|
||||||
private var canUserJoinCallResult: Result<Boolean> = Result.success(true)
|
|
||||||
private var setIsFavoriteResult = Result.success(Unit)
|
|
||||||
private var powerLevelsResult = Result.success(defaultRoomPowerLevels())
|
|
||||||
private var updatePowerLevelsResult = Result.success(Unit)
|
|
||||||
private var resetPowerLevelsResult = Result.success(defaultRoomPowerLevels())
|
|
||||||
var sendMessageMentions = emptyList<Mention>()
|
|
||||||
private val _typingRecord = mutableListOf<Boolean>()
|
|
||||||
val typingRecord: List<Boolean>
|
|
||||||
get() = _typingRecord
|
|
||||||
|
|
||||||
var sendMediaCount = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val _myReactions = mutableSetOf<String>()
|
|
||||||
val myReactions: Set<String> = _myReactions
|
|
||||||
|
|
||||||
var retrySendMessageCount: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
var cancelSendCount: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
var reportedContentCount: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val _sentLocations = mutableListOf<SendLocationInvocation>()
|
|
||||||
val sentLocations: List<SendLocationInvocation> = _sentLocations
|
|
||||||
|
|
||||||
private val _createPollInvocations = mutableListOf<SavePollInvocation>()
|
|
||||||
val createPollInvocations: List<SavePollInvocation> = _createPollInvocations
|
|
||||||
|
|
||||||
private val _editPollInvocations = mutableListOf<SavePollInvocation>()
|
|
||||||
val editPollInvocations: List<SavePollInvocation> = _editPollInvocations
|
|
||||||
|
|
||||||
private val _sendPollResponseInvocations = mutableListOf<SendPollResponseInvocation>()
|
|
||||||
val sendPollResponseInvocations: List<SendPollResponseInvocation> = _sendPollResponseInvocations
|
|
||||||
|
|
||||||
private val _endPollInvocations = mutableListOf<EndPollInvocation>()
|
|
||||||
val endPollInvocations: List<EndPollInvocation> = _endPollInvocations
|
|
||||||
|
|
||||||
var invitedUserId: UserId? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
var newTopic: String? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
var newName: String? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
var newAvatarData: ByteArray? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
var removedAvatar: Boolean = false
|
|
||||||
private set
|
|
||||||
|
|
||||||
var leaveRoomLambda: (() -> Result<Unit>) = { Result.success(Unit) }
|
|
||||||
|
|
||||||
private val _roomInfoFlow: MutableSharedFlow<MatrixRoomInfo> = MutableSharedFlow(replay = 1)
|
private val _roomInfoFlow: MutableSharedFlow<MatrixRoomInfo> = MutableSharedFlow(replay = 1)
|
||||||
override val roomInfoFlow: Flow<MatrixRoomInfo> = _roomInfoFlow
|
override val roomInfoFlow: Flow<MatrixRoomInfo> = _roomInfoFlow
|
||||||
|
|
||||||
|
fun givenRoomInfo(roomInfo: MatrixRoomInfo) {
|
||||||
|
_roomInfoFlow.tryEmit(roomInfo)
|
||||||
|
}
|
||||||
|
|
||||||
private val _roomTypingMembersFlow: MutableSharedFlow<List<UserId>> = MutableSharedFlow(replay = 1)
|
private val _roomTypingMembersFlow: MutableSharedFlow<List<UserId>> = MutableSharedFlow(replay = 1)
|
||||||
override val roomTypingMembersFlow: Flow<List<UserId>> = _roomTypingMembersFlow
|
override val roomTypingMembersFlow: Flow<List<UserId>> = _roomTypingMembersFlow
|
||||||
|
|
||||||
|
fun givenRoomTypingMembers(typingMembers: List<UserId>) {
|
||||||
|
_roomTypingMembersFlow.tryEmit(typingMembers)
|
||||||
|
}
|
||||||
|
|
||||||
override val membersStateFlow: MutableStateFlow<MatrixRoomMembersState> = MutableStateFlow(MatrixRoomMembersState.Unknown)
|
override val membersStateFlow: MutableStateFlow<MatrixRoomMembersState> = MutableStateFlow(MatrixRoomMembersState.Unknown)
|
||||||
|
|
||||||
override val roomNotificationSettingsStateFlow: MutableStateFlow<MatrixRoomNotificationSettingsState> =
|
override val roomNotificationSettingsStateFlow: MutableStateFlow<MatrixRoomNotificationSettingsState> =
|
||||||
MutableStateFlow(MatrixRoomNotificationSettingsState.Unknown)
|
MutableStateFlow(MatrixRoomNotificationSettingsState.Unknown)
|
||||||
|
|
||||||
override suspend fun updateMembers() = Unit
|
override suspend fun updateMembers() = updateMembersResult()
|
||||||
|
|
||||||
override suspend fun getUpdatedMember(userId: UserId): Result<RoomMember> {
|
override suspend fun getUpdatedMember(userId: UserId): Result<RoomMember> {
|
||||||
return getRoomMemberResult
|
return getUpdatedMemberResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getMembers(limit: Int): Result<List<RoomMember>> {
|
override suspend fun getMembers(limit: Int): Result<List<RoomMember>> {
|
||||||
return Result.success(emptyList())
|
return getMembersResult(limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateRoomNotificationSettings(): Result<Unit> = simulateLongTask {
|
override suspend fun updateRoomNotificationSettings(): Result<Unit> = simulateLongTask {
|
||||||
|
|
@ -214,76 +176,56 @@ class FakeMatrixRoom(
|
||||||
|
|
||||||
override val syncUpdateFlow: StateFlow<Long> = MutableStateFlow(0L)
|
override val syncUpdateFlow: StateFlow<Long> = MutableStateFlow(0L)
|
||||||
|
|
||||||
private var timelineFocusedOnEventResult: Result<Timeline> = Result.success(FakeTimeline())
|
|
||||||
|
|
||||||
fun givenTimelineFocusedOnEventResult(result: Result<Timeline>) {
|
|
||||||
timelineFocusedOnEventResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun timelineFocusedOnEvent(eventId: EventId): Result<Timeline> = simulateLongTask {
|
override suspend fun timelineFocusedOnEvent(eventId: EventId): Result<Timeline> = simulateLongTask {
|
||||||
timelineFocusedOnEventResult
|
timelineFocusedOnEventResult(eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun subscribeToSync() = Unit
|
override suspend fun subscribeToSync() = Unit
|
||||||
|
|
||||||
override suspend fun powerLevels(): Result<MatrixRoomPowerLevels> {
|
override suspend fun powerLevels(): Result<MatrixRoomPowerLevels> {
|
||||||
return powerLevelsResult
|
return powerLevelsResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updatePowerLevels(matrixRoomPowerLevels: MatrixRoomPowerLevels): Result<Unit> = simulateLongTask {
|
override suspend fun updatePowerLevels(matrixRoomPowerLevels: MatrixRoomPowerLevels): Result<Unit> = simulateLongTask {
|
||||||
updatePowerLevelsResult
|
updatePowerLevelsResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun resetPowerLevels(): Result<MatrixRoomPowerLevels> = simulateLongTask {
|
override suspend fun resetPowerLevels(): Result<MatrixRoomPowerLevels> = simulateLongTask {
|
||||||
resetPowerLevelsResult
|
resetPowerLevelsResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun destroy() = Unit
|
override fun destroy() = Unit
|
||||||
|
|
||||||
override suspend fun userDisplayName(userId: UserId): Result<String?> = simulateLongTask {
|
override suspend fun userDisplayName(userId: UserId): Result<String?> = simulateLongTask {
|
||||||
userDisplayNameResult
|
userDisplayNameResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun userAvatarUrl(userId: UserId): Result<String?> = simulateLongTask {
|
override suspend fun userAvatarUrl(userId: UserId): Result<String?> = simulateLongTask {
|
||||||
userAvatarUrlResult
|
userAvatarUrlResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun userRole(userId: UserId): Result<RoomMember.Role> {
|
override suspend fun userRole(userId: UserId): Result<RoomMember.Role> {
|
||||||
return userRoleResult
|
return userRoleResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateUsersRoles(changes: List<UserRoleChange>): Result<Unit> {
|
override suspend fun updateUsersRoles(changes: List<UserRoleChange>): Result<Unit> {
|
||||||
return updateUserRoleResult
|
return updateUserRoleResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List<Mention>) = simulateLongTask {
|
override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List<Mention>) = simulateLongTask {
|
||||||
sendMessageMentions = mentions
|
sendMessageResult(body, htmlBody, mentions)
|
||||||
Result.success(Unit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> {
|
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> {
|
||||||
if (toggleReactionResult.isFailure) {
|
return toggleReactionResult(emoji, eventId)
|
||||||
// Don't do the toggle if we failed
|
|
||||||
return toggleReactionResult
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_myReactions.contains(emoji)) {
|
|
||||||
_myReactions.remove(emoji)
|
|
||||||
} else {
|
|
||||||
_myReactions.add(emoji)
|
|
||||||
}
|
|
||||||
|
|
||||||
return toggleReactionResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit> {
|
override suspend fun retrySendMessage(transactionId: TransactionId): Result<Unit> {
|
||||||
retrySendMessageCount++
|
return retrySendMessageResult(transactionId)
|
||||||
return retrySendMessageResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun cancelSend(transactionId: TransactionId): Result<Boolean> {
|
override suspend fun cancelSend(transactionId: TransactionId): Result<Boolean> {
|
||||||
cancelSendCount++
|
return cancelSendResult(transactionId)
|
||||||
return cancelSendResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getPermalink(): Result<String> {
|
override suspend fun getPermalink(): Result<String> {
|
||||||
|
|
@ -299,48 +241,47 @@ class FakeMatrixRoom(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun join(): Result<Unit> {
|
override suspend fun join(): Result<Unit> {
|
||||||
return joinRoomResult
|
return joinRoomResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun inviteUserById(id: UserId): Result<Unit> = simulateLongTask {
|
override suspend fun inviteUserById(id: UserId): Result<Unit> = simulateLongTask {
|
||||||
invitedUserId = id
|
inviteUserResult(id)
|
||||||
inviteUserResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserBan(userId: UserId): Result<Boolean> {
|
override suspend fun canUserBan(userId: UserId): Result<Boolean> {
|
||||||
return canBanResult
|
return canBanResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserKick(userId: UserId): Result<Boolean> {
|
override suspend fun canUserKick(userId: UserId): Result<Boolean> {
|
||||||
return canKickResult
|
return canKickResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserInvite(userId: UserId): Result<Boolean> {
|
override suspend fun canUserInvite(userId: UserId): Result<Boolean> {
|
||||||
return canInviteResult
|
return canInviteResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserRedactOwn(userId: UserId): Result<Boolean> {
|
override suspend fun canUserRedactOwn(userId: UserId): Result<Boolean> {
|
||||||
return canRedactOwnResult
|
return canRedactOwnResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserRedactOther(userId: UserId): Result<Boolean> {
|
override suspend fun canUserRedactOther(userId: UserId): Result<Boolean> {
|
||||||
return canRedactOtherResult
|
return canRedactOtherResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> {
|
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> {
|
||||||
return canSendStateResults[type] ?: Result.failure(IllegalStateException("No fake answer"))
|
return canSendStateResult(userId, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result<Boolean> {
|
override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result<Boolean> {
|
||||||
return canSendEventResults[type] ?: Result.failure(IllegalStateException("No fake answer"))
|
return canUserSendMessageResult(userId, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserTriggerRoomNotification(userId: UserId): Result<Boolean> {
|
override suspend fun canUserTriggerRoomNotification(userId: UserId): Result<Boolean> {
|
||||||
return canUserTriggerRoomNotificationResult
|
return canUserTriggerRoomNotificationResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun canUserJoinCall(userId: UserId): Result<Boolean> {
|
override suspend fun canUserJoinCall(userId: UserId): Result<Boolean> {
|
||||||
return canUserJoinCallResult
|
return canUserJoinCallResult(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendImage(
|
override suspend fun sendImage(
|
||||||
|
|
@ -376,37 +317,31 @@ class FakeMatrixRoom(
|
||||||
): Result<MediaUploadHandler> = fakeSendMedia(progressCallback)
|
): Result<MediaUploadHandler> = fakeSendMedia(progressCallback)
|
||||||
|
|
||||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = simulateLongTask {
|
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = simulateLongTask {
|
||||||
forwardEventResult
|
forwardEventResult(eventId, roomIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fakeSendMedia(progressCallback: ProgressCallback?): Result<MediaUploadHandler> = simulateLongTask {
|
private suspend fun fakeSendMedia(progressCallback: ProgressCallback?): Result<MediaUploadHandler> = simulateLongTask {
|
||||||
sendMediaResult.onSuccess {
|
progressCallbackValues.forEach { (current, total) ->
|
||||||
progressCallbackValues.forEach { (current, total) ->
|
progressCallback?.onProgress(current, total)
|
||||||
progressCallback?.onProgress(current, total)
|
delay(1)
|
||||||
delay(1)
|
|
||||||
}
|
|
||||||
sendMediaCount++
|
|
||||||
}
|
}
|
||||||
|
sendMediaResult(progressCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateAvatar(mimeType: String, data: ByteArray): Result<Unit> = simulateLongTask {
|
override suspend fun updateAvatar(mimeType: String, data: ByteArray): Result<Unit> = simulateLongTask {
|
||||||
newAvatarData = data
|
updateAvatarResult(mimeType, data)
|
||||||
updateAvatarResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun removeAvatar(): Result<Unit> = simulateLongTask {
|
override suspend fun removeAvatar(): Result<Unit> = simulateLongTask {
|
||||||
removedAvatar = true
|
removeAvatarResult()
|
||||||
removeAvatarResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setName(name: String): Result<Unit> = simulateLongTask {
|
override suspend fun setName(name: String): Result<Unit> = simulateLongTask {
|
||||||
newName = name
|
setNameResult(name)
|
||||||
setNameResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setTopic(topic: String): Result<Unit> = simulateLongTask {
|
override suspend fun setTopic(topic: String): Result<Unit> = simulateLongTask {
|
||||||
newTopic = topic
|
setTopicResult(topic)
|
||||||
setTopicResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun reportContent(
|
override suspend fun reportContent(
|
||||||
|
|
@ -414,28 +349,23 @@ class FakeMatrixRoom(
|
||||||
reason: String,
|
reason: String,
|
||||||
blockUserId: UserId?
|
blockUserId: UserId?
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
reportedContentCount++
|
return reportContentResult(eventId, reason, blockUserId)
|
||||||
return reportContentResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun kickUser(userId: UserId, reason: String?): Result<Unit> {
|
override suspend fun kickUser(userId: UserId, reason: String?): Result<Unit> {
|
||||||
return kickUserResult
|
return kickUserResult(userId, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun banUser(userId: UserId, reason: String?): Result<Unit> {
|
override suspend fun banUser(userId: UserId, reason: String?): Result<Unit> {
|
||||||
return banUserResult
|
return banUserResult(userId, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun unbanUser(userId: UserId, reason: String?): Result<Unit> {
|
override suspend fun unbanUser(userId: UserId, reason: String?): Result<Unit> {
|
||||||
return unBanUserResult
|
return unBanUserResult(userId, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
val setIsFavoriteCalls = mutableListOf<Boolean>()
|
|
||||||
|
|
||||||
override suspend fun setIsFavorite(isFavorite: Boolean): Result<Unit> {
|
override suspend fun setIsFavorite(isFavorite: Boolean): Result<Unit> {
|
||||||
return setIsFavoriteResult.also {
|
return setIsFavoriteResult(isFavorite)
|
||||||
setIsFavoriteCalls.add(isFavorite)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val markAsReadCalls = mutableListOf<ReceiptType>()
|
val markAsReadCalls = mutableListOf<ReceiptType>()
|
||||||
|
|
@ -460,8 +390,13 @@ class FakeMatrixRoom(
|
||||||
zoomLevel: Int?,
|
zoomLevel: Int?,
|
||||||
assetType: AssetType?,
|
assetType: AssetType?,
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
_sentLocations.add(SendLocationInvocation(body, geoUri, description, zoomLevel, assetType))
|
return sendLocationResult(
|
||||||
return sendLocationResult
|
body,
|
||||||
|
geoUri,
|
||||||
|
description,
|
||||||
|
zoomLevel,
|
||||||
|
assetType,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createPoll(
|
override suspend fun createPoll(
|
||||||
|
|
@ -470,8 +405,12 @@ class FakeMatrixRoom(
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
pollKind: PollKind
|
pollKind: PollKind
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
_createPollInvocations.add(SavePollInvocation(question, answers, maxSelections, pollKind))
|
return createPollResult(
|
||||||
return createPollResult
|
question,
|
||||||
|
answers,
|
||||||
|
maxSelections,
|
||||||
|
pollKind,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun editPoll(
|
override suspend fun editPoll(
|
||||||
|
|
@ -481,24 +420,27 @@ class FakeMatrixRoom(
|
||||||
maxSelections: Int,
|
maxSelections: Int,
|
||||||
pollKind: PollKind
|
pollKind: PollKind
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
_editPollInvocations.add(SavePollInvocation(question, answers, maxSelections, pollKind))
|
return editPollResult(
|
||||||
return editPollResult
|
pollStartId,
|
||||||
|
question,
|
||||||
|
answers,
|
||||||
|
maxSelections,
|
||||||
|
pollKind,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendPollResponse(
|
override suspend fun sendPollResponse(
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
answers: List<String>
|
answers: List<String>
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
_sendPollResponseInvocations.add(SendPollResponseInvocation(pollStartId, answers))
|
return sendPollResponseResult(pollStartId, answers)
|
||||||
return sendPollResponseResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun endPoll(
|
override suspend fun endPoll(
|
||||||
pollStartId: EventId,
|
pollStartId: EventId,
|
||||||
text: String
|
text: String
|
||||||
): Result<Unit> = simulateLongTask {
|
): Result<Unit> = simulateLongTask {
|
||||||
_endPollInvocations.add(EndPollInvocation(pollStartId, text))
|
return endPollResult(pollStartId, text)
|
||||||
return endPollResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendVoiceMessage(
|
override suspend fun sendVoiceMessage(
|
||||||
|
|
@ -509,8 +451,7 @@ class FakeMatrixRoom(
|
||||||
): Result<MediaUploadHandler> = fakeSendMedia(progressCallback)
|
): Result<MediaUploadHandler> = fakeSendMedia(progressCallback)
|
||||||
|
|
||||||
override suspend fun typingNotice(isTyping: Boolean): Result<Unit> {
|
override suspend fun typingNotice(isTyping: Boolean): Result<Unit> {
|
||||||
_typingRecord += isTyping
|
return typingNoticeResult(isTyping)
|
||||||
return Result.success(Unit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun generateWidgetWebViewUrl(
|
override suspend fun generateWidgetWebViewUrl(
|
||||||
|
|
@ -518,228 +459,34 @@ class FakeMatrixRoom(
|
||||||
clientId: String,
|
clientId: String,
|
||||||
languageTag: String?,
|
languageTag: String?,
|
||||||
theme: String?,
|
theme: String?,
|
||||||
): Result<String> = generateWidgetWebViewUrlResult
|
): Result<String> = generateWidgetWebViewUrlResult(
|
||||||
|
widgetSettings,
|
||||||
|
clientId,
|
||||||
|
languageTag,
|
||||||
|
theme,
|
||||||
|
)
|
||||||
|
|
||||||
override suspend fun sendCallNotificationIfNeeded(): Result<Unit> {
|
override suspend fun sendCallNotificationIfNeeded(): Result<Unit> {
|
||||||
return sendCallNotificationIfNeededResult()
|
return sendCallNotificationIfNeededResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
var setSendQueueEnabledLambda = { _: Boolean -> }
|
|
||||||
override suspend fun setSendQueueEnabled(enabled: Boolean) = setSendQueueEnabledLambda(enabled)
|
override suspend fun setSendQueueEnabled(enabled: Boolean) = setSendQueueEnabledLambda(enabled)
|
||||||
|
|
||||||
var saveComposerDraftLambda = { _: ComposerDraft -> Result.success(Unit) }
|
|
||||||
override suspend fun saveComposerDraft(composerDraft: ComposerDraft) = saveComposerDraftLambda(composerDraft)
|
override suspend fun saveComposerDraft(composerDraft: ComposerDraft) = saveComposerDraftLambda(composerDraft)
|
||||||
|
|
||||||
var loadComposerDraftLambda = { Result.success<ComposerDraft?>(null) }
|
|
||||||
override suspend fun loadComposerDraft() = loadComposerDraftLambda()
|
override suspend fun loadComposerDraft() = loadComposerDraftLambda()
|
||||||
|
|
||||||
var clearComposerDraftLambda = { Result.success(Unit) }
|
|
||||||
override suspend fun clearComposerDraft() = clearComposerDraftLambda()
|
override suspend fun clearComposerDraft() = clearComposerDraftLambda()
|
||||||
|
|
||||||
override fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result<MatrixWidgetDriver> = getWidgetDriverResult
|
override fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result<MatrixWidgetDriver> {
|
||||||
|
return getWidgetDriverResult(widgetSettings)
|
||||||
|
}
|
||||||
|
|
||||||
fun givenRoomMembersState(state: MatrixRoomMembersState) {
|
fun givenRoomMembersState(state: MatrixRoomMembersState) {
|
||||||
membersStateFlow.value = state
|
membersStateFlow.value = state
|
||||||
}
|
}
|
||||||
|
|
||||||
fun givenGetRoomMemberResult(result: Result<RoomMember>) {
|
|
||||||
getRoomMemberResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUserDisplayNameResult(displayName: Result<String?>) {
|
|
||||||
userDisplayNameResult = displayName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUserAvatarUrlResult(avatarUrl: Result<String?>) {
|
|
||||||
userAvatarUrlResult = avatarUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUserRoleResult(role: Result<RoomMember.Role>) {
|
|
||||||
userRoleResult = role
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUpdateUserRoleResult(result: Result<Unit>) {
|
|
||||||
updateUserRoleResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenJoinRoomResult(result: Result<Unit>) {
|
|
||||||
joinRoomResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanKickResult(result: Result<Boolean>) {
|
|
||||||
canKickResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanBanResult(result: Result<Boolean>) {
|
|
||||||
canBanResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenInviteUserResult(result: Result<Unit>) {
|
|
||||||
inviteUserResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanInviteResult(result: Result<Boolean>) {
|
|
||||||
canInviteResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanSendStateResult(type: StateEventType, result: Result<Boolean>) {
|
|
||||||
canSendStateResults[type] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanSendEventResult(type: MessageEventType, result: Result<Boolean>) {
|
|
||||||
canSendEventResults[type] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanTriggerRoomNotification(result: Result<Boolean>) {
|
|
||||||
canUserTriggerRoomNotificationResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCanUserJoinCall(result: Result<Boolean>) {
|
|
||||||
canUserJoinCallResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenIgnoreResult(result: Result<Unit>) {
|
|
||||||
ignoreResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUnIgnoreResult(result: Result<Unit>) {
|
|
||||||
unignoreResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSendMediaResult(result: Result<FakeMediaUploadHandler>) {
|
|
||||||
sendMediaResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUpdateAvatarResult(result: Result<Unit>) {
|
|
||||||
updateAvatarResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenRemoveAvatarResult(result: Result<Unit>) {
|
|
||||||
removeAvatarResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSetNameResult(result: Result<Unit>) {
|
|
||||||
setNameResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSetTopicResult(result: Result<Unit>) {
|
|
||||||
setTopicResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenToggleReactionResult(result: Result<Unit>) {
|
|
||||||
toggleReactionResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenRetrySendMessageResult(result: Result<Unit>) {
|
|
||||||
retrySendMessageResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCancelSendResult(result: Result<Boolean>) {
|
|
||||||
cancelSendResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenForwardEventResult(result: Result<Unit>) {
|
|
||||||
forwardEventResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenReportContentResult(result: Result<Unit>) {
|
|
||||||
reportContentResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenKickUserResult(result: Result<Unit>) {
|
|
||||||
kickUserResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenBanUserResult(result: Result<Unit>) {
|
|
||||||
banUserResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUnbanUserResult(result: Result<Unit>) {
|
|
||||||
unBanUserResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSendLocationResult(result: Result<Unit>) {
|
|
||||||
sendLocationResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenCreatePollResult(result: Result<Unit>) {
|
|
||||||
createPollResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenEditPollResult(result: Result<Unit>) {
|
|
||||||
editPollResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSendPollResponseResult(result: Result<Unit>) {
|
|
||||||
sendPollResponseResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenEndPollResult(result: Result<Unit>) {
|
|
||||||
endPollResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenProgressCallbackValues(values: List<Pair<Long, Long>>) {
|
|
||||||
progressCallbackValues = values
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenGenerateWidgetWebViewUrlResult(result: Result<String>) {
|
|
||||||
generateWidgetWebViewUrlResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenGetWidgetDriverResult(result: Result<MatrixWidgetDriver>) {
|
|
||||||
getWidgetDriverResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenSetIsFavoriteResult(result: Result<Unit>) {
|
|
||||||
setIsFavoriteResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenRoomInfo(roomInfo: MatrixRoomInfo) {
|
|
||||||
_roomInfoFlow.tryEmit(roomInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenRoomTypingMembers(typingMembers: List<UserId>) {
|
|
||||||
_roomTypingMembersFlow.tryEmit(typingMembers)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenPowerLevelsResult(result: Result<MatrixRoomPowerLevels>) {
|
|
||||||
powerLevelsResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUpdatePowerLevelsResult(result: Result<Unit>) {
|
|
||||||
updatePowerLevelsResult = result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenResetPowerLevelsResult(result: Result<MatrixRoomPowerLevels>) {
|
|
||||||
resetPowerLevelsResult = result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class SendLocationInvocation(
|
|
||||||
val body: String,
|
|
||||||
val geoUri: String,
|
|
||||||
val description: String?,
|
|
||||||
val zoomLevel: Int?,
|
|
||||||
val assetType: AssetType?,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class SavePollInvocation(
|
|
||||||
val question: String,
|
|
||||||
val answers: List<String>,
|
|
||||||
val maxSelections: Int,
|
|
||||||
val pollKind: PollKind,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class SendPollResponseInvocation(
|
|
||||||
val pollStartId: EventId,
|
|
||||||
val answers: List<String>,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class EndPollInvocation(
|
|
||||||
val pollStartId: EventId,
|
|
||||||
val text: String,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun aRoomInfo(
|
fun aRoomInfo(
|
||||||
id: RoomId = A_ROOM_ID,
|
id: RoomId = A_ROOM_ID,
|
||||||
name: String? = A_ROOM_NAME,
|
name: String? = A_ROOM_NAME,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ android {
|
||||||
|
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
testImplementation(projects.libraries.mediaupload.test)
|
testImplementation(projects.libraries.mediaupload.test)
|
||||||
|
testImplementation(projects.tests.testutils)
|
||||||
testImplementation(libs.test.junit)
|
testImplementation(libs.test.junit)
|
||||||
testImplementation(libs.test.truth)
|
testImplementation(libs.test.truth)
|
||||||
testImplementation(libs.coroutines.test)
|
testImplementation(libs.coroutines.test)
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,12 @@ package io.element.android.libraries.mediaupload.api
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
|
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
|
|
@ -46,13 +49,17 @@ class MediaSenderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given an attachment when sending it the MatrixRoom will call sendMedia`() = runTest {
|
fun `given an attachment when sending it the MatrixRoom will call sendMedia`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val sendMediaResult = lambdaRecorder<ProgressCallback?, Result<FakeMediaUploadHandler>> {
|
||||||
|
Result.success(FakeMediaUploadHandler())
|
||||||
|
}
|
||||||
|
val room = FakeMatrixRoom(
|
||||||
|
sendMediaResult = sendMediaResult
|
||||||
|
)
|
||||||
val sender = aMediaSender(room = room)
|
val sender = aMediaSender(room = room)
|
||||||
|
|
||||||
val uri = Uri.parse("content://image.jpg")
|
val uri = Uri.parse("content://image.jpg")
|
||||||
sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
|
sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
|
||||||
|
sendMediaResult.assertions().isCalledOnce()
|
||||||
assertThat(room.sendMediaCount).isEqualTo(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -70,9 +77,9 @@ class MediaSenderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a failure in the media upload when sending the whole process fails`() = runTest {
|
fun `given a failure in the media upload when sending the whole process fails`() = runTest {
|
||||||
val room = FakeMatrixRoom().apply {
|
val room = FakeMatrixRoom(
|
||||||
givenSendMediaResult(Result.failure(Exception()))
|
sendMediaResult = { Result.failure(Exception()) }
|
||||||
}
|
)
|
||||||
val sender = aMediaSender(room = room)
|
val sender = aMediaSender(room = room)
|
||||||
|
|
||||||
val uri = Uri.parse("content://image.jpg")
|
val uri = Uri.parse("content://image.jpg")
|
||||||
|
|
@ -84,7 +91,9 @@ class MediaSenderTest {
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@Test
|
@Test
|
||||||
fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) {
|
fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom(
|
||||||
|
sendMediaResult = { Result.success(FakeMediaUploadHandler()) }
|
||||||
|
)
|
||||||
val sender = aMediaSender(room = room)
|
val sender = aMediaSender(room = room)
|
||||||
val sendJob = launch {
|
val sendJob = launch {
|
||||||
val uri = Uri.parse("content://image.jpg")
|
val uri = Uri.parse("content://image.jpg")
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
|
||||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.test.room.aRoomMember
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
|
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
|
||||||
|
|
@ -297,9 +298,9 @@ class NotificationBroadcastReceiverHandlerTest {
|
||||||
@Test
|
@Test
|
||||||
fun `Test reject room`() = runTest {
|
fun `Test reject room`() = runTest {
|
||||||
val leaveRoom = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
|
val leaveRoom = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
|
||||||
val matrixRoom = FakeMatrixRoom().apply {
|
val matrixRoom = FakeMatrixRoom(
|
||||||
leaveRoomLambda = leaveRoom
|
leaveRoomLambda = leaveRoom
|
||||||
}
|
)
|
||||||
val clearMembershipNotificationForRoomLambda = lambdaRecorder<SessionId, RoomId, Unit> { _, _ -> }
|
val clearMembershipNotificationForRoomLambda = lambdaRecorder<SessionId, RoomId, Unit> { _, _ -> }
|
||||||
val fakeNotificationCleaner = FakeNotificationCleaner(
|
val fakeNotificationCleaner = FakeNotificationCleaner(
|
||||||
clearMembershipNotificationForRoomLambda = clearMembershipNotificationForRoomLambda,
|
clearMembershipNotificationForRoomLambda = clearMembershipNotificationForRoomLambda,
|
||||||
|
|
@ -342,7 +343,8 @@ class NotificationBroadcastReceiverHandlerTest {
|
||||||
replyMessageLambda = replyMessage
|
replyMessageLambda = replyMessage
|
||||||
}
|
}
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
getUpdatedMemberResult = { Result.success(aRoomMember()) },
|
||||||
)
|
)
|
||||||
val onNotifiableEventReceivedResult = lambdaRecorder<NotifiableEvent, Unit> { _ -> }
|
val onNotifiableEventReceivedResult = lambdaRecorder<NotifiableEvent, Unit> { _ -> }
|
||||||
val onNotifiableEventReceived = FakeOnNotifiableEventReceived(onNotifiableEventReceivedResult = onNotifiableEventReceivedResult)
|
val onNotifiableEventReceived = FakeOnNotifiableEventReceived(onNotifiableEventReceivedResult = onNotifiableEventReceivedResult)
|
||||||
|
|
@ -400,7 +402,8 @@ class NotificationBroadcastReceiverHandlerTest {
|
||||||
replyMessageLambda = replyMessage
|
replyMessageLambda = replyMessage
|
||||||
}
|
}
|
||||||
val matrixRoom = FakeMatrixRoom(
|
val matrixRoom = FakeMatrixRoom(
|
||||||
liveTimeline = liveTimeline
|
liveTimeline = liveTimeline,
|
||||||
|
getUpdatedMemberResult = { Result.success(aRoomMember()) },
|
||||||
)
|
)
|
||||||
val onNotifiableEventReceivedResult = lambdaRecorder<NotifiableEvent, Unit> { _ -> }
|
val onNotifiableEventReceivedResult = lambdaRecorder<NotifiableEvent, Unit> { _ -> }
|
||||||
val onNotifiableEventReceived = FakeOnNotifiableEventReceived(onNotifiableEventReceivedResult = onNotifiableEventReceivedResult)
|
val onNotifiableEventReceived = FakeOnNotifiableEventReceived(onNotifiableEventReceivedResult = onNotifiableEventReceivedResult)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue