From 0466663d64875d359bf5fe58f2af7ab754902290 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 5 Feb 2026 11:33:24 +0100 Subject: [PATCH] Improve SpaceFilters: hide when empty and fix tests --- .../spacefilters/SpaceFiltersPresenter.kt | 8 +- .../spacefilters/SpaceFiltersStateProvider.kt | 4 +- .../impl/spacefilters/SpaceFiltersView.kt | 1 - .../spacefilters/SpaceFiltersPresenterTest.kt | 79 ++++++++++++++++--- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenter.kt index 92a2f33e7c..9813732bdb 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenter.kt @@ -36,14 +36,14 @@ class SpaceFiltersPresenter( .isFeatureEnabledFlow(FeatureFlags.RoomListSpaceFilters) .collectAsState(initial = false) - if (!isFeatureEnabled) { - return SpaceFiltersState.Disabled - } - val availableFilters by remember { matrixClient.spaceService.spaceFiltersFlow.map { it.toImmutableList() } }.collectAsState(initial = persistentListOf()) + if (!isFeatureEnabled || availableFilters.isEmpty()) { + return SpaceFiltersState.Disabled + } + var selectionMode by remember { mutableStateOf(SelectionMode.Unselected) } fun handleUnselectedEvent(event: SpaceFiltersEvent.Unselected) { diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersStateProvider.kt index 931d39aef4..264d122836 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersStateProvider.kt @@ -13,7 +13,7 @@ import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter import io.element.android.libraries.previewutils.room.aSpaceRoom -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList class SpaceFiltersStateProvider : PreviewParameterProvider { override val values: Sequence @@ -55,7 +55,7 @@ fun aSelectingSpaceFiltersState( searchQuery: String = "", eventSink: (SpaceFiltersEvent.Selecting) -> Unit = {}, ) = SpaceFiltersState.Selecting( - availableFilters = persistentListOf(*availableFilters.toTypedArray()), + availableFilters = availableFilters.toImmutableList(), searchQuery = TextFieldState(searchQuery), eventSink = eventSink, ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersView.kt index a753e78a87..3ce03dbdd3 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersView.kt @@ -49,7 +49,6 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.spaces.SpaceServiceFilter import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings -import timber.log.Timber @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenterTest.kt index 4d4b908624..278a268864 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spacefilters/SpaceFiltersPresenterTest.kt @@ -35,13 +35,34 @@ class SpaceFiltersPresenterTest { } @Test - fun `present - when feature flag is enabled returns Unselected state initially`() = runTest { + fun `present - when available filters is empty returns Disabled state`() = runTest { val presenter = createSpaceFiltersPresenter( featureFlagService = FakeFeatureFlagService( initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) ) ) presenter.test { + val state = awaitLastSequentialItem() + assertThat(state).isEqualTo(SpaceFiltersState.Disabled) + } + } + + @Test + fun `present - when feature flag is enabled and filters exist returns Unselected state`() = runTest { + val spaceFilter = aSpaceServiceFilter(displayName = "Test Space") + val spaceService = FakeSpaceService() + val matrixClient = FakeMatrixClient(spaceService = spaceService) + + val presenter = createSpaceFiltersPresenter( + featureFlagService = FakeFeatureFlagService( + initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) + ), + matrixClient = matrixClient, + ) + presenter.test { + // Emit filters + spaceService.emitSpaceFilters(listOf(spaceFilter)) + val state = awaitLastSequentialItem() assertThat(state).isInstanceOf(SpaceFiltersState.Unselected::class.java) } @@ -49,12 +70,20 @@ class SpaceFiltersPresenterTest { @Test fun `present - ShowFilters event transitions from Unselected to Selecting`() = runTest { + val spaceFilter = aSpaceServiceFilter(displayName = "Test Space") + val spaceService = FakeSpaceService() + val matrixClient = FakeMatrixClient(spaceService = spaceService) + val presenter = createSpaceFiltersPresenter( featureFlagService = FakeFeatureFlagService( initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) - ) + ), + matrixClient = matrixClient, ) presenter.test { + // Emit filters first + spaceService.emitSpaceFilters(listOf(spaceFilter)) + val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) @@ -65,12 +94,20 @@ class SpaceFiltersPresenterTest { @Test fun `present - Cancel event in Selecting state transitions back to Unselected`() = runTest { + val spaceFilter = aSpaceServiceFilter(displayName = "Test Space") + val spaceService = FakeSpaceService() + val matrixClient = FakeMatrixClient(spaceService = spaceService) + val presenter = createSpaceFiltersPresenter( featureFlagService = FakeFeatureFlagService( initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) - ) + ), + matrixClient = matrixClient, ) presenter.test { + // Emit filters first + spaceService.emitSpaceFilters(listOf(spaceFilter)) + // Start in Unselected val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) @@ -88,12 +125,19 @@ class SpaceFiltersPresenterTest { @Test fun `present - SelectFilter event in Selecting state transitions to Selected`() = runTest { val spaceFilter = aSpaceServiceFilter(displayName = "Test Space") + val spaceService = FakeSpaceService() + val matrixClient = FakeMatrixClient(spaceService = spaceService) + val presenter = createSpaceFiltersPresenter( featureFlagService = FakeFeatureFlagService( initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) - ) + ), + matrixClient = matrixClient, ) presenter.test { + // Emit filters first + spaceService.emitSpaceFilters(listOf(spaceFilter)) + // Start in Unselected val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) @@ -111,12 +155,19 @@ class SpaceFiltersPresenterTest { @Test fun `present - ClearSelection event in Selected state transitions back to Unselected`() = runTest { val spaceFilter = aSpaceServiceFilter(displayName = "Test Space") + val spaceService = FakeSpaceService() + val matrixClient = FakeMatrixClient(spaceService = spaceService) + val presenter = createSpaceFiltersPresenter( featureFlagService = FakeFeatureFlagService( initialState = mapOf(FeatureFlags.RoomListSpaceFilters.key to true) - ) + ), + matrixClient = matrixClient, ) presenter.test { + // Emit filters first + spaceService.emitSpaceFilters(listOf(spaceFilter)) + // Start in Unselected val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) @@ -151,13 +202,13 @@ class SpaceFiltersPresenterTest { matrixClient = matrixClient, ) presenter.test { + // Emit space filters + spaceService.emitSpaceFilters(spaceFilters) + // Start in Unselected val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) - // Emit space filters - spaceService.emitSpaceFilters(spaceFilters) - // Now in Selecting with available filters val selectingState = awaitLastSequentialItem() as SpaceFiltersState.Selecting assertThat(selectingState.availableFilters).containsExactly(spaceFilter1, spaceFilter2).inOrder() @@ -179,10 +230,12 @@ class SpaceFiltersPresenterTest { matrixClient = matrixClient, ) presenter.test { - // Go to Selecting and emit filters + // Emit filters first + spaceService.emitSpaceFilters(listOf(spaceFilter, otherSpaceFilter)) + + // Go to Selecting val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) - spaceService.emitSpaceFilters(listOf(spaceFilter, otherSpaceFilter)) // Select the filter val selectingState = awaitLastSequentialItem() as SpaceFiltersState.Selecting @@ -224,13 +277,13 @@ class SpaceFiltersPresenterTest { matrixClient = matrixClient, ) presenter.test { + // Emit initial space filters + spaceService.emitSpaceFilters(listOf(originalFilter)) + // Start in Unselected val unselectedState = awaitLastSequentialItem() as SpaceFiltersState.Unselected unselectedState.eventSink(SpaceFiltersEvent.Unselected.ShowFilters) - // Emit initial space filters - spaceService.emitSpaceFilters(listOf(originalFilter)) - // Now in Selecting val selectingState = awaitLastSequentialItem() as SpaceFiltersState.Selecting selectingState.eventSink(SpaceFiltersEvent.Selecting.SelectFilter(originalFilter))