diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c7536ed3..a576f4738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### 🐞 Fixed - Fix thread reply action shown when inside a Thread [#717](https://github.com/GetStream/stream-chat-swiftui/pull/717) +### 🔄 Changed +- Deprecate unused `ChatMessage.userDisplayInfo(from:)` which only accessed cached data [#718](https://github.com/GetStream/stream-chat-swiftui/pull/718) # [4.70.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.70.0) _January 15, 2025_ diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index 4c3bd44ad..a4eaa6f58 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -272,17 +272,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { scrolledId = nil return true } else { - let findBaseId: String? = { - if StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled { - return messageId - } else { - return messageId.components(separatedBy: "$").first - } - }() - guard let baseId = findBaseId else { - scrolledId = nil - return true - } + let baseId = messageId let alreadyLoaded = messages.map(\.id).contains(baseId) if alreadyLoaded { if scrolledId == nil { @@ -368,8 +358,8 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { let previous = index - 1 let previousMessage = messages[previous] - let currentAuthorId = messageCachingUtils.authorId(for: message) - let previousAuthorId = messageCachingUtils.authorId(for: previousMessage) + let currentAuthorId = message.author.id + let previousAuthorId = previousMessage.author.id if currentAuthorId != previousAuthorId { temp[message.id]?.append(firstMessageKey) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/AsyncVoiceMessages/VoiceRecordingContainerView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/AsyncVoiceMessages/VoiceRecordingContainerView.swift index 8e44411cf..da10c2183 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/AsyncVoiceMessages/VoiceRecordingContainerView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/AsyncVoiceMessages/VoiceRecordingContainerView.swift @@ -41,7 +41,7 @@ public struct VoiceRecordingContainerView: View { public var body: some View { VStack(spacing: 0) { VStack { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/FileAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/FileAttachmentView.swift index aad6ca267..c3672ac27 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/FileAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/FileAttachmentView.swift @@ -6,9 +6,6 @@ import StreamChat import SwiftUI public struct FileAttachmentsContainer: View { - - @Injected(\.utils) private var utils - var factory: Factory var message: ChatMessage var width: CGFloat @@ -31,7 +28,7 @@ public struct FileAttachmentsContainer: View { public var body: some View { VStack(alignment: message.alignmentInBubble) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/GiphyAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/GiphyAttachmentView.swift index f6d13a316..370ed2052 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/GiphyAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/GiphyAttachmentView.swift @@ -11,7 +11,6 @@ public struct GiphyAttachmentView: View { @Injected(\.chatClient) private var chatClient @Injected(\.colors) private var colors @Injected(\.fonts) private var fonts - @Injected(\.utils) private var utils let factory: Factory let message: ChatMessage @@ -24,7 +23,7 @@ public struct GiphyAttachmentView: View { alignment: message.alignmentInBubble, spacing: 0 ) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift index b7600ac8f..f6d075d1c 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift @@ -7,7 +7,6 @@ import SwiftUI public struct ImageAttachmentContainer: View { @Injected(\.colors) private var colors - @Injected(\.utils) private var utils var factory: Factory let message: ChatMessage @@ -23,7 +22,7 @@ public struct ImageAttachmentContainer: View { alignment: message.alignmentInBubble, spacing: 0 ) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/LinkAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/LinkAttachmentView.swift index ec8f3714e..1c7b5158d 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/LinkAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/LinkAttachmentView.swift @@ -9,7 +9,6 @@ import SwiftUI /// In case of more than one link, only the first link is previewed. public struct LinkAttachmentContainer: View { @Injected(\.colors) private var colors - @Injected(\.utils) private var utils var factory: Factory var message: ChatMessage @@ -38,7 +37,7 @@ public struct LinkAttachmentContainer: View { alignment: message.alignmentInBubble, spacing: 0 ) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift index e2ff8568d..8e93fa16a 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageContainerView.swift @@ -68,7 +68,7 @@ public struct MessageContainerView: View { } else { if messageListConfig.messageDisplayOptions.showAvatars(for: channel) { factory.makeMessageAvatarView( - for: utils.messageCachingUtils.authorInfo(from: message) + for: message.authorDisplayInfo ) .opacity(showsAllInfo ? 1 : 0) .offset(y: bottomReactionsShown ? offsetYAvatar : 0) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift index 2689cea30..2fa38e309 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift @@ -16,17 +16,6 @@ public class DefaultMessageIdBuilder: MessageIdBuilder { public init() { /* Public init. */ } public func makeMessageId(for message: ChatMessage) -> String { - if StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled { - return message.id - } - var statesId = "empty" - if message.localState != nil { - statesId = message.uploadingStatesId - } - if message.textUpdatedAt != nil { - statesId = "edited" - } - return message.baseId + statesId + message.reactionScoresId - + message.repliesCountId + "\(message.updatedAt)" + message.pinStateId + message.id } } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift index f02274e5d..a08eb27a4 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListHelperViews.swift @@ -34,7 +34,6 @@ public struct MessageAuthorAndDateView: View { /// View that displays the message author. public struct MessageAuthorView: View { - @Injected(\.utils) private var utils @Injected(\.fonts) private var fonts @Injected(\.colors) private var colors @@ -44,8 +43,12 @@ public struct MessageAuthorView: View { self.message = message } + var authorName: String { + message.author.name ?? message.author.id + } + public var body: some View { - Text(utils.messageCachingUtils.authorName(for: message)) + Text(authorName) .lineLimit(1) .font(fonts.footnoteBold) .foregroundColor(Color(colors.textLowEmphasis)) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageView.swift index f3d6d78cc..0bd8ec75d 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageView.swift @@ -158,7 +158,7 @@ public struct MessageTextView: View { alignment: message.alignmentInBubble, spacing: 0 ) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { factory.makeQuotedMessageView( quotedMessage: quotedMessage, fillAvailableSpace: !message.attachmentCounts.isEmpty, @@ -193,11 +193,10 @@ public struct EmojiTextView: View { var isFirst: Bool @Injected(\.fonts) private var fonts - @Injected(\.utils) private var utils public var body: some View { ZStack { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { VStack(spacing: 0) { factory.makeQuotedMessageView( quotedMessage: quotedMessage, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/QuotedMessageView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/QuotedMessageView.swift index 8cf0cbb23..73e4841c3 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/QuotedMessageView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/QuotedMessageView.swift @@ -7,9 +7,6 @@ import SwiftUI /// Container showing the quoted message view with the user avatar. struct QuotedMessageViewContainer: View { - - @Injected(\.utils) private var utils - private let avatarSize: CGFloat = 24 var factory: Factory @@ -22,7 +19,7 @@ struct QuotedMessageViewContainer: View { HStack(alignment: .bottom) { if !quotedMessage.isSentByCurrentUser || forceLeftToRight { factory.makeQuotedMessageAvatarView( - for: utils.messageCachingUtils.authorInfo(from: quotedMessage), + for: quotedMessage.authorDisplayInfo, size: CGSize(width: avatarSize, height: avatarSize) ) @@ -41,7 +38,7 @@ struct QuotedMessageViewContainer: View { ) factory.makeQuotedMessageAvatarView( - for: utils.messageCachingUtils.authorInfo(from: quotedMessage), + for: quotedMessage.authorDisplayInfo, size: CGSize(width: avatarSize, height: avatarSize) ) } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/VideoAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/VideoAttachmentView.swift index 4c959329a..9536c6740 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/VideoAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/VideoAttachmentView.swift @@ -7,9 +7,6 @@ import StreamChat import SwiftUI public struct VideoAttachmentsContainer: View { - - @Injected(\.utils) private var utils - var factory: Factory let message: ChatMessage let width: CGFloat @@ -17,7 +14,7 @@ public struct VideoAttachmentsContainer: View { public var body: some View { VStack(spacing: 0) { - if let quotedMessage = utils.messageCachingUtils.quotedMessage(for: message) { + if let quotedMessage = message.quotedMessage { VStack { factory.makeQuotedMessageView( quotedMessage: quotedMessage, diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift index 3e9462828..0a2ef60cf 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift @@ -88,7 +88,7 @@ public struct ReactionsOverlayView: View { if !messageDisplayInfo.message.isRightAligned && utils.messageListConfig.messageDisplayOptions.showAvatars(for: channel) { factory.makeMessageAvatarView( - for: utils.messageCachingUtils.authorInfo(from: messageDisplayInfo.message) + for: messageDisplayInfo.message.authorDisplayInfo ) .offset( x: paddingValue / 2, diff --git a/Sources/StreamChatSwiftUI/Utils/MessageCachingUtils.swift b/Sources/StreamChatSwiftUI/Utils/MessageCachingUtils.swift index dd4068888..445624fec 100644 --- a/Sources/StreamChatSwiftUI/Utils/MessageCachingUtils.swift +++ b/Sources/StreamChatSwiftUI/Utils/MessageCachingUtils.swift @@ -6,15 +6,9 @@ import Foundation import StreamChat import UIKit -/// Caches messages related data to avoid accessing the database. +/// Caches messages related data. /// Cleared on chat channel view dismiss or memory warning. class MessageCachingUtils { - - private var messageAuthorMapping = [String: String]() - private var messageAuthors = [String: UserDisplayInfo]() - private var checkedMessageIds = Set() - private var quotedMessageMapping = [String: ChatMessage]() - var scrollOffset: CGFloat = 0 var messageThreadShown = false { didSet { @@ -26,117 +20,10 @@ class MessageCachingUtils { var jumpToReplyId: String? - func authorId(for message: ChatMessage) -> String { - if let userDisplayInfo = userDisplayInfo(for: message) { - return userDisplayInfo.id - } - - let userDisplayInfo = saveUserDisplayInfo(for: message) - return userDisplayInfo.id - } - - func authorName(for message: ChatMessage) -> String { - if let userDisplayInfo = userDisplayInfo(for: message) { - return userDisplayInfo.name - } - - let userDisplayInfo = saveUserDisplayInfo(for: message) - return userDisplayInfo.name - } - - func authorImageURL(for message: ChatMessage) -> URL? { - if let userDisplayInfo = userDisplayInfo(for: message) { - return userDisplayInfo.imageURL - } - - let userDisplayInfo = saveUserDisplayInfo(for: message) - return userDisplayInfo.imageURL - } - - func authorInfo(from message: ChatMessage) -> UserDisplayInfo { - if let userDisplayInfo = userDisplayInfo(for: message) { - return userDisplayInfo - } - - let userDisplayInfo = saveUserDisplayInfo(for: message) - return userDisplayInfo - } - - func quotedMessage(for message: ChatMessage) -> ChatMessage? { - if StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled { - return message.quotedMessage - } - - if checkedMessageIds.contains(message.id) { - return nil - } - - if let quoted = quotedMessageMapping[message.id] { - return quoted - } - - let quoted = message.quotedMessage - if quoted == nil { - checkedMessageIds.insert(message.id) - } else { - quotedMessageMapping[message.id] = quoted - } - - return quoted - } - - func userDisplayInfo(with id: String) -> UserDisplayInfo? { - for userInfo in messageAuthors.values { - if userInfo.id == id { - return userInfo - } - } - return nil - } - func clearCache() { log.debug("Clearing cached message data") scrollOffset = 0 messageThreadShown = false - messageAuthorMapping = [String: String]() - messageAuthors = [String: UserDisplayInfo]() - checkedMessageIds = Set() - quotedMessageMapping = [String: ChatMessage]() - } - - // MARK: - private - - private func userDisplayInfo(for message: ChatMessage) -> UserDisplayInfo? { - if StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled { - let user = message.author - return UserDisplayInfo( - id: user.id, - name: user.name ?? user.id, - imageURL: user.imageURL, - role: user.userRole - ) - } - - if let userId = messageAuthorMapping[message.id], - let userDisplayInfo = messageAuthors[userId] { - return userDisplayInfo - } else { - return nil - } - } - - private func saveUserDisplayInfo(for message: ChatMessage) -> UserDisplayInfo { - let user = message.author - let userDisplayInfo = UserDisplayInfo( - id: user.id, - name: user.name ?? user.id, - imageURL: user.imageURL, - role: user.userRole - ) - messageAuthorMapping[message.id] = user.id - messageAuthors[user.id] = userDisplayInfo - - return userDisplayInfo } } @@ -158,12 +45,19 @@ public struct UserDisplayInfo { extension ChatMessage { public var authorDisplayInfo: UserDisplayInfo { - let cachingUtils = InjectedValues[\.utils].messageCachingUtils - return cachingUtils.authorInfo(from: self) + UserDisplayInfo( + id: author.id, + name: author.name ?? author.id, + imageURL: author.imageURL, + role: author.userRole + ) } + @available(*, deprecated, message: """ + User display info is not cached anymore and this method returned + cached data only. Use `ChatMessage.authorDisplayInfo` instead + """) public func userDisplayInfo(from id: String) -> UserDisplayInfo? { - let cachingUtils = InjectedValues[\.utils].messageCachingUtils - return cachingUtils.userDisplayInfo(with: id) + nil } } diff --git a/StreamChatSwiftUI.xcodeproj/project.pbxproj b/StreamChatSwiftUI.xcodeproj/project.pbxproj index d2220212d..3fa80a29a 100644 --- a/StreamChatSwiftUI.xcodeproj/project.pbxproj +++ b/StreamChatSwiftUI.xcodeproj/project.pbxproj @@ -3843,8 +3843,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/GetStream/stream-chat-swift.git"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 4.70.0; + branch = develop; + kind = branch; }; }; E3A1C01A282BAC66002D1E26 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = { diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/ChatMessageIDs_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/ChatMessageIDs_Tests.swift index 0fcf27f6d..685d3a851 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/ChatMessageIDs_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/ChatMessageIDs_Tests.swift @@ -7,129 +7,11 @@ import XCTest class ChatMessageIDs_Tests: StreamChatTestCase { - - override func setUpWithError() throws { - try super.setUpWithError() - StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled = false - } - - override func tearDownWithError() throws { - StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled = true - try super.tearDownWithError() - } - - func test_chatMessage_reactionScoresId() { - // Given - let id: String = .unique - let reaction = "like" - let expectedId = id + "$empty" + "\(reaction)\(3)" - let message = ChatMessage.mock( - id: id, - cid: .unique, - text: "test", - author: .mock(id: .unique), - reactionScores: [ - MessageReactionType(rawValue: reaction): 3 - ] - ) - - // When - let messageId = message.messageId - - // Then - XCTAssert(messageId.starts(with: expectedId)) - } - - func test_chatMessage_DeletedId() { - // Given - let id: String = .unique - let expectedId = "\(id)$deleted" - let message = ChatMessage.mock( - id: id, - cid: .unique, - text: "test", - author: .mock(id: .unique), - deletedAt: Date() - ) - - // When - let messageId = message.messageId - - // Then - XCTAssert(messageId.starts(with: expectedId)) - } - - func test_chatMessage_uploadingStatesId() { - // Given - let id: String = .unique - let state = "pendingUpload" - let expectedId = "\(id)$\(state)" - let message = ChatMessage.mock( - id: id, - cid: .unique, - text: "test", - author: .mock(id: .unique), - attachments: ChatChannelTestHelpers.imageAttachments, - localState: .pendingSend - ) - - // When - let uploadingStatesId = message.uploadingStatesId - let messageId = message.messageId - - // Then - XCTAssert(messageId.contains(expectedId)) - XCTAssert(uploadingStatesId == state) - } - - func test_chatMessage_messageIdComplete() { - // Given - let id: String = .unique - let reaction = "like" - let expectedId = "\(id)$pendingUploadlike3" - let message = ChatMessage.mock( - id: id, - cid: .unique, - text: "test", - author: .mock(id: .unique), - reactionScores: [ - MessageReactionType(rawValue: reaction): 3 - ], - attachments: ChatChannelTestHelpers.imageAttachments, - localState: .pendingSend - ) - - // When - let messageId = message.messageId - - // Then - XCTAssert(messageId.contains(expectedId)) - } - - func test_chatMessage_sendingState() { - // Given - let id: String = .unique - let expectedId = "\(id)$sending" - let message = ChatMessage.mock( - id: id, - cid: .unique, - text: "test", - author: .mock(id: .unique), - localState: .sending - ) - - // When - let messageId = message.messageId - - // Then - XCTAssert(messageId.contains(expectedId)) - } - func test_chatMessage_messageBuilder() { // Given let id: String = .unique let reaction = "like" - let expectedId = id + "$empty" + "\(reaction)\(3)" + let expectedId = id let message = ChatMessage.mock( id: id, cid: .unique, @@ -145,6 +27,6 @@ class ChatMessageIDs_Tests: StreamChatTestCase { let messageId = defaultMessageBuilder.makeMessageId(for: message) // Then - XCTAssert(messageId.starts(with: expectedId)) + XCTAssertEqual(expectedId, messageId) } } diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/MessageCachingUtils_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/MessageCachingUtils_Tests.swift index 47ddb78f5..c252416ee 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/MessageCachingUtils_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/MessageCachingUtils_Tests.swift @@ -7,221 +7,18 @@ import XCTest class MessageCachingUtils_Tests: StreamChatTestCase { - - let author = ChatUser.mock( - id: "test", - name: "Test", - imageURL: URL(string: "https://test.com")! - ) - lazy var message = ChatMessage.mock( - id: .unique, - cid: .unique, - text: "Test", - author: author, - quotedMessage: .mock( - id: .unique, - cid: .unique, - text: "Quoted", - author: author - ) - ) - - private var initialReusingState = false - - override func setUpWithError() throws { - initialReusingState = StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled - StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled = false - } - - override func tearDownWithError() throws { - StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled = initialReusingState - } - - func test_messageCachingUtils_authorId() { - // Given - let utils = MessageCachingUtils() - - // When - let authorIdInitial = utils.authorId(for: message) - let authorIdCached = utils.authorId(for: message) - - // Then - XCTAssert(authorIdInitial == "test") - XCTAssert(authorIdInitial == authorIdCached) - } - - func test_messageCachingUtils_authorName() { - // Given - let utils = MessageCachingUtils() - - // When - let authorNameInitial = utils.authorName(for: message) - let authorNameCached = utils.authorName(for: message) - - // Then - XCTAssert(authorNameInitial == "Test") - XCTAssert(authorNameInitial == authorNameCached) - } - - func test_messageCachingUtils_imageURL() { - // Given - let utils = MessageCachingUtils() - - // When - let authorURLInitial = utils.authorImageURL(for: message) - let authorURLCached = utils.authorImageURL(for: message) - - // Then - XCTAssert(authorURLInitial?.absoluteString == "https://test.com") - XCTAssert(authorURLInitial == authorURLCached) - } - - func test_messageCachingUtils_quotedMessageAvailable() { - // Given - let utils = MessageCachingUtils() - - // When - let quotedMessageInitial = utils.quotedMessage(for: message) - let quotedMessageCached = utils.quotedMessage(for: message) - - // Then - XCTAssert(quotedMessageInitial == quotedMessageCached) - } - - func test_messageCachingUtils_quotedMessageNotAvailable() { - // Given - let message = ChatMessage.mock( - id: .unique, - cid: .unique, - text: .unique, - author: .mock(id: .unique) - ) - let utils = MessageCachingUtils() - - // When - let quotedMessageInitial = utils.quotedMessage(for: message) - let quotedMessageCached = utils.quotedMessage(for: message) - - // Then - XCTAssert(quotedMessageInitial == nil) - XCTAssert(quotedMessageCached == nil) - } - func test_messageCachingUtils_recreatingCache() { // Given let utils = MessageCachingUtils() + utils.jumpToReplyId = "test" // When - let authorIdInitial = utils.authorId(for: message) + let initial = utils.jumpToReplyId utils.clearCache() - let authorIdAfterClear = utils.authorId(for: message) + let after = utils.jumpToReplyId // Then - XCTAssert(authorIdInitial == "test") - XCTAssert(authorIdInitial == authorIdAfterClear) - } - - func test_messageCachingUtils_userDisplayInfo() { - // Given - let id: String = .unique - let url = URL(string: "https://imageurl.com") - let author = ChatUser.mock(id: id, name: "Martin", imageURL: url) - let message = ChatMessage.mock( - id: .unique, - cid: .unique, - text: "Test message", - author: author - ) - let utils = MessageCachingUtils() - - // When - let authorInfo = utils.authorInfo(from: message) - let userDisplayInfo = message.authorDisplayInfo - - // Then - XCTAssert(authorInfo == userDisplayInfo) - XCTAssert(userDisplayInfo.id == id) - XCTAssert(userDisplayInfo.name == author.name) - XCTAssert(userDisplayInfo.imageURL == url) - } - - func test_messageCachingUtils_userDisplayInfoIdExisting() { - // Given - let id: String = .unique - let url = URL(string: "https://imageurl.com") - let author = ChatUser.mock(id: id, name: "Martin", imageURL: url) - let message = ChatMessage.mock( - id: .unique, - cid: .unique, - text: "Test message", - author: author - ) - let utils = MessageCachingUtils() - - // When - let authorInfo = utils.authorInfo(from: message) - let userDisplayInfo = utils.userDisplayInfo(with: id) - - // Then - XCTAssert(userDisplayInfo != nil) - XCTAssert(authorInfo == userDisplayInfo) - XCTAssert(userDisplayInfo!.id == id) - XCTAssert(userDisplayInfo!.name == author.name) - XCTAssert(userDisplayInfo!.imageURL == url) - } - - func test_messageCachingUtils_userDisplayInfoIdNonExisting() { - let utils = MessageCachingUtils() - - // When - let userDisplayInfo = utils.userDisplayInfo(with: "some id") - - // Then - XCTAssert(userDisplayInfo == nil) - } - - func test_messageCachingUtils_userDisplayInfoWithoutCaching() { - // Given - StreamRuntimeCheck._isDatabaseObserverItemReusingEnabled = true - let utils = MessageCachingUtils() - let authorId: String = .unique - let messageId: MessageId = .unique - let cid: ChannelId = .unique - let url1 = URL(string: "https://imageurl.com") - let author1 = ChatUser.mock(id: authorId, name: "Martin", imageURL: url1) - let message1 = ChatMessage.mock( - id: messageId, - cid: cid, - text: "Test message", - author: author1 - ) - let url2 = URL(string: "https://anotherimageurl.com") - let author2 = ChatUser.mock(id: authorId, name: "Toomas", imageURL: url2) - let message2 = ChatMessage.mock( - id: messageId, - cid: cid, - text: "Test message", - author: author2 - ) - - // When - let authorInfo1 = utils.authorInfo(from: message1) - let authorInfo2 = utils.authorInfo(from: message2) - - // Then - // Accessing the same message returns updated author information - XCTAssertEqual("Martin", authorInfo1.name) - XCTAssertEqual(url1, authorInfo1.imageURL) - XCTAssertEqual("Toomas", authorInfo2.name) - XCTAssertEqual(url2, authorInfo2.imageURL) - } -} - -extension UserDisplayInfo: Equatable { - public static func == (lhs: UserDisplayInfo, rhs: UserDisplayInfo) -> Bool { - lhs.id == rhs.id && - lhs.name == rhs.name && - lhs.imageURL == rhs.imageURL && - lhs.role == rhs.role + XCTAssertEqual("test", initial) + XCTAssertNil(after) } }