From 846f75434d28daf48737a53a34e07f12c01618c1 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Thu, 13 Jun 2024 17:12:50 +0100 Subject: [PATCH] Fix `channel.pinnedMessages` with missing messages (#3244) * Fix `channel.pinnedMessages` with missing messages * Update CHANGELOG.md * Update CHANGELOG.md --- CHANGELOG.md | 1 + .../StreamChat/Database/DTOs/MessageDTO.swift | 2 +- .../Database/DTOs/MessageDTO_Tests.swift | 32 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 780d19e209e..a4f93e104c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## StreamChat ### 🐞 Fixed +- Fix `channel.pinnedMessages` with missing messages [#3244](https://github.com/GetStream/stream-chat-swift/pull/3244) - Fix notifications muted state for the current user in channel members [#3236](https://github.com/GetStream/stream-chat-swift/pull/3236) # [4.57.0](https://github.com/GetStream/stream-chat-swift/releases/tag/4.57.0) diff --git a/Sources/StreamChat/Database/DTOs/MessageDTO.swift b/Sources/StreamChat/Database/DTOs/MessageDTO.swift index 5dab6eadfa4..d0d8adc1e5b 100644 --- a/Sources/StreamChat/Database/DTOs/MessageDTO.swift +++ b/Sources/StreamChat/Database/DTOs/MessageDTO.swift @@ -774,7 +774,7 @@ extension NSManagedObjectContext: MessageDatabaseSession { if dto.pinned && !channelDTO.pinnedMessages.contains(dto) { channelDTO.pinnedMessages.insert(dto) - } else { + } else if !dto.pinned { channelDTO.pinnedMessages.remove(dto) } diff --git a/Tests/StreamChatTests/Database/DTOs/MessageDTO_Tests.swift b/Tests/StreamChatTests/Database/DTOs/MessageDTO_Tests.swift index 2f70423e23d..54652afbc40 100644 --- a/Tests/StreamChatTests/Database/DTOs/MessageDTO_Tests.swift +++ b/Tests/StreamChatTests/Database/DTOs/MessageDTO_Tests.swift @@ -819,6 +819,38 @@ final class MessageDTO_Tests: XCTestCase { ) } + func test_messagePayload_isPinned_whenAlreadyAddedToPinnedMessages() throws { + let channelId: ChannelId = .unique + let messageId: MessageId = .unique + let channelPayload: ChannelPayload = dummyPayload(with: channelId, pinnedMessages: [.dummy(messageId: messageId)]) + let payload: MessagePayload = .dummy( + messageId: messageId, + authorUserId: .unique, + createdAt: "2018-12-12T15:33:46.488935Z".toDate(), + pinned: true + ) + + let (channelDTO, messageDTO): (ChannelDTO, MessageDTO) = try waitFor { completion in + var channelDTO: ChannelDTO! + var messageDTO: MessageDTO! + + database.write { session in + // Create the channel first + channelDTO = try! session.saveChannel(payload: channelPayload, query: nil, cache: nil) + // Save the message twice + messageDTO = try! session.saveMessage(payload: payload, for: channelId, syncOwnReactions: true, cache: nil) + messageDTO = try! session.saveMessage(payload: payload, for: channelId, syncOwnReactions: true, cache: nil) + } completion: { _ in + completion((channelDTO, messageDTO)) + } + } + + let channel = try XCTUnwrap(channelDTO.inContext(database.viewContext)) + let message = try XCTUnwrap(messageDTO.inContext(database.viewContext)) + XCTAssertTrue(channel.pinnedMessages.contains(message)) + XCTAssertEqual(channel.pinnedMessages.count, 1) + } + func test_messagePayload_isNotPinned_removedFromPinnedMessages() throws { let channelId: ChannelId = .unique let channelPayload: ChannelPayload = dummyPayload(with: channelId)