Skip to content

Commit 8eedd43

Browse files
committed
Fix filter tests and add RoomSummaryProvider tests for the default filters.
1 parent 1170109 commit 8eedd43

File tree

3 files changed

+156
-40
lines changed

3 files changed

+156
-40
lines changed

ElementX.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@
570570
6A54F52443EC52AC5CD772C0 /* JoinRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869A8A4632E511351BFE2EC4 /* JoinRoomScreen.swift */; };
571571
6A64546ABE648ED9E6DBB459 /* RemoteSettingsHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D186A6DB8FAC5C9D0E4D61 /* RemoteSettingsHook.swift */; };
572572
6A916606A8B92FE8A990A219 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A1941B874A3BE9CDDF43EF /* XCTestCase.swift */; };
573+
6AB306367E56A6F6DFA0E2FF /* RoomSummaryProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */; };
573574
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
574575
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
575576
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
@@ -2679,6 +2680,7 @@
26792680
F409D44C2E6BE50462E82F8A /* en-US */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-US"; path = "en-US.lproj/Localizable.strings"; sourceTree = "<group>"; };
26802681
F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionMock.swift; sourceTree = "<group>"; };
26812682
F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsView.swift; sourceTree = "<group>"; };
2683+
F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderTests.swift; sourceTree = "<group>"; };
26822684
F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedAccessibilityTests.swift; sourceTree = "<group>"; };
26832685
F506C6ADB1E1DA6638078E11 /* UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
26842686
F51D674A5B5F1FE1B878E20F /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -4498,6 +4500,7 @@
44984500
48FEFF746DB341CDB18D7AAA /* RoomRolesAndPermissionsScreenViewModelTests.swift */,
44994501
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
45004502
AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */,
4503+
F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */,
45014504
046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */,
45024505
2E88534A39781D76487D59DF /* SecureBackupKeyBackupScreenViewModelTests.swift */,
45034506
848F69921527D31CAACB93AF /* SecureBackupLogoutConfirmationScreenViewModelTests.swift */,
@@ -7168,6 +7171,7 @@
71687171
84C631E734FD2555B39B681C /* RoomRolesAndPermissionsScreenViewModelTests.swift in Sources */,
71697172
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
71707173
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */,
7174+
6AB306367E56A6F6DFA0E2FF /* RoomSummaryProviderTests.swift in Sources */,
71717175
15913A5B07118C1268A840E4 /* RoomSummaryTests.swift in Sources */,
71727176
7691233E3572A9173FD96CB3 /* SecureBackupKeyBackupScreenViewModelTests.swift in Sources */,
71737177
EB87DF90CF6F8D5D12404C6E /* SecureBackupLogoutConfirmationScreenViewModelTests.swift in Sources */,

UnitTests/Sources/RoomListFiltersStateTests.swift

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,58 @@ import XCTest
1010
@testable import ElementX
1111

