From d7a190ba23a7962ce12d5a52524f228a2fde85c1 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 8 Feb 2024 10:08:20 +0200 Subject: [PATCH] Fix room list cell highlighting issues, add unit tests --- ElementX.xcodeproj/project.pbxproj | 4 + .../Screens/HomeScreen/HomeScreenModels.swift | 2 +- .../HomeScreen/View/HomeScreenRoomCell.swift | 5 +- UnitTests/Sources/HomeScreenRoomTests.swift | 237 ++++++++++++++++++ 4 files changed, 243 insertions(+), 5 deletions(-) create mode 100644 UnitTests/Sources/HomeScreenRoomTests.swift diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 4062b6df6..0c150b9b3 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -404,6 +404,7 @@ 6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */; }; 67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; }; 67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = AD544C0FA48DFFB080920061 /* Collections */; }; + 6817EAD73DC1FFD8B943B5B9 /* HomeScreenRoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73587C2E3CF5998361AE516 /* HomeScreenRoomTests.swift */; }; 68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; }; 6832733838C57A7D3FE8FEB5 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; }; 6851B077B4C913CC12DB6E77 /* AppLockFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE93F0CBF0D96B77111C413 /* AppLockFlowCoordinator.swift */; }; @@ -1726,6 +1727,7 @@ B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = ""; }; B6E89E530A8E92EC44301CA1 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = ""; }; B70A50C41C5871B4DB905E7E /* VoiceMessageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRoomTimelineView.swift; sourceTree = ""; }; + B73587C2E3CF5998361AE516 /* HomeScreenRoomTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomTests.swift; sourceTree = ""; }; B746EFA112532A7B701FB914 /* RoomNotificationSettingsCustomSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsCustomSectionView.swift; sourceTree = ""; }; B7884BD256C091EB511B2EDF /* AppLockSetupPINScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModelProtocol.swift; sourceTree = ""; }; B788615712FED326F73D3F83 /* GlobalSearchScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -3321,6 +3323,7 @@ 84B7A28A6606D58D1E38C55A /* ExpiringTaskRunnerTests.swift */, 1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */, EA4D639E27D5882A6A71AECF /* GlobalSearchScreenViewModelTests.swift */, + B73587C2E3CF5998361AE516 /* HomeScreenRoomTests.swift */, 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */, CC14E5209C262530E19BC4C1 /* InvitesScreenViewModelTests.swift */, 845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */, @@ -5296,6 +5299,7 @@ 71B62C48B8079D49F3FBC845 /* ExpiringTaskRunnerTests.swift in Sources */, 07756D532EFE33DD1FA258E5 /* GeoURITests.swift in Sources */, EE56238683BC3ECA9BA00684 /* GlobalSearchScreenViewModelTests.swift in Sources */, + 6817EAD73DC1FFD8B943B5B9 /* HomeScreenRoomTests.swift in Sources */, F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */, A23B8B27A1436A1049EEF68E /* InfoPlistReader.swift in Sources */, A216C83ADCF32BA5EF8A6FBC /* InviteUsersViewModelTests.swift in Sources */, diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index f15070268..9b0a4b54e 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -197,7 +197,7 @@ extension HomeScreenRoom { let isMentionShown = details.hasUnreadMentions && !details.isMuted let isMuteShown = details.isMuted let isCallShown = details.hasOngoingCall - let isHighlighted = !details.isMuted && (details.hasUnreadNotifications || details.hasUnreadMentions || details.isMarkedUnread) + let isHighlighted = details.isMarkedUnread || (!details.isMuted && (details.hasUnreadNotifications || details.hasUnreadMentions)) self.init(id: identifier, roomId: details.id, diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift index 59dab2349..92f13826d 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift @@ -119,26 +119,23 @@ struct HomeScreenRoomCell: View { HStack(spacing: 8) { if room.badges.isCallShown { CompoundIcon(\.videoCallSolid, size: .xSmall, relativeTo: .compound.bodySM) - .foregroundColor(room.isHighlighted ? .compound.iconAccentTertiary : .compound.iconQuaternary) } if room.badges.isMuteShown { CompoundIcon(\.notificationsOffSolid, size: .custom(15), relativeTo: .compound.bodyMD) .accessibilityLabel(L10n.a11yNotificationsMuted) - .foregroundColor(.compound.iconQuaternary) } if room.badges.isMentionShown { mentionIcon - .foregroundColor(.compound.iconAccentTertiary) } if room.badges.isDotShown { Circle() .frame(width: 12, height: 12) - .foregroundColor(room.isHighlighted ? .compound.iconAccentTertiary : .compound.iconQuaternary) } } + .foregroundColor(room.isHighlighted ? .compound.iconAccentTertiary : .compound.iconQuaternary) } } diff --git a/UnitTests/Sources/HomeScreenRoomTests.swift b/UnitTests/Sources/HomeScreenRoomTests.swift new file mode 100644 index 000000000..5eedcfbcf --- /dev/null +++ b/UnitTests/Sources/HomeScreenRoomTests.swift @@ -0,0 +1,237 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Combine +import XCTest + +@testable import ElementX + +@MainActor +class HomeScreenRoomTests: XCTestCase { + var roomSummaryDetails: RoomSummaryDetails! + + // swiftlint:disable:next function_parameter_count + func setupRoomSummary(isMarkedUnread: Bool, + unreadMessagesCount: UInt, + unreadMentionsCount: UInt, + unreadNotificationsCount: UInt, + notificationMode: RoomNotificationModeProxy, + hasOngoingCall: Bool) { + roomSummaryDetails = RoomSummaryDetails(id: "Test room", + name: "Test room", + isDirect: false, + avatarURL: nil, + lastMessage: nil, + lastMessageFormattedTimestamp: nil, + isMarkedUnread: isMarkedUnread, + unreadMessagesCount: unreadMessagesCount, + unreadMentionsCount: unreadMentionsCount, + unreadNotificationsCount: unreadNotificationsCount, + notificationMode: notificationMode, + canonicalAlias: nil, + inviter: nil, + hasOngoingCall: hasOngoingCall) + } + + func testNoBadge() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 0, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertFalse(room.isHighlighted) + XCTAssertFalse(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testAllBadgesExceptMute() { + setupRoomSummary(isMarkedUnread: true, + unreadMessagesCount: 5, + unreadMentionsCount: 5, + unreadNotificationsCount: 5, + notificationMode: .allMessages, + hasOngoingCall: true) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertTrue(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertTrue(room.badges.isMentionShown) + } + + func testUnhighlightedDot() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 5, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertFalse(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testHighlightedDot() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 0, + unreadMentionsCount: 0, + unreadNotificationsCount: 5, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testHighlightedMentionAndDot() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 0, + unreadMentionsCount: 5, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertTrue(room.badges.isMentionShown) + } + + func testUnhighlightedCall() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 0, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: true) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertFalse(room.isHighlighted) + XCTAssertFalse(room.badges.isDotShown) + XCTAssertTrue(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testMentionAndKeywordsUnhighlightedDot() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 10, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .mentionsAndKeywordsOnly, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertFalse(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testMentionAndKeywordsUnhighlightedDotHidden() { + setupRoomSummary(isMarkedUnread: false, + unreadMessagesCount: 10, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .mentionsAndKeywordsOnly, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: true) + + XCTAssertFalse(room.isHighlighted) + XCTAssertFalse(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + // MARK: - Mark unread + + func testMarkedUnreadDot() { + setupRoomSummary(isMarkedUnread: true, + unreadMessagesCount: 0, + unreadMentionsCount: 0, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } + + func testMarkedUnreadDotAndMention() { + setupRoomSummary(isMarkedUnread: true, + unreadMessagesCount: 0, + unreadMentionsCount: 5, + unreadNotificationsCount: 0, + notificationMode: .allMessages, + hasOngoingCall: false) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertFalse(room.badges.isCallShown) + XCTAssertFalse(room.badges.isMuteShown) + XCTAssertTrue(room.badges.isMentionShown) + } + + func testMarkedUnreadMuteDotAndCall() { + setupRoomSummary(isMarkedUnread: true, + unreadMessagesCount: 5, + unreadMentionsCount: 5, + unreadNotificationsCount: 5, + notificationMode: .mute, + hasOngoingCall: true) + + let room = HomeScreenRoom(details: roomSummaryDetails, invalidated: false, hideUnreadMessagesBadge: false) + + XCTAssertTrue(room.isHighlighted) + XCTAssertTrue(room.badges.isDotShown) + XCTAssertTrue(room.badges.isCallShown) + XCTAssertTrue(room.badges.isMuteShown) + XCTAssertFalse(room.badges.isMentionShown) + } +}