Move and fix test for DefaultInvitePeoplePresenter
This commit is contained in:
parent
f3d4b7c546
commit
4e334efb51
2 changed files with 118 additions and 93 deletions
|
|
@ -46,6 +46,7 @@ dependencies {
|
||||||
testImplementation(libs.test.robolectric)
|
testImplementation(libs.test.robolectric)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
testImplementation(projects.libraries.usersearch.test)
|
testImplementation(projects.libraries.usersearch.test)
|
||||||
|
testImplementation(projects.services.apperror.test)
|
||||||
testImplementation(projects.tests.testutils)
|
testImplementation(projects.tests.testutils)
|
||||||
testImplementation(libs.androidx.compose.ui.test.junit)
|
testImplementation(libs.androidx.compose.ui.test.junit)
|
||||||
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
|
testReleaseImplementation(libs.androidx.compose.ui.test.manifest)
|
||||||
|
|
|
||||||
|
|
@ -5,32 +5,32 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.features.roomdetails.impl.invite
|
package io.element.android.features.invitepeople.impl
|
||||||
|
|
||||||
import app.cash.molecule.RecompositionMode
|
import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
|
import app.cash.turbine.ReceiveTurbine
|
||||||
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.features.roomdetails.impl.aRoom
|
|
||||||
import io.element.android.features.roomdetails.impl.members.RoomMemberListDataSource
|
|
||||||
import io.element.android.features.roomdetails.impl.members.aRoomMember
|
|
||||||
import io.element.android.features.roomdetails.impl.members.aRoomMemberList
|
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
|
||||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembersState
|
import io.element.android.libraries.matrix.api.room.RoomMembersState
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
import io.element.android.libraries.matrix.api.room.RoomMembershipState
|
||||||
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_ID_2
|
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||||
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
|
import io.element.android.libraries.matrix.test.room.aRoomMember
|
||||||
|
import io.element.android.libraries.matrix.test.room.aRoomMemberList
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
||||||
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.UserRepository
|
||||||
import io.element.android.libraries.usersearch.api.UserSearchResult
|
import io.element.android.libraries.usersearch.api.UserSearchResult
|
||||||
import io.element.android.libraries.usersearch.api.UserSearchResultState
|
import io.element.android.libraries.usersearch.api.UserSearchResultState
|
||||||
import io.element.android.libraries.usersearch.test.FakeUserRepository
|
import io.element.android.libraries.usersearch.test.FakeUserRepository
|
||||||
|
import io.element.android.services.apperror.api.AppErrorStateService
|
||||||
|
import io.element.android.services.apperror.test.FakeAppErrorStateService
|
||||||
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.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
@ -39,22 +39,18 @@ import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
internal class RoomInviteMembersPresenterTest {
|
internal class DefaultInvitePeoplePresenterTest {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state has no results and no search`() = runTest {
|
fun `present - initial state has no results and no search`() = runTest {
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter()
|
||||||
userRepository = FakeUserRepository(),
|
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers()
|
|
||||||
)
|
|
||||||
|
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItemAsDefault()
|
||||||
|
|
||||||
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||||
assertThat(initialState.isSearchActive).isFalse()
|
assertThat(initialState.isSearchActive).isFalse()
|
||||||
|
|
@ -67,11 +63,7 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - updates search active state`() = runTest {
|
fun `present - updates search active state`() = runTest {
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter()
|
||||||
userRepository = FakeUserRepository(),
|
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers()
|
|
||||||
)
|
|
||||||
|
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -79,7 +71,7 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.OnSearchActiveChanged(true))
|
initialState.eventSink(DefaultInvitePeopleEvents.OnSearchActiveChanged(true))
|
||||||
|
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItem()
|
||||||
assertThat(resultState.isSearchActive).isTrue()
|
assertThat(resultState.isSearchActive).isTrue()
|
||||||
|
|
@ -89,24 +81,24 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - performs search and handles empty result list`() = runTest {
|
fun `present - performs search and handles empty result list`() = runTest {
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitState(UserSearchResultState(results = emptyList(), isSearching = true))
|
repository.emitState(UserSearchResultState(results = emptyList(), isSearching = true))
|
||||||
consumeItemsUntilPredicate { it.showSearchLoader }.last().also { state ->
|
skipItems(3)
|
||||||
|
awaitItemAsDefault().also { state ->
|
||||||
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||||
assertThat(state.showSearchLoader).isTrue()
|
assertThat(state.showSearchLoader).isTrue()
|
||||||
}
|
}
|
||||||
repository.emitState(results = emptyList(), isSearching = false)
|
repository.emitState(results = emptyList(), isSearching = false)
|
||||||
consumeItemsUntilPredicate { !it.showSearchLoader }.last().also { state ->
|
awaitItemAsDefault().also { state ->
|
||||||
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java)
|
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java)
|
||||||
assertThat(state.showSearchLoader).isFalse()
|
assertThat(state.showSearchLoader).isFalse()
|
||||||
}
|
}
|
||||||
|
|
@ -116,9 +108,8 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - performs search and handles user results`() = runTest {
|
fun `present - performs search and handles user results`() = runTest {
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -127,23 +118,27 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList())
|
repository.emitStateWithUsers(users = aMatrixUserList())
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
|
||||||
val expectedUsers = aMatrixUserList()
|
val expectedUsers = aMatrixUserList()
|
||||||
val users = resultState.searchResults.users()
|
val users = resultState.searchResults.users()
|
||||||
expectedUsers.forEachIndexed { index, matrixUser ->
|
expectedUsers.forEachIndexed { index, matrixUser ->
|
||||||
assertThat(users[index].matrixUser).isEqualTo(matrixUser)
|
assertThat(users[index].matrixUser).isEqualTo(matrixUser)
|
||||||
assertThat(users[index].isAlreadyInvited).isFalse()
|
// All users are joined or invited
|
||||||
assertThat(users[index].isAlreadyJoined).isFalse()
|
if (users[index].isAlreadyInvited) {
|
||||||
assertThat(users[index].isSelected).isFalse()
|
assertThat(users[index].isAlreadyJoined).isFalse()
|
||||||
|
} else {
|
||||||
|
assertThat(users[index].isAlreadyJoined).isTrue()
|
||||||
|
}
|
||||||
|
assertThat(users[index].isSelected).isTrue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,22 +151,21 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
|
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(
|
roomMembersState = RoomMembersState.Ready(
|
||||||
room = FakeBaseRoom().apply {
|
persistentListOf(
|
||||||
givenRoomMembersState(
|
aRoomMember(
|
||||||
RoomMembersState.Ready(
|
userId = joinedUser.userId,
|
||||||
persistentListOf(
|
membership = RoomMembershipState.JOIN
|
||||||
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
|
),
|
||||||
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
|
aRoomMember(
|
||||||
)
|
userId = invitedUser.userId,
|
||||||
)
|
membership = RoomMembershipState.INVITE
|
||||||
)
|
),
|
||||||
},
|
)
|
||||||
coroutineDispatchers = coroutineDispatchers,
|
|
||||||
),
|
),
|
||||||
coroutineDispatchers = coroutineDispatchers
|
coroutineDispatchers = coroutineDispatchers,
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -179,14 +173,14 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList())
|
repository.emitStateWithUsers(users = aMatrixUserList())
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
|
||||||
val users = resultState.searchResults.users()
|
val users = resultState.searchResults.users()
|
||||||
|
|
@ -217,18 +211,21 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val invitedUser = userList[1]
|
val invitedUser = userList[1]
|
||||||
|
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom().apply {
|
roomMembersState =
|
||||||
givenRoomMembersState(
|
RoomMembersState.Ready(
|
||||||
RoomMembersState.Ready(
|
persistentListOf(
|
||||||
persistentListOf(
|
aRoomMember(
|
||||||
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
|
userId = joinedUser.userId,
|
||||||
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
|
membership = RoomMembershipState.JOIN
|
||||||
)
|
),
|
||||||
|
aRoomMember(
|
||||||
|
userId = invitedUser.userId,
|
||||||
|
membership = RoomMembershipState.INVITE
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
}),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -238,16 +235,21 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
|
|
||||||
val unresolvedUser = UserSearchResult(aMatrixUser(id = A_USER_ID.value), isUnresolved = true)
|
val unresolvedUser =
|
||||||
repository.emitState(listOf(unresolvedUser) + aMatrixUserList().map { UserSearchResult(it) })
|
UserSearchResult(aMatrixUser(id = A_USER_ID.value), isUnresolved = true)
|
||||||
|
repository.emitState(listOf(unresolvedUser) + aMatrixUserList().map {
|
||||||
|
UserSearchResult(
|
||||||
|
it
|
||||||
|
)
|
||||||
|
})
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
|
||||||
val users = resultState.searchResults.users()
|
val users = resultState.searchResults.users()
|
||||||
|
|
@ -264,9 +266,8 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - toggle users updates selected user state`() = runTest {
|
fun `present - toggle users updates selected user state`() = runTest {
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers()
|
coroutineDispatchers = testCoroutineDispatchers()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -277,25 +278,27 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
// When we toggle a user not in the list, they are added
|
// When we toggle a user not in the list, they are added
|
||||||
initialState.eventSink(RoomInviteMembersEvents.ToggleUser(aMatrixUser()))
|
initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser()))
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(aMatrixUser())
|
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(aMatrixUser())
|
||||||
|
|
||||||
// Toggling a different user also adds them
|
// Toggling a different user also adds them
|
||||||
initialState.eventSink(RoomInviteMembersEvents.ToggleUser(aMatrixUser(id = A_USER_ID_2.value)))
|
initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser(id = A_USER_ID_2.value)))
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(aMatrixUser(), aMatrixUser(id = A_USER_ID_2.value))
|
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(
|
||||||
|
aMatrixUser(),
|
||||||
|
aMatrixUser(id = A_USER_ID_2.value)
|
||||||
|
)
|
||||||
|
|
||||||
// Toggling the first user removes them
|
// Toggling the first user removes them
|
||||||
initialState.eventSink(RoomInviteMembersEvents.ToggleUser(aMatrixUser()))
|
initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(aMatrixUser()))
|
||||||
assertThat(awaitItem().selectedUsers).containsExactly(aMatrixUser(id = A_USER_ID_2.value))
|
assertThat(awaitItemAsDefault().selectedUsers).containsExactly(aMatrixUser(id = A_USER_ID_2.value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - selected users appear as such in search results`() = runTest {
|
fun `present - selected users appear as such in search results`() = runTest {
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -306,16 +309,16 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
|
|
||||||
val selectedUser = aMatrixUser()
|
val selectedUser = aMatrixUser()
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.ToggleUser(selectedUser))
|
initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
|
||||||
|
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
||||||
skipItems(2)
|
skipItems(2)
|
||||||
|
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItemAsDefault()
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
|
||||||
val users = resultState.searchResults.users()
|
val users = resultState.searchResults.users()
|
||||||
|
|
@ -325,18 +328,17 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
assertThat(shouldBeSelectedUser).isNotNull()
|
assertThat(shouldBeSelectedUser).isNotNull()
|
||||||
assertThat(shouldBeSelectedUser?.isSelected).isTrue()
|
assertThat(shouldBeSelectedUser?.isSelected).isTrue()
|
||||||
|
|
||||||
// And no others are
|
// All the others are selected since their membership is joined or invited
|
||||||
val allOtherUsers = users.minus(shouldBeSelectedUser!!)
|
val allOtherUsers = users.minus(shouldBeSelectedUser!!)
|
||||||
assertThat(allOtherUsers.none { it.isSelected }).isTrue()
|
assertThat(allOtherUsers.all { it.isSelected }).isTrue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - toggling a user updates existing search results`() = runTest {
|
fun `present - toggling a user updates existing search results`() = runTest {
|
||||||
val repository = FakeUserRepository()
|
val repository = FakeUserRepository()
|
||||||
val presenter = RoomInviteMembersPresenter(
|
val presenter = createDefaultInvitePeoplePresenter(
|
||||||
userRepository = repository,
|
userRepository = repository,
|
||||||
roomMemberListDataSource = createDataSource(FakeBaseRoom()),
|
|
||||||
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
)
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -348,17 +350,25 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
val selectedUser = aMatrixUser()
|
val selectedUser = aMatrixUser()
|
||||||
|
|
||||||
// Given a query is made
|
// Given a query is made
|
||||||
initialState.eventSink(RoomInviteMembersEvents.UpdateSearchQuery("some query"))
|
initialState.eventSink(DefaultInvitePeopleEvents.UpdateSearchQuery("some query"))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
|
|
||||||
assertThat(repository.providedQuery).isEqualTo("some query")
|
assertThat(repository.providedQuery).isEqualTo("some query")
|
||||||
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
repository.emitStateWithUsers(users = aMatrixUserList() + selectedUser)
|
||||||
skipItems(2)
|
skipItems(1)
|
||||||
|
awaitItemAsDefault().also { state ->
|
||||||
|
// selectedUser is not selected
|
||||||
|
assertThat(state.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
val users = state.searchResults.users()
|
||||||
|
val shouldNotBeSelectedUser = users.find { it.matrixUser == selectedUser }
|
||||||
|
assertThat(shouldNotBeSelectedUser).isNotNull()
|
||||||
|
assertThat(shouldNotBeSelectedUser?.isSelected).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
// And then a user is toggled
|
// And then a user is toggled
|
||||||
initialState.eventSink(RoomInviteMembersEvents.ToggleUser(selectedUser))
|
initialState.eventSink(DefaultInvitePeopleEvents.ToggleUser(selectedUser))
|
||||||
skipItems(1)
|
skipItems(1)
|
||||||
val resultState = awaitItem()
|
val resultState = awaitItemAsDefault()
|
||||||
|
|
||||||
// The results are updated...
|
// The results are updated...
|
||||||
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
assertThat(resultState.searchResults).isInstanceOf(SearchBarResultState.Results::class.java)
|
||||||
|
|
@ -369,9 +379,9 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
assertThat(shouldBeSelectedUser).isNotNull()
|
assertThat(shouldBeSelectedUser).isNotNull()
|
||||||
assertThat(shouldBeSelectedUser?.isSelected).isTrue()
|
assertThat(shouldBeSelectedUser?.isSelected).isTrue()
|
||||||
|
|
||||||
// And no others are
|
// All the others are selected since their membership is joined or invited
|
||||||
val allOtherUsers = users.minus(shouldBeSelectedUser!!)
|
val allOtherUsers = users.minus(shouldBeSelectedUser!!)
|
||||||
assertThat(allOtherUsers.none { it.isSelected }).isTrue()
|
assertThat(allOtherUsers.all { it.isSelected }).isTrue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,13 +406,27 @@ internal class RoomInviteMembersPresenterTest {
|
||||||
emitState(state)
|
emitState(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createDataSource(
|
|
||||||
room: BaseRoom = aRoom().apply {
|
|
||||||
givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList()))
|
|
||||||
},
|
|
||||||
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers()
|
|
||||||
) = RoomMemberListDataSource(room, coroutineDispatchers)
|
|
||||||
|
|
||||||
private fun SearchBarResultState<ImmutableList<InvitableUser>>.users() =
|
private fun SearchBarResultState<ImmutableList<InvitableUser>>.users() =
|
||||||
(this as? SearchBarResultState.Results<ImmutableList<InvitableUser>>)?.results.orEmpty()
|
(this as? SearchBarResultState.Results<ImmutableList<InvitableUser>>)?.results.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun <T> ReceiveTurbine<T>.awaitItemAsDefault(): DefaultInvitePeopleState {
|
||||||
|
return awaitItem() as DefaultInvitePeopleState
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TestScope.createDefaultInvitePeoplePresenter(
|
||||||
|
roomMembersState: RoomMembersState = RoomMembersState.Ready(aRoomMemberList()),
|
||||||
|
userRepository: UserRepository = FakeUserRepository(),
|
||||||
|
coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
appErrorStateService: AppErrorStateService = FakeAppErrorStateService(),
|
||||||
|
): DefaultInvitePeoplePresenter {
|
||||||
|
return DefaultInvitePeoplePresenter(
|
||||||
|
room = FakeJoinedRoom().apply {
|
||||||
|
givenRoomMembersState(roomMembersState)
|
||||||
|
},
|
||||||
|
userRepository = userRepository,
|
||||||
|
coroutineDispatchers = coroutineDispatchers,
|
||||||
|
coroutineScope = backgroundScope,
|
||||||
|
appErrorStateService = appErrorStateService,
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue