change(invites) : add some tests and update some fakes

This commit is contained in:
ganfra
2025-02-27 21:33:28 +01:00
parent 148fe9db43
commit abb0460bbb
4 changed files with 128 additions and 50 deletions

View File

@@ -63,7 +63,7 @@ class AcceptDeclineInvitePresenterTest {
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData))
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
InternalAcceptDeclineInviteEvents.CancelDeclineInvite
)
@@ -93,9 +93,9 @@ class AcceptDeclineInvitePresenterTest {
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData))
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite()
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
@@ -141,9 +141,9 @@ class AcceptDeclineInvitePresenterTest {
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData))
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite()
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
@@ -158,6 +158,80 @@ class AcceptDeclineInvitePresenterTest {
.with(value(A_SESSION_ID), value(A_ROOM_ID))
}
@Test
fun `present - declining invite with block success flow`() = runTest {
val clearMembershipNotificationForRoomLambda = lambdaRecorder<SessionId, RoomId, Unit> { _, _ ->
Result.success(Unit)
}
val fakeNotificationCleaner = FakeNotificationCleaner(
clearMembershipNotificationForRoomLambda = clearMembershipNotificationForRoomLambda
)
val declineInviteSuccess = lambdaRecorder { -> Result.success(Unit) }
val ignoreUserSuccess = lambdaRecorder { _: UserId -> Result.success(Unit) }
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteSuccess))
},
ignoreUserResult = ignoreUserSuccess
)
val presenter = createAcceptDeclineInvitePresenter(
client = client,
notificationCleaner = fakeNotificationCleaner,
)
presenter.test {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = true)
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, true))
state.eventSink(
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
awaitItem().also { state ->
assertThat(state.declineAction).isInstanceOf(AsyncAction.Success::class.java)
}
cancelAndConsumeRemainingEvents()
}
declineInviteSuccess.assertions().isCalledOnce()
ignoreUserSuccess.assertions().isCalledOnce().with(value(A_USER_ID))
clearMembershipNotificationForRoomLambda.assertions()
.isCalledOnce()
.with(value(A_SESSION_ID), value(A_ROOM_ID))
}
@Test
fun `present - declining invite with block error flow`() = runTest {
val declineInviteFailure = lambdaRecorder { ->
Result.failure<Unit>(RuntimeException("Failed to leave room"))
}
val client = FakeMatrixClient(
getRoomPreviewResult = { _, _ ->
Result.success(FakeRoomPreview(declineInviteResult = declineInviteFailure))
}
)
val presenter = createAcceptDeclineInvitePresenter(client = client)
presenter.test {
val inviteData = anInviteData()
awaitItem().also { state ->
state.eventSink(
AcceptDeclineInviteEvents.DeclineInvite(inviteData, blockUser = true)
)
}
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, true))
state.eventSink(
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite
)
}
assertThat(awaitItem().declineAction.isLoading()).isTrue()
}
}
@Test
fun `present - accepting invite error flow`() = runTest {
val joinRoomFailure = lambdaRecorder { roomIdOrAlias: RoomIdOrAlias, _: List<String>, _: JoinedRoom.Trigger ->

View File

@@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -40,9 +41,9 @@ class BlockedUsersPresenterTest {
@Test
fun `present - initial state with blocked users`() = runTest {
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID)
}
val matrixClient = FakeMatrixClient(
ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID))
)
val presenter = aBlockedUsersPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@@ -56,9 +57,10 @@ class BlockedUsersPresenterTest {
@Test
fun `present - blocked users list updates with new emissions`() = runTest {
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID)
}
val ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID))
val matrixClient = FakeMatrixClient(
ignoredUsersFlow = ignoredUsersFlow
)
val presenter = aBlockedUsersPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@@ -66,7 +68,7 @@ class BlockedUsersPresenterTest {
with(awaitItem()) {
assertThat(blockedUsers).isEqualTo(listOf(MatrixUser(A_USER_ID)))
}
matrixClient.ignoredUsersFlow.value = persistentListOf(A_USER_ID, A_USER_ID_2)
ignoredUsersFlow.value = persistentListOf(A_USER_ID, A_USER_ID_2)
skipItems(1)
with(awaitItem()) {
assertThat(blockedUsers).isEqualTo(listOf(MatrixUser(A_USER_ID), MatrixUser(A_USER_ID_2)))
@@ -77,8 +79,9 @@ class BlockedUsersPresenterTest {
@Test
fun `present - blocked users list with data`() = runTest {
val alice = MatrixUser(A_USER_ID, displayName = "Alice", avatarUrl = "aliceAvatar")
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID, A_USER_ID_2)
val matrixClient = FakeMatrixClient(
ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID, A_USER_ID_2))
).apply {
givenGetProfileResult(A_USER_ID, Result.success(alice))
givenGetProfileResult(A_USER_ID_2, Result.failure(AN_EXCEPTION))
}
@@ -103,9 +106,9 @@ class BlockedUsersPresenterTest {
@Test
fun `present - unblock user`() = runTest {
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID)
}
val matrixClient = FakeMatrixClient(
ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID))
)
val presenter = aBlockedUsersPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@@ -125,10 +128,10 @@ class BlockedUsersPresenterTest {
@Test
fun `present - unblock user handles failure`() = runTest {
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID)
givenUnignoreUserResult(Result.failure(IllegalStateException("User not banned")))
}
val matrixClient = FakeMatrixClient(
unIgnoreUserResult = { Result.failure(IllegalStateException("User not banned")) },
ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID))
)
val presenter = aBlockedUsersPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@@ -147,10 +150,10 @@ class BlockedUsersPresenterTest {
@Test
fun `present - unblock user then cancel`() = runTest {
val matrixClient = FakeMatrixClient().apply {
ignoredUsersFlow.value = persistentListOf(A_USER_ID)
givenUnignoreUserResult(Result.failure(IllegalStateException("User not banned")))
}
val matrixClient = FakeMatrixClient(
unIgnoreUserResult = { Result.failure(IllegalStateException("User not banned")) },
ignoredUsersFlow = MutableStateFlow(persistentListOf(A_USER_ID))
)
val presenter = aBlockedUsersPresenter(matrixClient = matrixClient)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()

View File

@@ -40,7 +40,11 @@ import io.element.android.tests.testutils.lambda.any
import io.element.android.tests.testutils.lambda.lambdaRecorder
import io.element.android.tests.testutils.lambda.value
import io.element.android.tests.testutils.test
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@@ -169,7 +173,8 @@ class UserProfilePresenterTest {
@Test
fun `present - BlockUser and UnblockUser without confirmation change the 'blocked' state`() = runTest {
val client = createFakeMatrixClient()
val ignoredUsersFlow = MutableStateFlow(persistentListOf<UserId>())
val client = createFakeMatrixClient(ignoredUsersFlow = ignoredUsersFlow)
val presenter = createUserProfilePresenter(
client = client,
userId = A_USER_ID
@@ -178,20 +183,21 @@ class UserProfilePresenterTest {
val initialState = awaitFirstItem()
initialState.eventSink(UserProfileEvents.BlockUser(needsConfirmation = false))
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
client.emitIgnoreUserList(listOf(A_USER_ID))
ignoredUsersFlow.emit(persistentListOf(A_USER_ID))
assertThat(awaitItem().isBlocked.dataOrNull()).isTrue()
initialState.eventSink(UserProfileEvents.UnblockUser(needsConfirmation = false))
assertThat(awaitItem().isBlocked.isLoading()).isTrue()
client.emitIgnoreUserList(listOf())
ignoredUsersFlow.emit(persistentListOf())
assertThat(awaitItem().isBlocked.dataOrNull()).isFalse()
}
}
@Test
fun `present - BlockUser with error`() = runTest {
val matrixClient = createFakeMatrixClient()
matrixClient.givenIgnoreUserResult(Result.failure(A_THROWABLE))
val matrixClient = createFakeMatrixClient(
ignoreUserResult = { Result.failure(A_THROWABLE) }
)
val presenter = createUserProfilePresenter(client = matrixClient)
presenter.test {
val initialState = awaitFirstItem()
@@ -207,8 +213,9 @@ class UserProfilePresenterTest {
@Test
fun `present - UnblockUser with error`() = runTest {
val matrixClient = createFakeMatrixClient()
matrixClient.givenUnignoreUserResult(Result.failure(A_THROWABLE))
val matrixClient = createFakeMatrixClient(
unIgnoreUserResult = { Result.failure(A_THROWABLE) }
)
val presenter = createUserProfilePresenter(client = matrixClient)
presenter.test {
val initialState = awaitFirstItem()
@@ -374,10 +381,16 @@ class UserProfilePresenterTest {
private fun createFakeMatrixClient(
isUserVerified: Boolean = false,
ignoreUserResult: (UserId) -> Result<Unit> = { Result.success(Unit) },
unIgnoreUserResult: (UserId) -> Result<Unit> = { Result.success(Unit) },
ignoredUsersFlow: StateFlow<ImmutableList<UserId>> = MutableStateFlow(persistentListOf())
) = FakeMatrixClient(
encryptionService = FakeEncryptionService(
isUserVerifiedResult = { Result.success(isUserVerified) }
),
ignoreUserResult = ignoreUserResult,
unIgnoreUserResult = unIgnoreUserResult,
ignoredUsersFlow = ignoredUsersFlow
)
private fun createUserProfilePresenter(

View File

@@ -85,7 +85,10 @@ class FakeMatrixClient(
private val canDeactivateAccountResult: () -> Boolean = { lambdaError() },
private val deactivateAccountResult: (String, Boolean) -> Result<Unit> = { _, _ -> lambdaError() },
private val currentSlidingSyncVersionLambda: () -> Result<SlidingSyncVersion> = { lambdaError() },
private val availableSlidingSyncVersionsLambda: () -> Result<List<SlidingSyncVersion>> = { lambdaError() }
private val availableSlidingSyncVersionsLambda: () -> Result<List<SlidingSyncVersion>> = { lambdaError() },
private val ignoreUserResult: (UserId) -> Result<Unit> = { lambdaError() },
private var unIgnoreUserResult: (UserId)-> Result<Unit> = {Result.success(Unit)},
override val ignoredUsersFlow: StateFlow<ImmutableList<UserId>> = MutableStateFlow(persistentListOf()),
) : MatrixClient {
var setDisplayNameCalled: Boolean = false
private set
@@ -96,10 +99,7 @@ class FakeMatrixClient(
private val _userProfile: MutableStateFlow<MatrixUser> = MutableStateFlow(MatrixUser(sessionId, userDisplayName, userAvatarUrl))
override val userProfile: StateFlow<MatrixUser> = _userProfile
override val ignoredUsersFlow: MutableStateFlow<ImmutableList<UserId>> = MutableStateFlow(persistentListOf())
private var ignoreUserResult: Result<Unit> = Result.success(Unit)
private var unignoreUserResult: Result<Unit> = Result.success(Unit)
private var createRoomResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var createDmResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var findDmResult: RoomId? = A_ROOM_ID
@@ -137,11 +137,11 @@ class FakeMatrixClient(
}
override suspend fun ignoreUser(userId: UserId): Result<Unit> = simulateLongTask {
return ignoreUserResult
return ignoreUserResult(userId)
}
override suspend fun unignoreUser(userId: UserId): Result<Unit> = simulateLongTask {
return unignoreUserResult
return unIgnoreUserResult(userId)
}
override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId> = simulateLongTask {
@@ -239,10 +239,6 @@ class FakeMatrixClient(
return RoomMembershipObserver()
}
suspend fun emitIgnoreUserList(users: List<UserId>) {
ignoredUsersFlow.emit(users.toImmutableList())
}
// Mocks
fun givenCreateRoomResult(result: Result<RoomId>) {
@@ -253,14 +249,6 @@ class FakeMatrixClient(
createDmResult = result
}
fun givenIgnoreUserResult(result: Result<Unit>) {
ignoreUserResult = result
}
fun givenUnignoreUserResult(result: Result<Unit>) {
unignoreUserResult = result
}
fun givenFindDmResult(result: RoomId?) {
findDmResult = result
}