1212
final class RoomListFiltersStateTests: XCTestCase {
13+
var appSettings: AppSettings!
14+
1315
var state: RoomListFiltersState!
16+
var allCasesWithoutLowPriority = RoomListFilter.allCases.filter { $0 != .lowPriority }
1417

1518
override func setUp() {
16-
state = RoomListFiltersState()
19+
AppSettings.resetAllSettings()
20+
appSettings = AppSettings()
21+
state = RoomListFiltersState(appSettings: appSettings)
22+
}
23+
24+
override func tearDown() {
25+
AppSettings.resetAllSettings()
1726
}
1827

1928
func testInitialState() {
2029
XCTAssertFalse(state.isFiltering)
2130
XCTAssertEqual(state.activeFilters, [])
22-
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
31+
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
2332
}
2433

2534
func testSetAndUnsetFilters() {
2635
state.activateFilter(.unreads)
2736
XCTAssertTrue(state.isFiltering)
2837
XCTAssertEqual(state.activeFilters, [.unreads])
29-
XCTAssertEqual(state.availableFilters, [.people, .rooms, .favourites, .lowPriority])
38+
XCTAssertEqual(state.availableFilters, [.people, .rooms, .favourites])
3039
state.deactivateFilter(.unreads)
3140
XCTAssertFalse(state.isFiltering)
3241
XCTAssertEqual(state.activeFilters, [])
33-
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
42+
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
3443
}
3544

3645
func testMutuallyExclusiveFilters() {
3746
state.activateFilter(.people)
3847
XCTAssertTrue(state.isFiltering)
3948
XCTAssertEqual(state.activeFilters, [.people])
40-
XCTAssertEqual(state.availableFilters, [.unreads, .favourites, .lowPriority])
49+
XCTAssertEqual(state.availableFilters, [.unreads, .favourites])
4150

4251
state.deactivateFilter(.people)
4352
XCTAssertFalse(state.isFiltering)
4453
XCTAssertEqual(state.activeFilters, [])
45-
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
54+
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
4655

4756
state.activateFilter(.rooms)
4857
XCTAssertTrue(state.isFiltering)
4958
XCTAssertEqual(state.activeFilters, [.rooms])
50-
XCTAssertEqual(state.availableFilters, [.unreads, .favourites, .lowPriority])
59+
XCTAssertEqual(state.availableFilters, [.unreads, .favourites])
5160

5261
state.activateFilter(.unreads)
5362
XCTAssertTrue(state.isFiltering)
5463
XCTAssertEqual(state.activeFilters, [.rooms, .unreads])
55-
XCTAssertEqual(state.availableFilters, [.favourites, .lowPriority])
64+
XCTAssertEqual(state.availableFilters, [.favourites])
5665
}
5766

5867
func testClearFilters() {
@@ -71,7 +80,7 @@ final class RoomListFiltersStateTests: XCTestCase {
7180
state.clearFilters()
7281
XCTAssertFalse(state.isFiltering)
7382
XCTAssertEqual(state.activeFilters, [])
74-
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
83+
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
7584
}
7685

7786
func testOrder() {
@@ -81,52 +90,39 @@ final class RoomListFiltersStateTests: XCTestCase {
8190

8291
state.deactivateFilter(.favourites)
8392
XCTAssertEqual(state.activeFilters, [])
84-
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
93+
XCTAssertEqual(state.availableFilters, allCasesWithoutLowPriority)
8594

8695
state.activateFilter(.rooms)
8796
XCTAssertEqual(state.activeFilters, [.rooms])
88-
XCTAssertEqual(state.availableFilters, [.unreads, .favourites, .lowPriority])
97+
XCTAssertEqual(state.availableFilters, [.unreads, .favourites])
8998

9099
state.activateFilter(.unreads)
91100
XCTAssertEqual(state.activeFilters, [.rooms, .unreads])
92-
XCTAssertEqual(state.availableFilters, [.favourites, .lowPriority])
101+
XCTAssertEqual(state.availableFilters, [.favourites])
93102

94103
state.deactivateFilter(.unreads)
95104
XCTAssertEqual(state.activeFilters, [.rooms])
96-
XCTAssertEqual(state.availableFilters, [.unreads, .favourites, .lowPriority])
105+
XCTAssertEqual(state.availableFilters, [.unreads, .favourites])
97106
}
98107

99-
func testLowPriorityFilterIncompatibility() {
100-
// Test that low priority cannot be combined with favourites
108+
// MARK: Low Priority feature flag
109+
110+
// Don't forget to add .lowPriority into the mix above when enabling the feature.
111+
func testWithLowPriorityFeature() {
112+
enableLowPriorityFeature()
113+
XCTAssertFalse(state.isFiltering)
114+
XCTAssertEqual(state.activeFilters, [])
115+
XCTAssertEqual(state.availableFilters, RoomListFilter.allCases)
116+
101117
state.activateFilter(.lowPriority)
102-
XCTAssertTrue(state.isFiltering)
103118
XCTAssertEqual(state.activeFilters, [.lowPriority])
104119
XCTAssertEqual(state.availableFilters, [.unreads, .people, .rooms])
105-
106-
// Test that low priority cannot be combined with invites
107-
state.deactivateFilter(.lowPriority)
108-
state.activateFilter(.invites)
109-
XCTAssertTrue(state.isFiltering)
110-
XCTAssertEqual(state.activeFilters, [.invites])
111-
XCTAssertEqual(state.availableFilters, [])
112-
113-
// Test that favourites cannot be combined with low priority
114-
state.deactivateFilter(.invites)
115-
state.activateFilter(.favourites)
116-
XCTAssertTrue(state.isFiltering)
117-
XCTAssertEqual(state.activeFilters, [.favourites])
118-
XCTAssertEqual(state.availableFilters, [.unreads, .people, .rooms])
119120
}
120121

121-
func testLowPriorityFilterCompatibility() {
122-
// Test that low priority can be combined with other compatible filters
123-
state.activateFilter(.lowPriority)
124-
state.activateFilter(.unreads)
125-
XCTAssertEqual(state.activeFilters, [.lowPriority, .unreads])
126-
XCTAssertEqual(state.availableFilters, [.people, .rooms])
127-
128-
state.activateFilter(.people)
129-
XCTAssertEqual(state.activeFilters, [.lowPriority, .unreads, .people])
130-
XCTAssertEqual(state.availableFilters, [])
122+
// MARK: - Helpers
123+
124+
private func enableLowPriorityFeature() {
125+
appSettings.lowPriorityFilterEnabled = true
126+
state = RoomListFiltersState(appSettings: appSettings)
131127
}
132128
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//
2+
// Copyright 2025 New Vector Ltd.
3+
//
4+
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
// Please see LICENSE files in the repository root for full details.
6+
//
7+
8+
import XCTest
9+
10+
@testable import ElementX
11+
12+
final class RoomSummaryProviderTests: XCTestCase {
13+
var appSettings: AppSettings!
14+
var roomList: RoomListSDKMock!
15+
var dynamicEntriesController: RoomListDynamicEntriesControllerSDKMock!
16+
17+
var roomSummaryProvider: RoomSummaryProvider!
18+
19+
override func setUp() {
20+
AppSettings.resetAllSettings()
21+
appSettings = AppSettings()
22+
}
23+
24+
override func tearDown() {
25+
AppSettings.resetAllSettings()
26+
}
27+
28+
func testDefaultRustFilters() async {
29+
// Given a new room provider.
30+
setupProvider()
31+
await Task.yield()
32+
33+
// Then it should have the default Rust filters enabled.
34+
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 1)
35+
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.nonLeft,
36+
.nonSpace,
37+
.deduplicateVersions]))
38+
39+
// When setting one our user filters.
40+
roomSummaryProvider.setFilter(.all(filters: [.favourites]))
41+
await Task.yield()
42+
43+
// Then that filter should be added to the default Rust filters.
44+
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 2)
45+
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.favourite, .joined]),
46+
.nonLeft,
47+
.nonSpace,
48+
.deduplicateVersions]))
49+
}
50+
51+
func testLowPriorityRustFilters() async {
52+
// Given a new room provider with the low priority filter enabled.
53+
setupProvider(isLowPriorityFilterEnabled: true)
54+
await Task.yield()
55+
56+
// Then the default Rust filters should include the non-low priority filter,
57+
// so that low priority rooms are hidden from the top of the room list.
58+
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 1)
59+
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.nonLeft,
60+
.nonSpace,
61+
.deduplicateVersions,
62+
.all(filters: [.nonLowPriority, .joined])]))
63+
64+
// When setting the low priority filter.
65+
roomSummaryProvider.setFilter(.all(filters: [.lowPriority]))
66+
await Task.yield()
67+
68+
// Then the non-low priority filter should be replaced with the low priority filter.
69+
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 2)
70+
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.lowPriority, .joined]),
71+
.nonLeft,
72+
.nonSpace,
73+
.deduplicateVersions]))
74+
75+
// When setting another one of our filters.
76+
roomSummaryProvider.setFilter(.all(filters: [.rooms]))
77+
await Task.yield()
78+
79+
// Then the filter should be combined with the non-low priority filter.
80+
XCTAssertEqual(dynamicEntriesController.setFilterKindCallsCount, 3)
81+
XCTAssertEqual(dynamicEntriesController.setFilterKindReceivedInvocations.last, .all(filters: [.all(filters: [.category(expect: .group), .joined]),
82+
.nonLeft,
83+
.nonSpace,
84+
.deduplicateVersions,
85+
.all(filters: [.nonLowPriority, .joined])]))
86+
}
87+
88+
// MARK: - Helpers
89+
90+
private func setupProvider(isLowPriorityFilterEnabled: Bool = false) {
91+
appSettings.lowPriorityFilterEnabled = isLowPriorityFilterEnabled
92+
93+
let stateEventStringBuilder = RoomStateEventStringBuilder(userID: "@me:matrix.org")
94+
let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder())
95+
let eventStringBuilder = RoomEventStringBuilder(stateEventStringBuilder: stateEventStringBuilder,
96+
messageEventStringBuilder: RoomMessageEventStringBuilder(attributedStringBuilder: attributedStringBuilder,
97+
destination: .roomList),
98+
shouldDisambiguateDisplayNames: true,
99+
shouldPrefixSenderName: true)
100+
101+
roomSummaryProvider = RoomSummaryProvider(roomListService: RoomListServiceSDKMock(),
102+
eventStringBuilder: eventStringBuilder,
103+
name: "Test",
104+
notificationSettings: NotificationSettingsProxyMock(with: .init()),
105+
appSettings: appSettings)
106+
107+
dynamicEntriesController = RoomListDynamicEntriesControllerSDKMock()
108+
dynamicEntriesController.setFilterKindReturnValue = true
109+
let dynamicAdaptersResult = RoomListEntriesWithDynamicAdaptersResultSDKMock()
110+
dynamicAdaptersResult.controllerReturnValue = dynamicEntriesController
111+
roomList = RoomListSDKMock()
112+
roomList.entriesWithDynamicAdaptersPageSizeListenerReturnValue = dynamicAdaptersResult
113+
roomList.loadingStateListenerReturnValue = .some(.init(state: .notLoaded, stateStream: .init(noPointer: .init())))
114+
roomSummaryProvider.setRoomList(roomList)
115+
}
116+
}

0 commit comments

Comments
 (0)