Don't show own user in search results
Anywhere we do a global search (starting a DM, creating a room, inviting a user to a room) should filter out the local user.
This commit is contained in:
parent
bbd1ff31a3
commit
ac7a547971
2 changed files with 71 additions and 13 deletions
|
|
@ -18,6 +18,7 @@ package io.element.android.libraries.usersearch.impl
|
||||||
|
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.di.SessionScope
|
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.MatrixPatterns
|
||||||
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.user.MatrixUser
|
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
|
|
@ -31,13 +32,16 @@ import javax.inject.Inject
|
||||||
|
|
||||||
@ContributesBinding(SessionScope::class)
|
@ContributesBinding(SessionScope::class)
|
||||||
class MatrixUserRepository @Inject constructor(
|
class MatrixUserRepository @Inject constructor(
|
||||||
|
client: MatrixClient,
|
||||||
private val dataSource: UserListDataSource
|
private val dataSource: UserListDataSource
|
||||||
) : UserRepository {
|
) : UserRepository {
|
||||||
|
|
||||||
|
private val sessionId = client.sessionId
|
||||||
|
|
||||||
override suspend fun search(query: String): Flow<List<UserSearchResult>> = flow {
|
override suspend fun search(query: String): Flow<List<UserSearchResult>> = flow {
|
||||||
// Manually add a fake result with the matrixId, if any
|
// Manually add a fake result with the matrixId, if provided and not the local user
|
||||||
val isUserId = MatrixPatterns.isUserId(query)
|
val isAnotherUsersId = query != sessionId.value && MatrixPatterns.isUserId(query)
|
||||||
if (isUserId) {
|
if (isAnotherUsersId) {
|
||||||
emit(listOf(UserSearchResult(MatrixUser(UserId(query)))))
|
emit(listOf(UserSearchResult(MatrixUser(UserId(query)))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,10 +49,14 @@ class MatrixUserRepository @Inject constructor(
|
||||||
// Debounce
|
// Debounce
|
||||||
delay(DEBOUNCE_TIME_MILLIS)
|
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 the query is another user's MXID and the result doesn't contain that user ID, query the profile information explicitly
|
||||||
if (isUserId && results.none { it.matrixUser.userId.value == query }) {
|
if (isAnotherUsersId && results.none { it.matrixUser.userId.value == query }) {
|
||||||
results.add(
|
results.add(
|
||||||
0,
|
0,
|
||||||
dataSource.getProfile(UserId(query))
|
dataSource.getProfile(UserId(query))
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,26 @@ package io.element.android.libraries.usersearch.impl
|
||||||
|
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
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.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
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_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_NAME
|
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.matrix.ui.components.aMatrixUserList
|
||||||
import io.element.android.libraries.usersearch.api.UserSearchResult
|
import io.element.android.libraries.usersearch.api.UserSearchResult
|
||||||
import io.element.android.libraries.usersearch.test.FakeUserListDataSource
|
import io.element.android.libraries.usersearch.test.FakeUserListDataSource
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
private val SESSION_ID = SessionId("@current-user:example.com")
|
||||||
|
|
||||||
internal class MatrixUserRepositoryTest {
|
internal class MatrixUserRepositoryTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `search - emits nothing if the search query is too short`() = runTest {
|
fun `search - emits nothing if the search query is too short`() = runTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search("x")
|
val result = repository.search("x")
|
||||||
|
|
||||||
|
|
@ -45,7 +49,7 @@ internal class MatrixUserRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
fun `search - returns empty list if no results are found`() = runTest {
|
fun `search - returns empty list if no results are found`() = runTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search("some query")
|
val result = repository.search("some query")
|
||||||
|
|
||||||
|
|
@ -59,7 +63,7 @@ internal class MatrixUserRepositoryTest {
|
||||||
fun `search - returns users if results are found`() = runTest {
|
fun `search - returns users if results are found`() = runTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
dataSource.givenSearchResult(aMatrixUserList())
|
dataSource.givenSearchResult(aMatrixUserList())
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search("some query")
|
val result = repository.search("some query")
|
||||||
|
|
||||||
|
|
@ -72,7 +76,7 @@ internal class MatrixUserRepositoryTest {
|
||||||
@Test
|
@Test
|
||||||
fun `search - immediately returns placeholder if search is mxid`() = runTest {
|
fun `search - immediately returns placeholder if search is mxid`() = runTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search(A_USER_ID.value)
|
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
|
@Test
|
||||||
fun `search - does not change results if they contain searched mxid`() = runTest {
|
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 searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME)
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
dataSource.givenSearchResult(searchResults)
|
dataSource.givenSearchResult(searchResults)
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search(A_USER_ID.value)
|
val result = repository.search(A_USER_ID.value)
|
||||||
|
|
||||||
|
|
@ -107,7 +139,7 @@ internal class MatrixUserRepositoryTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
dataSource.givenSearchResult(searchResults)
|
dataSource.givenSearchResult(searchResults)
|
||||||
dataSource.givenUserProfile(userProfile)
|
dataSource.givenUserProfile(userProfile)
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search(A_USER_ID.value)
|
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
|
@Test
|
||||||
fun `search - returns unresolved user if profile can't be loaded`() = runTest {
|
fun `search - returns unresolved user if profile can't be loaded`() = runTest {
|
||||||
val searchResults = aMatrixUserListWithoutUserId(A_USER_ID)
|
val searchResults = aMatrixUserListWithoutUserId(A_USER_ID)
|
||||||
|
|
@ -125,7 +175,7 @@ internal class MatrixUserRepositoryTest {
|
||||||
val dataSource = FakeUserListDataSource()
|
val dataSource = FakeUserListDataSource()
|
||||||
dataSource.givenSearchResult(searchResults)
|
dataSource.givenSearchResult(searchResults)
|
||||||
dataSource.givenUserProfile(null)
|
dataSource.givenUserProfile(null)
|
||||||
val repository = MatrixUserRepository(dataSource)
|
val repository = MatrixUserRepository(FakeMatrixClient(SESSION_ID), dataSource)
|
||||||
|
|
||||||
val result = repository.search(A_USER_ID.value)
|
val result = repository.search(A_USER_ID.value)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue