diff --git a/Example/AblyChatExample/Mocks/Misc.swift b/Example/AblyChatExample/Mocks/Misc.swift index 9a0c2587..790b4e19 100644 --- a/Example/AblyChatExample/Mocks/Misc.swift +++ b/Example/AblyChatExample/Mocks/Misc.swift @@ -12,7 +12,7 @@ final class MockMessagesPaginatedResult: PaginatedResult { Array(repeating: 0, count: numberOfMockMessages).map { _ in Message( serial: "\(Date().timeIntervalSince1970)", - latestAction: .create, + action: .create, clientID: self.clientID, roomID: self.roomID, text: MockStrings.randomPhrase(), diff --git a/Example/AblyChatExample/Mocks/MockClients.swift b/Example/AblyChatExample/Mocks/MockClients.swift index 831d7044..1a950d65 100644 --- a/Example/AblyChatExample/Mocks/MockClients.swift +++ b/Example/AblyChatExample/Mocks/MockClients.swift @@ -104,7 +104,7 @@ actor MockMessages: Messages { let subscription = MockSubscription(randomElement: { Message( serial: "\(Date().timeIntervalSince1970)", - latestAction: .create, + action: .create, clientID: MockStrings.names.randomElement()!, roomID: self.roomID, text: MockStrings.randomPhrase(), @@ -130,7 +130,7 @@ actor MockMessages: Messages { func send(params: SendMessageParams) async throws -> Message { let message = Message( serial: "\(Date().timeIntervalSince1970)", - latestAction: .create, + action: .create, clientID: clientID, roomID: roomID, text: params.text, diff --git a/Sources/AblyChat/ChatAPI.swift b/Sources/AblyChat/ChatAPI.swift index 3792d0f8..9ea9978d 100644 --- a/Sources/AblyChat/ChatAPI.swift +++ b/Sources/AblyChat/ChatAPI.swift @@ -46,7 +46,7 @@ internal final class ChatAPI: Sendable { let message = Message( serial: response.serial, - latestAction: .create, + action: .create, clientID: clientId, roomID: roomId, text: params.text, diff --git a/Sources/AblyChat/DefaultMessages.swift b/Sources/AblyChat/DefaultMessages.swift index 5c2fea1b..03339058 100644 --- a/Sources/AblyChat/DefaultMessages.swift +++ b/Sources/AblyChat/DefaultMessages.swift @@ -83,7 +83,7 @@ internal final class DefaultMessages: Messages, EmitsDiscontinuities { let message = Message( serial: serial, - latestAction: action, + action: action, clientID: clientID, roomID: self.roomID, text: text, diff --git a/Sources/AblyChat/Message.swift b/Sources/AblyChat/Message.swift index a9053b7c..b781bad5 100644 --- a/Sources/AblyChat/Message.swift +++ b/Sources/AblyChat/Message.swift @@ -9,7 +9,7 @@ public struct Message: Sendable, Codable, Identifiable, Equatable { public var id: String { serial } public var serial: String - public var latestAction: MessageAction + public var action: MessageAction public var clientID: String public var roomID: String public var text: String @@ -17,9 +17,9 @@ public struct Message: Sendable, Codable, Identifiable, Equatable { public var metadata: MessageMetadata public var headers: MessageHeaders - public init(serial: String, latestAction: MessageAction, clientID: String, roomID: String, text: String, createdAt: Date?, metadata: MessageMetadata, headers: MessageHeaders) { + public init(serial: String, action: MessageAction, clientID: String, roomID: String, text: String, createdAt: Date?, metadata: MessageMetadata, headers: MessageHeaders) { self.serial = serial - self.latestAction = latestAction + self.action = action self.clientID = clientID self.roomID = roomID self.text = text @@ -30,7 +30,7 @@ public struct Message: Sendable, Codable, Identifiable, Equatable { internal enum CodingKeys: String, CodingKey { case serial - case latestAction + case action case clientID = "clientId" case roomID = "roomId" case text diff --git a/Tests/AblyChatTests/ChatAPITests.swift b/Tests/AblyChatTests/ChatAPITests.swift index 8564ed6f..e160d3ff 100644 --- a/Tests/AblyChatTests/ChatAPITests.swift +++ b/Tests/AblyChatTests/ChatAPITests.swift @@ -41,7 +41,7 @@ struct ChatAPITests { // Then let expectedMessage = Message( serial: "3446456", - latestAction: .create, + action: .create, clientID: "mockClientId", roomID: roomId, text: "hello", @@ -91,7 +91,7 @@ struct ChatAPITests { items: [ Message( serial: "3446456", - latestAction: .create, + action: .create, clientID: "random", roomID: roomId, text: "hello", @@ -101,7 +101,7 @@ struct ChatAPITests { ), Message( serial: "3446457", - latestAction: .create, + action: .create, clientID: "random", roomID: roomId, text: "hello response", diff --git a/Tests/AblyChatTests/IntegrationTests.swift b/Tests/AblyChatTests/IntegrationTests.swift index abbfa2af..a0104399 100644 --- a/Tests/AblyChatTests/IntegrationTests.swift +++ b/Tests/AblyChatTests/IntegrationTests.swift @@ -116,7 +116,36 @@ struct IntegrationTests { #expect(rxMessageFromSubscription == txMessageAfterRxSubscribe) // (7) Fetch historical messages from before subscribing, and check we get txMessageBeforeRxSubscribe - let rxMessagesBeforeSubscribing = try await rxMessageSubscription.getPreviousMessages(params: .init()) + + /* + TODO: This line should just be + + let messages = try await rxMessageSubscription.getPreviousMessages(params: .init()) + + but sometimes `messages.items` is coming back empty. Andy said in + https://ably-real-time.slack.com/archives/C03JDBVM5MY/p1733220395208909 + that + + > new materialised history system doesn’t currently support “live” + > history (realtime implementation detail) - so we’re approximating the + > behaviour + + and indicated that the right workaround for now is to introduce a + wait. So we retry the fetching of history until we get a non-empty + result. + + Revert this (https://github.com/ably/ably-chat-swift/issues/175) once it’s fixed in Realtime. + */ + let rxMessagesBeforeSubscribing = try await { + while true { + let messages = try await rxMessageSubscription.getPreviousMessages(params: .init()) + if !messages.items.isEmpty { + return messages + } + // Wait 1 second before retrying the history fetch + try await Task.sleep(nanoseconds: NSEC_PER_SEC) + } + }() try #require(rxMessagesBeforeSubscribing.items.count == 1) #expect(rxMessagesBeforeSubscribing.items[0] == txMessageBeforeRxSubscribe) @@ -149,22 +178,26 @@ struct IntegrationTests { // (4) Enter presence on the other client and check that we receive the updated occupancy on the subscription try await txRoom.presence.enter(data: nil) - // It can take a moment for the occupancy to update from the clients entering presence above, so we’ll wait 2 seconds here. - try await Task.sleep(nanoseconds: 2_000_000_000) - - // (5) Check that we received an updated presence count when getting the occupancy - let updatedCurrentOccupancy = try await rxRoom.occupancy.get() - #expect(updatedCurrentOccupancy.presenceMembers == 1) // 1 for txClient entering presence + // (5) Check that we received an updated presence count on the subscription + _ = try #require(await rxOccupancySubscription.first { occupancyEvent in + occupancyEvent.presenceMembers == 1 // 1 for txClient entering presence + }) - // (6) Check that we received an updated presence count on the subscription - let rxOccupancyEventFromSubscription = try #require(await rxOccupancySubscription.first { _ in true }) - - #expect(rxOccupancyEventFromSubscription.presenceMembers == 1) // 1 for txClient entering presence + // (6) Check that we received an updated presence count when getting the occupancy + let rxOccupancyAfterTxEnter = try await rxRoom.occupancy.get() + #expect(rxOccupancyAfterTxEnter.presenceMembers == 1) // 1 for txClient entering presence + // (7) Leave presence on the other client and check that we receive the updated occupancy on the subscription try await txRoom.presence.leave(data: nil) - // It can take a moment for the occupancy to update from the clients leaving presence above, so we’ll wait 2 seconds here. Important for the occupancy tests below. - try await Task.sleep(nanoseconds: 2_000_000_000) + // (8) Check that we received an updated presence count on the subscription + _ = try #require(await rxOccupancySubscription.first { occupancyEvent in + occupancyEvent.presenceMembers == 0 // 0 for txClient leaving presence + }) + + // (9) Check that we received an updated presence count when getting the occupancy + let rxOccupancyAfterTxLeave = try await rxRoom.occupancy.get() + #expect(rxOccupancyAfterTxLeave.presenceMembers == 0) // 0 for txClient leaving presence // MARK: - Presence diff --git a/Tests/AblyChatTests/MessageSubscriptionTests.swift b/Tests/AblyChatTests/MessageSubscriptionTests.swift index 7bbea980..c6d27ade 100644 --- a/Tests/AblyChatTests/MessageSubscriptionTests.swift +++ b/Tests/AblyChatTests/MessageSubscriptionTests.swift @@ -26,7 +26,7 @@ private final class MockPaginatedResult: PaginatedResult { struct MessageSubscriptionTests { let messages = ["First", "Second"].map { text in - Message(serial: "", latestAction: .create, clientID: "", roomID: "", text: text, createdAt: .init(), metadata: [:], headers: [:]) + Message(serial: "", action: .create, clientID: "", roomID: "", text: text, createdAt: .init(), metadata: [:], headers: [:]) } @Test diff --git a/Tests/AblyChatTests/MessageTests.swift b/Tests/AblyChatTests/MessageTests.swift index 115fdbd1..e085d72a 100644 --- a/Tests/AblyChatTests/MessageTests.swift +++ b/Tests/AblyChatTests/MessageTests.swift @@ -4,7 +4,7 @@ import Testing struct MessageTests { let earlierMessage = Message( serial: "ABC123@1631840000000-5:2", - latestAction: .create, + action: .create, clientID: "testClientID", roomID: "roomId", text: "hello", @@ -15,7 +15,7 @@ struct MessageTests { let laterMessage = Message( serial: "ABC123@1631840000001-5:2", - latestAction: .create, + action: .create, clientID: "testClientID", roomID: "roomId", text: "hello", @@ -26,7 +26,7 @@ struct MessageTests { let invalidMessage = Message( serial: "invalid", - latestAction: .create, + action: .create, clientID: "testClientID", roomID: "roomId", text: "hello", @@ -70,7 +70,7 @@ struct MessageTests { func isEqual_whenMessageIsEqual_ReturnsTrue() async throws { let duplicateOfEarlierMessage = Message( serial: "ABC123@1631840000000-5:2", - latestAction: .create, + action: .create, clientID: "random", roomID: "", text: "", diff --git a/Tests/AblyChatTests/Mocks/MockHTTPPaginatedResponse.swift b/Tests/AblyChatTests/Mocks/MockHTTPPaginatedResponse.swift index e31e2086..43587ae7 100644 --- a/Tests/AblyChatTests/Mocks/MockHTTPPaginatedResponse.swift +++ b/Tests/AblyChatTests/Mocks/MockHTTPPaginatedResponse.swift @@ -99,7 +99,7 @@ extension MockHTTPPaginatedResponse { [ "clientId": "random", "serial": "3446456", - "latestAction": "message.create", + "action": "message.create", "createdAt": 1_730_943_049_269, "roomId": "basketball::$chat::$chatMessages", "text": "hello", @@ -109,7 +109,7 @@ extension MockHTTPPaginatedResponse { [ "clientId": "random", "serial": "3446457", - "latestAction": "message.create", + "action": "message.create", "roomId": "basketball::$chat::$chatMessages", "text": "hello response", "metadata": [:],