diff --git a/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt index 2a693ff9a4..f77e990a7a 100644 --- a/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt +++ b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt @@ -18,6 +18,7 @@ package io.element.android.libraries.usersearch.impl import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.MatrixPatterns import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser @@ -31,13 +32,16 @@ import javax.inject.Inject @ContributesBinding(SessionScope::class) class MatrixUserRepository @Inject constructor( + client: MatrixClient, private val dataSource: UserListDataSource ) : UserRepository { + private val sessionId = client.sessionId + override suspend fun search(query: String): Flow> = flow { - // Manually add a fake result with the matrixId, if any - val isUserId = MatrixPatterns.isUserId(query) - if (isUserId) { + // Manually add a fake result with the matrixId, if provided and not the local user + val isAnotherUsersId = query != sessionId.value && MatrixPatterns.isUserId(query) + if (isAnotherUsersId) { emit(listOf(UserSearchResult(MatrixUser(UserId(query))))) } @@ -45,10 +49,14 @@ class MatrixUserRepository @Inject constructor( // Debounce delay(DEBOUNCE_TIME_MILLIS) - val results = dataSource.search(query, MAXIMUM_SEARCH_RESULTS).map { UserSearchResult(it) }.toMutableList() + val results = dataSource + .search(query, MAXIMUM_SEARCH_RESULTS) + .filter { it.userId != sessionId } + .map { UserSearchResult(it) } + .toMutableList() - // If the query is a user ID and the result doesn't contain that user ID, query the profile information explicitly - if (isUserId && results.none { it.matrixUser.userId.value == query }) { + // If the query is another user's MXID and the result doesn't contain that user ID, query the profile information explicitly + if (isAnotherUsersId && results.none { it.matrixUser.userId.value == query }) { results.add( 0, dataSource.getProfile(UserId(query)) diff --git a/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt index b2327ef750..621274bef5 100644 --- a/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt +++ b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt @@ -18,22 +18,26 @@ package io.element.android.libraries.usersearch.impl import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_NAME +import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.usersearch.api.UserSearchResult import io.element.android.libraries.usersearch.test.FakeUserListDataSource import kotlinx.coroutines.test.runTest import org.junit.Test +private val SESSION_ID = SessionId("@current-user:example.com") + internal class MatrixUserRepositoryTest { @Test fun `search - emits nothing if the search query is too short`() = runTest { val dataSource = FakeUserListDataSource() - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search("x") @@ -45,7 +49,7 @@ internal class MatrixUserRepositoryTest { @Test fun `search - returns empty list if no results are found`() = runTest { val dataSource = FakeUserListDataSource() - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search("some query") @@ -59,7 +63,7 @@ internal class MatrixUserRepositoryTest { fun `search - returns users if results are found`() = runTest { val dataSource = FakeUserListDataSource() dataSource.givenSearchResult(aMatrixUserList()) - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search("some query") @@ -72,7 +76,7 @@ internal class MatrixUserRepositoryTest { @Test fun `search - immediately returns placeholder if search is mxid`() = runTest { val dataSource = FakeUserListDataSource() - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search(A_USER_ID.value) @@ -83,12 +87,40 @@ internal class MatrixUserRepositoryTest { } } + @Test + fun `search - doesn't return placeholder if search is the local user's mxid`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) + + val result = repository.search(SESSION_ID.value) + + result.test { + assertThat(awaitItem()).isEmpty() + awaitComplete() + } + } + + @Test + fun `search - filters out results with the local user's mxid`() = runTest { + val searchResults = aMatrixUserList() + MatrixUser(userId = SESSION_ID, displayName = A_USER_NAME) + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) + + val result = repository.search("some text") + + result.test { + assertThat(awaitItem()).isEqualTo(aMatrixUserList().toUserSearchResults()) + awaitComplete() + } + } + @Test fun `search - does not change results if they contain searched mxid`() = runTest { val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) val dataSource = FakeUserListDataSource() dataSource.givenSearchResult(searchResults) - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search(A_USER_ID.value) @@ -107,7 +139,7 @@ internal class MatrixUserRepositoryTest { val dataSource = FakeUserListDataSource() dataSource.givenSearchResult(searchResults) dataSource.givenUserProfile(userProfile) - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search(A_USER_ID.value) @@ -118,6 +150,24 @@ internal class MatrixUserRepositoryTest { } } + @Test + fun `search - doesn't add profile results if searched mxid is local user and not in results`() = runTest { + val userProfile = MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) + val searchResults = aMatrixUserListWithoutUserId(SESSION_ID) + + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + dataSource.givenUserProfile(userProfile) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) + + val result = repository.search(SESSION_ID.value) + + result.test { + assertThat(awaitItem()).isEqualTo(searchResults.toUserSearchResults()) + awaitComplete() + } + } + @Test fun `search - returns unresolved user if profile can't be loaded`() = runTest { val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) @@ -125,7 +175,7 @@ internal class MatrixUserRepositoryTest { val dataSource = FakeUserListDataSource() dataSource.givenSearchResult(searchResults) dataSource.givenUserProfile(null) - val repository = MatrixUserRepository(dataSource) + val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource) val result = repository.search(A_USER_ID.value)