Skip to content

Commit

Permalink
Enable deleting messages in pendingSend state (#2432)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmitrevski committed Jan 4, 2023
1 parent ed94418 commit 7056e8a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix Channel List pagination gaps [#2420](https://github.com/GetStream/stream-chat-swift/pull/2420)
- Fix truncated channels being moved to the bottom of the channel list [#2420](https://github.com/GetStream/stream-chat-swift/pull/2420)
- Fix reactions not insantly updating when enforce unique is true [#2421](https://github.com/GetStream/stream-chat-swift/pull/2421)
- Fix not being able to delete messages in `pendingSend` state [#2432](https://github.com/GetStream/stream-chat-swift/pull/2432)

## StreamChatUI
### ✅ Added
Expand Down
6 changes: 4 additions & 2 deletions Sources/StreamChat/Workers/MessageUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ class MessageUpdater: Worker {
// Hard Deleting is necessary for bounced messages, since these messages are never stored on the cloud
// an apiClient request to delete them would never be triggered.
let shouldBeHardDeleted = hard || messageDTO.failedToBeSentDueToModeration
let shouldAllowLocallyStoredMessagesToBeDeleted = !isLocalStorageEnabled || messageDTO.failedToBeSentDueToModeration

let shouldAllowLocallyStoredMessagesToBeDeleted = !isLocalStorageEnabled
|| messageDTO.localMessageState == .pendingSend
|| messageDTO.failedToBeSentDueToModeration

messageDTO.isHardDeleted = shouldBeHardDeleted

if messageDTO.existsOnlyLocally && shouldAllowLocallyStoredMessagesToBeDeleted {
Expand Down
98 changes: 68 additions & 30 deletions Tests/StreamChatTests/Workers/MessageUpdater_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,47 +394,85 @@ final class MessageUpdater_Tests: XCTestCase {

func test_deleteMessage_softlyRemovesMessageThatExistOnlyLocally_localStorageEnabled() throws {
recreateUpdater(isLocalStorageEnabled: true)
for state in [LocalMessageState.pendingSend, .sendingFailed] {
let currentUserId: UserId = .unique
let messageId: MessageId = .unique
let state = LocalMessageState.sendingFailed
let currentUserId: UserId = .unique
let messageId: MessageId = .unique

// Flush the database
let exp = expectation(description: "removeAllData completion")
database.removeAllData { error in
if let error = error {
XCTFail("removeAllData failed with \(error)")
}
exp.fulfill()
// Flush the database
let exp = expectation(description: "removeAllData completion")
database.removeAllData { error in
if let error = error {
XCTFail("removeAllData failed with \(error)")
}
wait(for: [exp], timeout: 1)
messageRepository.clear()
exp.fulfill()
}
wait(for: [exp], timeout: 1)
messageRepository.clear()

// Create current user in the database
try database.createCurrentUser(id: currentUserId)
// Create current user in the database
try database.createCurrentUser(id: currentUserId)

// Create a new message in the database
try database.createMessage(id: messageId, authorId: currentUserId, localState: state)
// Create a new message in the database
try database.createMessage(id: messageId, authorId: currentUserId, localState: state)

let expectation = expectation(description: "deleteMessage")
let expectation = expectation(description: "deleteMessage")

// Simulate `deleteMessage(messageId:)` call
messageUpdater.deleteMessage(messageId: messageId, hard: false) { error in
XCTAssertNil(error)
expectation.fulfill()
// Simulate `deleteMessage(messageId:)` call
messageUpdater.deleteMessage(messageId: messageId, hard: false) { error in
XCTAssertNil(error)
expectation.fulfill()
}

// Assert correct endpoint is called
let expectedEndpoint: Endpoint<MessagePayload.Boxed> = .deleteMessage(messageId: messageId, hard: false)
AssertAsync.willBeEqual(apiClient.request_endpoint, AnyEndpoint(expectedEndpoint))

// Simulate API response with success
let response: Result<MessagePayload.Boxed, Error> =
.success(.init(message: .dummy(messageId: .unique, authorUserId: .unique)))
apiClient.test_simulateResponse(response)

wait(for: [expectation], timeout: 0.5)
XCTAssertCall("saveSuccessfullyDeletedMessage(message:completion:)", on: messageRepository, times: 1)
}

func test_deleteMessage_softlyRemovesMessageThatExistOnlyLocally_pendingSend() throws {
recreateUpdater(isLocalStorageEnabled: true)
let state = LocalMessageState.pendingSend
let currentUserId: UserId = .unique
let messageId: MessageId = .unique

// Flush the database
let exp = expectation(description: "removeAllData completion")
database.removeAllData { error in
if let error = error {
XCTFail("removeAllData failed with \(error)")
}
exp.fulfill()
}
wait(for: [exp], timeout: 1)
messageRepository.clear()

// Assert correct endpoint is called
let expectedEndpoint: Endpoint<MessagePayload.Boxed> = .deleteMessage(messageId: messageId, hard: false)
AssertAsync.willBeEqual(apiClient.request_endpoint, AnyEndpoint(expectedEndpoint))
// Create current user in the database
try database.createCurrentUser(id: currentUserId)

// Simulate API response with success
let response: Result<MessagePayload.Boxed, Error> =
.success(.init(message: .dummy(messageId: .unique, authorUserId: .unique)))
apiClient.test_simulateResponse(response)
// Create a new message in the database
try database.createMessage(id: messageId, authorId: currentUserId, localState: state)

wait(for: [expectation], timeout: 0.5)
XCTAssertCall("saveSuccessfullyDeletedMessage(message:completion:)", on: messageRepository, times: 1)
let expectation = expectation(description: "deleteMessage")

// Simulate `deleteMessage(messageId:)` call
messageUpdater.deleteMessage(messageId: messageId, hard: false) { error in
XCTAssertNil(error)
expectation.fulfill()
}

wait(for: [expectation], timeout: 0.5)
let message = try XCTUnwrap(database.viewContext.message(id: messageId))

XCTAssertNotNil(message.deletedAt)
XCTAssertEqual(message.type, MessageType.deleted.rawValue)
XCTAssertNil(apiClient.request_endpoint)
}

func test_deleteMessage_updatesMessageStateCorrectly() throws {
Expand Down

0 comments on commit 7056e8a

Please sign in to comment.