Add a Low Priority room filter behind a feature flag. (#4394)
* Add Low Priority room filter with incompatibility rules Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com> * Add a feature flag and use the SDK filters. * Fix filter tests and add RoomSummaryProvider tests for the default filters. * Remove unnecessary comment. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com> Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
@@ -574,6 +574,7 @@
|
||||
6A54F52443EC52AC5CD772C0 /* JoinRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869A8A4632E511351BFE2EC4 /* JoinRoomScreen.swift */; };
|
||||
6A64546ABE648ED9E6DBB459 /* RemoteSettingsHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D186A6DB8FAC5C9D0E4D61 /* RemoteSettingsHook.swift */; };
|
||||
6A916606A8B92FE8A990A219 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A1941B874A3BE9CDDF43EF /* XCTestCase.swift */; };
|
||||
6AB306367E56A6F6DFA0E2FF /* RoomSummaryProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */; };
|
||||
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
||||
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
|
||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
||||
@@ -2707,6 +2708,7 @@
|
||||
F409D44C2E6BE50462E82F8A /* en-US */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-US"; path = "en-US.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionMock.swift; sourceTree = "<group>"; };
|
||||
F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsView.swift; sourceTree = "<group>"; };
|
||||
F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderTests.swift; sourceTree = "<group>"; };
|
||||
F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedAccessibilityTests.swift; sourceTree = "<group>"; };
|
||||
F506C6ADB1E1DA6638078E11 /* UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F51D674A5B5F1FE1B878E20F /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -4530,6 +4532,7 @@
|
||||
48FEFF746DB341CDB18D7AAA /* RoomRolesAndPermissionsScreenViewModelTests.swift */,
|
||||
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
||||
AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */,
|
||||
F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */,
|
||||
046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */,
|
||||
2E88534A39781D76487D59DF /* SecureBackupKeyBackupScreenViewModelTests.swift */,
|
||||
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */,
|
||||
@@ -7242,6 +7245,7 @@
|
||||
84C631E734FD2555B39B681C /* RoomRolesAndPermissionsScreenViewModelTests.swift in Sources */,
|
||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
||||
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */,
|
||||
6AB306367E56A6F6DFA0E2FF /* RoomSummaryProviderTests.swift in Sources */,
|
||||
15913A5B07118C1268A840E4 /* RoomSummaryTests.swift in Sources */,
|
||||
7691233E3572A9173FD96CB3 /* SecureBackupKeyBackupScreenViewModelTests.swift in Sources */,
|
||||
EB87DF90CF6F8D5D12404C6E /* SecureBackupLogoutConfirmationScreenViewModelTests.swift in Sources */,
|
||||
|
||||
@@ -55,6 +55,7 @@ final class AppSettings {
|
||||
// Feature flags
|
||||
case publicSearchEnabled
|
||||
case fuzzyRoomListSearchEnabled
|
||||
case lowPriorityFilterEnabled
|
||||
case enableOnlySignedDeviceIsolationMode
|
||||
case enableKeyShareOnInvite
|
||||
case knockingEnabled
|
||||
@@ -345,6 +346,9 @@ final class AppSettings {
|
||||
@UserPreference(key: UserDefaultsKeys.fuzzyRoomListSearchEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var fuzzyRoomListSearchEnabled
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.lowPriorityFilterEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var lowPriorityFilterEnabled
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var knockingEnabled
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ struct HomeScreenViewState: BindableState {
|
||||
return rooms
|
||||
}
|
||||
|
||||
var bindings = HomeScreenViewStateBindings()
|
||||
var bindings: HomeScreenViewStateBindings
|
||||
|
||||
var placeholderRooms: [HomeScreenRoom] {
|
||||
(1...10).map { _ in
|
||||
@@ -136,7 +136,7 @@ struct HomeScreenViewState: BindableState {
|
||||
}
|
||||
|
||||
struct HomeScreenViewStateBindings {
|
||||
var filtersState = RoomListFiltersState()
|
||||
var filtersState: RoomListFiltersState
|
||||
var searchQuery = ""
|
||||
var isSearchFieldFocused = false
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
roomSummaryProvider = userSession.clientProxy.roomSummaryProvider
|
||||
|
||||
super.init(initialViewState: .init(userID: userSession.clientProxy.userID),
|
||||
super.init(initialViewState: .init(userID: userSession.clientProxy.userID,
|
||||
bindings: .init(filtersState: .init(appSettings: appSettings))),
|
||||
mediaProvider: userSession.mediaProvider)
|
||||
|
||||
userSession.clientProxy.userAvatarURLPublisher
|
||||
|
||||
@@ -21,6 +21,7 @@ enum RoomListFilter: Int, CaseIterable, Identifiable {
|
||||
case rooms
|
||||
case favourites
|
||||
case invites
|
||||
case lowPriority
|
||||
|
||||
static var availableFilters: [RoomListFilter] {
|
||||
RoomListFilter.allCases
|
||||
@@ -38,6 +39,8 @@ enum RoomListFilter: Int, CaseIterable, Identifiable {
|
||||
return L10n.screenRoomlistFilterFavourites
|
||||
case .invites:
|
||||
return L10n.screenRoomlistFilterInvites
|
||||
case .lowPriority:
|
||||
return L10n.screenRoomlistFilterLowPriority
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +53,11 @@ enum RoomListFilter: Int, CaseIterable, Identifiable {
|
||||
case .unreads:
|
||||
return [.invites]
|
||||
case .favourites:
|
||||
// When we will have Low Priority we may need to return it here
|
||||
return [.invites]
|
||||
return [.invites, .lowPriority]
|
||||
case .invites:
|
||||
return [.rooms, .people, .unreads, .favourites]
|
||||
return [.rooms, .people, .unreads, .favourites, .lowPriority]
|
||||
case .lowPriority:
|
||||
return [.favourites, .invites]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,20 +73,29 @@ enum RoomListFilter: Int, CaseIterable, Identifiable {
|
||||
return .all(filters: [.favourite, .joined])
|
||||
case .invites:
|
||||
return .invite
|
||||
case .lowPriority:
|
||||
// Note: When not activated, the setFilter method automatically applies the .nonLowPriority filter.
|
||||
return .all(filters: [.lowPriority, .joined])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomListFiltersState {
|
||||
private(set) var activeFilters: OrderedSet<RoomListFilter>
|
||||
private let appSettings: AppSettings
|
||||
|
||||
init(activeFilters: OrderedSet<RoomListFilter> = []) {
|
||||
init(activeFilters: OrderedSet<RoomListFilter> = [], appSettings: AppSettings) {
|
||||
self.activeFilters = .init(activeFilters)
|
||||
self.appSettings = appSettings
|
||||
}
|
||||
|
||||
var availableFilters: [RoomListFilter] {
|
||||
var availableFilters = OrderedSet(RoomListFilter.availableFilters)
|
||||
|
||||
if !appSettings.lowPriorityFilterEnabled {
|
||||
availableFilters.remove(.lowPriority)
|
||||
}
|
||||
|
||||
for filter in activeFilters {
|
||||
availableFilters.remove(filter)
|
||||
filter.incompatibleFilters.forEach { availableFilters.remove($0) }
|
||||
|
||||
@@ -19,13 +19,6 @@ struct RoomListFilterView: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomListFilterView_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
RoomListFilterView(filter: .people, isActive: .constant(false))
|
||||
RoomListFilterView(filter: .people, isActive: .constant(true))
|
||||
}
|
||||
}
|
||||
|
||||
private struct FilterToggleStyle: ToggleStyle {
|
||||
private func strokeColor(isOn: Bool) -> Color {
|
||||
isOn ? .compound.bgActionPrimaryRest : .compound.borderInteractiveSecondary
|
||||
@@ -59,3 +52,12 @@ private struct FilterToggleStyle: ToggleStyle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct RoomListFilterView_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
RoomListFilterView(filter: .people, isActive: .constant(false))
|
||||
RoomListFilterView(filter: .people, isActive: .constant(true))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ struct RoomListFiltersEmptyStateView: View {
|
||||
return L10n.screenRoomlistFilterFavouritesEmptyStateTitle
|
||||
case .invites:
|
||||
return L10n.screenRoomlistFilterInvitesEmptyStateTitle
|
||||
case .lowPriority:
|
||||
return L10n.screenRoomlistFilterLowPriorityEmptyStateTitle
|
||||
}
|
||||
}
|
||||
return L10n.screenRoomlistFilterMixedEmptyStateTitle
|
||||
@@ -55,9 +57,11 @@ struct RoomListFiltersEmptyStateView_Previews: PreviewProvider, TestablePreview
|
||||
static var previews: some View {
|
||||
VStack(spacing: 24) {
|
||||
ForEach(RoomListFilter.allCases) { filter in
|
||||
RoomListFiltersEmptyStateView(state: .init(activeFilters: [filter]))
|
||||
RoomListFiltersEmptyStateView(state: .init(activeFilters: [filter],
|
||||
appSettings: ServiceLocator.shared.settings))
|
||||
}
|
||||
RoomListFiltersEmptyStateView(state: .init(activeFilters: [.people, .favourites]))
|
||||
RoomListFiltersEmptyStateView(state: .init(activeFilters: [.people, .favourites],
|
||||
appSettings: ServiceLocator.shared.settings))
|
||||
}
|
||||
.padding(.bottom)
|
||||
.previewLayout(.sizeThatFits)
|
||||
|
||||
@@ -87,7 +87,10 @@ struct RoomListFiltersView: View {
|
||||
|
||||
struct RoomListFiltersView_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
RoomListFiltersView(state: .constant(.init()))
|
||||
RoomListFiltersView(state: .constant(.init(activeFilters: [.rooms, .favourites])))
|
||||
RoomListFiltersView(state: .constant(.init(appSettings: ServiceLocator.shared.settings)))
|
||||
RoomListFiltersView(state: .constant(.init(activeFilters: [.rooms, .favourites],
|
||||
appSettings: ServiceLocator.shared.settings)))
|
||||
RoomListFiltersView(state: .constant(.init(activeFilters: [.lowPriority],
|
||||
appSettings: ServiceLocator.shared.settings)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
||||
|
||||
var publicSearchEnabled: Bool { get set }
|
||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||
var lowPriorityFilterEnabled: Bool { get set }
|
||||
var knockingEnabled: Bool { get set }
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@ struct DeveloperOptionsScreen: View {
|
||||
Toggle(isOn: $context.fuzzyRoomListSearchEnabled) {
|
||||
Text("Fuzzy searching")
|
||||
}
|
||||
|
||||
Toggle(isOn: $context.lowPriorityFilterEnabled) {
|
||||
Text("Low priority filter")
|
||||
}
|
||||
}
|
||||
|
||||
Section("Timeline") {
|
||||
|
||||
@@ -127,9 +127,14 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
}
|
||||
_ = listUpdatesSubscriptionResult?.controller().setFilter(kind: .all(filters: filters))
|
||||
case let .all(filters):
|
||||
var filters = filters.map(\.rustFilter)
|
||||
filters.append(contentsOf: [.nonLeft, .nonSpace, .deduplicateVersions])
|
||||
_ = listUpdatesSubscriptionResult?.controller().setFilter(kind: .all(filters: filters))
|
||||
var rustFilters = filters.map(\.rustFilter)
|
||||
rustFilters.append(contentsOf: [.nonLeft, .nonSpace, .deduplicateVersions])
|
||||
|
||||
if !filters.contains(.lowPriority), appSettings.lowPriorityFilterEnabled {
|
||||
rustFilters.append(.all(filters: [.nonLowPriority, .joined]))
|
||||
}
|
||||
|
||||
_ = listUpdatesSubscriptionResult?.controller().setFilter(kind: .all(filters: rustFilters))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:298a6d99b6e2a010ca3db350524498210f988cd6e302474cd7c3aa902de0a5cb
|
||||
size 81295
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d17daf1432f41dbb4ff28d010500f85e48da50e605a6671a8c28e828497f8116
|
||||
size 82478
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:92f896aab9210b8aec55600da87c0032fdcbcd87c3a1aa8b5fc3dba5a570a67e
|
||||
size 38601
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1d19d7e28fadb77f1cbb3a0a0b6ccae511910c6b1924b28507b5f105712f801a
|
||||
size 37696
|
||||
@@ -10,16 +10,25 @@ import XCTest
|
||||
@testable import ElementX
|
||||
|
||||
final class RoomListFiltersStateTests: XCTestCase {
|
||||
var appSettings: AppSettings!
|
||||
|
||||
var state: RoomListFiltersState!
|
||||
var allCasesWithoutLowPriority = RoomListFilter.allCases.filter { $0 != .lowPriority }
|
||||
|
||||
override func setUp() {
|
||||
state = RoomListFiltersState()
|
||||
AppSettings.resetAllSettings()
|
||||
appSettings = AppSettings()
|
||||
state = RoomListFiltersState(appSettings: appSettings)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testInitialState() {
|
||||
XCTAssertFalse(state.isFiltering)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
|
||||
}
|
||||
|
||||
func testSetAndUnsetFilters() {
|
||||
@@ -30,7 +39,7 @@ final class RoomListFiltersStateTests: XCTestCase {
|
||||
state.deactivateFilter(.unreads)
|
||||
XCTAssertFalse(state.isFiltering)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
|
||||
}
|
||||
|
||||
func testMutuallyExclusiveFilters() {
|
||||
@@ -42,7 +51,7 @@ final class RoomListFiltersStateTests: XCTestCase {
|
||||
state.deactivateFilter(.people)
|
||||
XCTAssertFalse(state.isFiltering)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
|
||||
|
||||
state.activateFilter(.rooms)
|
||||
XCTAssertTrue(state.isFiltering)
|
||||
@@ -71,7 +80,7 @@ final class RoomListFiltersStateTests: XCTestCase {
|
||||
state.clearFilters()
|
||||
XCTAssertFalse(state.isFiltering)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
|
||||
}
|
||||
|
||||
func testOrder() {
|
||||
@@ -81,7 +90,7 @@ final class RoomListFiltersStateTests: XCTestCase {
|
||||
|
||||
state.deactivateFilter(.favourites)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
|
||||
|
||||
state.activateFilter(.rooms)
|
||||
XCTAssertEqual(state.activeFilters, [.rooms])
|
||||
@@ -95,4 +104,25 @@ final class RoomListFiltersStateTests: XCTestCase {
|
||||
XCTAssertEqual(state.activeFilters, [.rooms])
|
||||
XCTAssertEqual(state.availableFilters, [.unreads, .favourites])
|
||||
}
|
||||
|
||||
// MARK: Low Priority feature flag
|
||||
|
||||
// Don't forget to add .lowPriority into the mix above when enabling the feature.
|
||||
func testWithLowPriorityFeature() {
|
||||
enableLowPriorityFeature()
|
||||
XCTAssertFalse(state.isFiltering)
|
||||
XCTAssertEqual(state.activeFilters, [])
|
||||
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
|
||||
|
||||
state.activateFilter(.lowPriority)
|
||||
XCTAssertEqual(state.activeFilters, [.lowPriority])
|
||||
XCTAssertEqual(state.availableFilters, [.unreads, .people, .rooms])
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func enableLowPriorityFeature() {
|
||||
appSettings.lowPriorityFilterEnabled = true
|
||||
state = RoomListFiltersState(appSettings: appSettings)
|
||||
}
|
||||
}
|
||||
|
||||
116
UnitTests/Sources/RoomSummaryProviderTests.swift
Normal file
116
UnitTests/Sources/RoomSummaryProviderTests.swift
Normal file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
final class RoomSummaryProviderTests: XCTestCase {
|
||||
var appSettings: AppSettings!
|
||||
var roomList: RoomListSDKMock!
|
||||
var dynamicEntriesController: RoomListDynamicEntriesControllerSDKMock!
|
||||
|
||||
var roomSummaryProvider: RoomSummaryProvider!
|
||||
|
||||
override func setUp() {
|
||||
AppSettings.resetAllSettings()
|
||||
appSettings = AppSettings()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testDefaultRustFilters() async {
|
||||
// Given a new room provider.
|
||||
setupProvider()
|
||||
await Task.yield()
|
||||
|
||||
// Then it should have the default Rust filters enabled.
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 1)
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.nonLeft,
|
||||
.nonSpace,
|
||||
.deduplicateVersions]))
|
||||
|
||||
// When setting one our user filters.
|
||||
roomSummaryProvider.setFilter(.all(filters: [.favourites]))
|
||||
await Task.yield()
|
||||
|
||||
// Then that filter should be added to the default Rust filters.
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 2)
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.favourite, .joined]),
|
||||
.nonLeft,
|
||||
.nonSpace,
|
||||
.deduplicateVersions]))
|
||||
}
|
||||
|
||||
func testLowPriorityRustFilters() async {
|
||||
// Given a new room provider with the low priority filter enabled.
|
||||
setupProvider(isLowPriorityFilterEnabled: true)
|
||||
await Task.yield()
|
||||
|
||||
// Then the default Rust filters should include the non-low priority filter,
|
||||
// so that low priority rooms are hidden from the top of the room list.
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 1)
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.nonLeft,
|
||||
.nonSpace,
|
||||
.deduplicateVersions,
|
||||
.all(filters: [.nonLowPriority, .joined])]))
|
||||
|
||||
// When setting the low priority filter.
|
||||
roomSummaryProvider.setFilter(.all(filters: [.lowPriority]))
|
||||
await Task.yield()
|
||||
|
||||
// Then the non-low priority filter should be replaced with the low priority filter.
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 2)
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.lowPriority, .joined]),
|
||||
.nonLeft,
|
||||
.nonSpace,
|
||||
.deduplicateVersions]))
|
||||
|
||||
// When setting another one of our filters.
|
||||
roomSummaryProvider.setFilter(.all(filters: [.rooms]))
|
||||
await Task.yield()
|
||||
|
||||
// Then the filter should be combined with the non-low priority filter.
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 3)
|
||||
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.category(expect: .group), .joined]),
|
||||
.nonLeft,
|
||||
.nonSpace,
|
||||
.deduplicateVersions,
|
||||
.all(filters: [.nonLowPriority, .joined])]))
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func setupProvider(isLowPriorityFilterEnabled: Bool = false) {
|
||||
appSettings.lowPriorityFilterEnabled = isLowPriorityFilterEnabled
|
||||
|
||||
let stateEventStringBuilder = RoomStateEventStringBuilder(userID: "@me:matrix.org")
|
||||
let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder())
|
||||
let eventStringBuilder = RoomEventStringBuilder(stateEventStringBuilder: stateEventStringBuilder,
|
||||
messageEventStringBuilder: RoomMessageEventStringBuilder(attributedStringBuilder: attributedStringBuilder,
|
||||
destination: .roomList),
|
||||
shouldDisambiguateDisplayNames: true,
|
||||
shouldPrefixSenderName: true)
|
||||
|
||||
roomSummaryProvider = RoomSummaryProvider(roomListService: RoomListServiceSDKMock(),
|
||||
eventStringBuilder: eventStringBuilder,
|
||||
name: "Test",
|
||||
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||
appSettings: appSettings)
|
||||
|
||||
dynamicEntriesController = RoomListDynamicEntriesControllerSDKMock()
|
||||
dynamicEntriesController.setFilterKindReturnValue = true
|
||||
let dynamicAdaptersResult = RoomListEntriesWithDynamicAdaptersResultSDKMock()
|
||||
dynamicAdaptersResult.controllerReturnValue = dynamicEntriesController
|
||||
roomList = RoomListSDKMock()
|
||||
roomList.entriesWithDynamicAdaptersPageSizeListenerReturnValue = dynamicAdaptersResult
|
||||
roomList.loadingStateListenerReturnValue = .some(.init(state: .notLoaded, stateStream: .init(noPointer: .init())))
|
||||
roomSummaryProvider.setRoomList(roomList)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user