fix: Make Client.findDM return a Result (#4816)

This commit is contained in:
Jorge Martin Espinosa 2025-06-04 10:41:26 +02:00 committed by GitHub
parent 0aa1a258e4
commit c02c1ae1bd
7 changed files with 44 additions and 22 deletions

View file

@ -27,7 +27,7 @@ class DefaultStartDMActionTest {
@Test @Test
fun `when dm is found, assert state is updated with given room id`() = runTest { fun `when dm is found, assert state is updated with given room id`() = runTest {
val matrixClient = FakeMatrixClient().apply { val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(A_ROOM_ID) givenFindDmResult(Result.success(A_ROOM_ID))
} }
val analyticsService = FakeAnalyticsService() val analyticsService = FakeAnalyticsService()
val action = createStartDMAction(matrixClient, analyticsService) val action = createStartDMAction(matrixClient, analyticsService)
@ -37,10 +37,23 @@ class DefaultStartDMActionTest {
assertThat(analyticsService.capturedEvents).isEmpty() assertThat(analyticsService.capturedEvents).isEmpty()
} }
@Test
fun `when finding the dm fails, assert state is updated with given error`() = runTest {
val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(Result.failure(AN_EXCEPTION))
}
val analyticsService = FakeAnalyticsService()
val action = createStartDMAction(matrixClient, analyticsService)
val state = mutableStateOf<AsyncAction<RoomId>>(AsyncAction.Uninitialized)
action.execute(aMatrixUser(), true, state)
assertThat(state.value).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
assertThat(analyticsService.capturedEvents).isEmpty()
}
@Test @Test
fun `when dm is not found, assert dm is created, state is updated with given room id and analytics get called`() = runTest { fun `when dm is not found, assert dm is created, state is updated with given room id and analytics get called`() = runTest {
val matrixClient = FakeMatrixClient().apply { val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(null) givenFindDmResult(Result.success(null))
givenCreateDmResult(Result.success(A_ROOM_ID)) givenCreateDmResult(Result.success(A_ROOM_ID))
} }
val analyticsService = FakeAnalyticsService() val analyticsService = FakeAnalyticsService()
@ -54,7 +67,7 @@ class DefaultStartDMActionTest {
@Test @Test
fun `when dm is not found, and createIfDmDoesNotExist is false, assert dm is not created and state is updated to confirmation state`() = runTest { fun `when dm is not found, and createIfDmDoesNotExist is false, assert dm is not created and state is updated to confirmation state`() = runTest {
val matrixClient = FakeMatrixClient().apply { val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(null) givenFindDmResult(Result.success(null))
givenCreateDmResult(Result.success(A_ROOM_ID)) givenCreateDmResult(Result.success(A_ROOM_ID))
} }
val analyticsService = FakeAnalyticsService() val analyticsService = FakeAnalyticsService()
@ -69,7 +82,7 @@ class DefaultStartDMActionTest {
@Test @Test
fun `when dm creation fails, assert state is updated with given error`() = runTest { fun `when dm creation fails, assert state is updated with given error`() = runTest {
val matrixClient = FakeMatrixClient().apply { val matrixClient = FakeMatrixClient().apply {
givenFindDmResult(null) givenFindDmResult(Result.success(null))
givenCreateDmResult(Result.failure(AN_EXCEPTION)) givenCreateDmResult(Result.failure(AN_EXCEPTION))
} }
val analyticsService = FakeAnalyticsService() val analyticsService = FakeAnalyticsService()

View file

@ -55,7 +55,7 @@ class UserProfilePresenter @AssistedInject constructor(
@Composable @Composable
private fun getDmRoomId(): State<RoomId?> { private fun getDmRoomId(): State<RoomId?> {
return produceState<RoomId?>(initialValue = null) { return produceState<RoomId?>(initialValue = null) {
value = client.findDM(userId) value = client.findDM(userId).getOrNull()
} }
} }

View file

@ -141,7 +141,7 @@ class UserProfilePresenterTest {
if (canFindRoom) { if (canFindRoom) {
givenGetRoomResult(A_ROOM_ID, room) givenGetRoomResult(A_ROOM_ID, room)
} }
givenFindDmResult(dmRoom) givenFindDmResult(Result.success(dmRoom))
} }
val presenter = createUserProfilePresenter( val presenter = createUserProfilePresenter(
userId = A_USER_ID_2, userId = A_USER_ID_2,

View file

@ -55,7 +55,7 @@ interface MatrixClient {
val ignoredUsersFlow: StateFlow<ImmutableList<UserId>> val ignoredUsersFlow: StateFlow<ImmutableList<UserId>>
suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom? suspend fun getJoinedRoom(roomId: RoomId): JoinedRoom?
suspend fun getRoom(roomId: RoomId): BaseRoom? suspend fun getRoom(roomId: RoomId): BaseRoom?
suspend fun findDM(userId: UserId): RoomId? suspend fun findDM(userId: UserId): Result<RoomId?>
suspend fun ignoreUser(userId: UserId): Result<Unit> suspend fun ignoreUser(userId: UserId): Result<Unit>
suspend fun unignoreUser(userId: UserId): Result<Unit> suspend fun unignoreUser(userId: UserId): Result<Unit>
suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId> suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId>

View file

@ -18,17 +18,24 @@ suspend fun MatrixClient.startDM(
userId: UserId, userId: UserId,
createIfDmDoesNotExist: Boolean, createIfDmDoesNotExist: Boolean,
): StartDMResult { ): StartDMResult {
val existingDM = findDM(userId) return findDM(userId)
return if (existingDM != null) { .fold(
StartDMResult.Success(existingDM, isNew = false) onSuccess = { existingDM ->
} else if (createIfDmDoesNotExist) { if (existingDM != null) {
createDM(userId).fold( StartDMResult.Success(existingDM, isNew = false)
{ StartDMResult.Success(it, isNew = true) }, } else if (createIfDmDoesNotExist) {
{ StartDMResult.Failure(it) } createDM(userId).fold(
{ StartDMResult.Success(it, isNew = true) },
{ StartDMResult.Failure(it) }
)
} else {
StartDMResult.DmDoesNotExist
}
},
onFailure = { error ->
StartDMResult.Failure(error)
}
) )
} else {
StartDMResult.DmDoesNotExist
}
} }
sealed interface StartDMResult { sealed interface StartDMResult {

View file

@ -297,8 +297,10 @@ class RustMatrixClient(
} }
} }
override suspend fun findDM(userId: UserId): RoomId? = withContext(sessionDispatcher) { override suspend fun findDM(userId: UserId): Result<RoomId?> = withContext(sessionDispatcher) {
innerClient.getDmRoom(userId.value)?.use { RoomId(it.id()) } runCatchingExceptions {
innerClient.getDmRoom(userId.value)?.use { RoomId(it.id()) }
}
} }
override suspend fun ignoreUser(userId: UserId): Result<Unit> = withContext(sessionDispatcher) { override suspend fun ignoreUser(userId: UserId): Result<Unit> = withContext(sessionDispatcher) {

View file

@ -103,7 +103,7 @@ class FakeMatrixClient(
private var createRoomResult: Result<RoomId> = Result.success(A_ROOM_ID) private var createRoomResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var createDmResult: Result<RoomId> = Result.success(A_ROOM_ID) private var createDmResult: Result<RoomId> = Result.success(A_ROOM_ID)
private var findDmResult: RoomId? = A_ROOM_ID private var findDmResult: Result<RoomId?> = Result.success(A_ROOM_ID)
private val getRoomResults = mutableMapOf<RoomId, BaseRoom>() private val getRoomResults = mutableMapOf<RoomId, BaseRoom>()
private val searchUserResults = mutableMapOf<String, Result<MatrixSearchUserResults>>() private val searchUserResults = mutableMapOf<String, Result<MatrixSearchUserResults>>()
private val getProfileResults = mutableMapOf<UserId, Result<MatrixUser>>() private val getProfileResults = mutableMapOf<UserId, Result<MatrixUser>>()
@ -133,7 +133,7 @@ class FakeMatrixClient(
return getRoomResults[roomId] as? JoinedRoom return getRoomResults[roomId] as? JoinedRoom
} }
override suspend fun findDM(userId: UserId): RoomId? { override suspend fun findDM(userId: UserId): Result<RoomId?> {
return findDmResult return findDmResult
} }
@ -248,7 +248,7 @@ class FakeMatrixClient(
createDmResult = result createDmResult = result
} }
fun givenFindDmResult(result: RoomId?) { fun givenFindDmResult(result: Result<RoomId?>) {
findDmResult = result findDmResult = result
} }