added .read state
This commit is contained in:
1 parent
299f78de36
commit
16c9fab509
9 files changed
+513
-19
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import XCTest
|
||||
@testable import Luma
|
||||
|
||||
final class ChatMessageDeliveryTests: XCTestCase {
|
||||
func testMergeKeepsTheStrongestState() {
|
||||
XCTAssertEqual(ChatMessage.Delivery.sent.merged(with: .sending), .sent)
|
||||
XCTAssertEqual(ChatMessage.Delivery.sending.merged(with: .sent), .sent)
|
||||
XCTAssertEqual(ChatMessage.Delivery.sent.merged(with: .delivered), .delivered)
|
||||
XCTAssertEqual(ChatMessage.Delivery.delivered.merged(with: .read), .read)
|
||||
XCTAssertEqual(ChatMessage.Delivery.read.merged(with: .sent), .read)
|
||||
XCTAssertEqual(ChatMessage.Delivery.read.merged(with: .delivered), .read)
|
||||
}
|
||||
|
||||
func testMAMReplayNeverDowngradesReadState() {
|
||||
// The archived copy of an outgoing message carries `.sent`; the local
|
||||
// copy that received the peer's displayed marker must stay `.read`.
|
||||
XCTAssertEqual(ChatMessage.Delivery.read.merged(with: .sent), .read)
|
||||
XCTAssertEqual(ChatMessage.Delivery.delivered.merged(with: .sent), .delivered)
|
||||
}
|
||||
|
||||
func testFailedIsSticky() {
|
||||
XCTAssertEqual(ChatMessage.Delivery.failed.merged(with: .sent), .failed)
|
||||
XCTAssertEqual(ChatMessage.Delivery.sent.merged(with: .failed), .failed)
|
||||
}
|
||||
|
||||
func testReadMessagesRemainEditableAndRetractable() {
|
||||
let message = ChatMessage(
|
||||
conversationID: "bob@example.org",
|
||||
senderJID: "alice@example.org",
|
||||
body: "привет",
|
||||
direction: .outgoing,
|
||||
delivery: .read,
|
||||
security: .plaintext
|
||||
)
|
||||
XCTAssertTrue(message.canBeEdited)
|
||||
XCTAssertTrue(message.canBeRetracted)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import Martin
|
||||
import XCTest
|
||||
@testable import Luma
|
||||
|
||||
final class ReadStateSyncTests: XCTestCase {
|
||||
private func makePayloadMessage(id: String = "marker-42") -> Message {
|
||||
let message = Message()
|
||||
message.id = id
|
||||
let payload = Element(name: "read-marker", xmlns: ReadStateSync.namespace)
|
||||
payload.addChild(Element(name: "conversation", cdata: "Bob@Example.org"))
|
||||
payload.addChild(Element(name: "id", cdata: "msg-uuid"))
|
||||
payload.addChild(Element(name: "stanza", cdata: "stanza-7"))
|
||||
payload.addChild(Element(name: "when", cdata: "2026-09-14T12:00:00Z"))
|
||||
message.addChild(payload)
|
||||
return message
|
||||
}
|
||||
|
||||
func testEnvelopeParsesPayload() throws {
|
||||
let envelope = try XCTUnwrap(ReadStateSync.envelope(from: makePayloadMessage()))
|
||||
XCTAssertEqual(envelope.id, "marker-42")
|
||||
XCTAssertEqual(envelope.conversationJID, "bob@example.org")
|
||||
XCTAssertEqual(envelope.messageID, "msg-uuid")
|
||||
XCTAssertEqual(envelope.stanzaID, "stanza-7")
|
||||
XCTAssertEqual(
|
||||
envelope.timestamp,
|
||||
ISO8601DateFormatter().date(from: "2026-09-14T12:00:00Z")
|
||||
)
|
||||
}
|
||||
|
||||
func testEnvelopePrefersOriginID() throws {
|
||||
let message = makePayloadMessage()
|
||||
let origin = Element(name: "origin-id", xmlns: "urn:xmpp:sid:0")
|
||||
origin.setAttribute("id", value: "marker-uuid")
|
||||
message.addChild(origin)
|
||||
XCTAssertEqual(ReadStateSync.envelope(from: message)?.id, "marker-uuid")
|
||||
}
|
||||
|
||||
func testEnvelopeIgnoresOrdinaryMessages() {
|
||||
let message = Message()
|
||||
message.body = "hello"
|
||||
XCTAssertNil(ReadStateSync.envelope(from: message))
|
||||
}
|
||||
|
||||
func testEnvelopeAllowsMissingStanzaID() throws {
|
||||
let message = Message()
|
||||
message.id = "marker-1"
|
||||
let payload = Element(name: "read-marker", xmlns: ReadStateSync.namespace)
|
||||
payload.addChild(Element(name: "conversation", cdata: "bob@example.org"))
|
||||
payload.addChild(Element(name: "id", cdata: "msg-uuid"))
|
||||
message.addChild(payload)
|
||||
let envelope = try XCTUnwrap(ReadStateSync.envelope(from: message))
|
||||
XCTAssertNil(envelope.stanzaID)
|
||||
}
|
||||
|
||||
func testPayloadRoundTripPreservesReadDetails() throws {
|
||||
let marker = ReadStateSync.Envelope(
|
||||
id: "marker-1",
|
||||
conversationJID: "Room@Conference.example.org",
|
||||
messageID: "msg-uuid",
|
||||
stanzaID: "stanza-7",
|
||||
timestamp: Date(timeIntervalSince1970: 1_700_000_000)
|
||||
)
|
||||
let message = Message()
|
||||
message.id = marker.id
|
||||
message.addChild(ReadStateSync.payloadElement(marker: marker))
|
||||
|
||||
let envelope = try XCTUnwrap(ReadStateSync.envelope(from: message))
|
||||
XCTAssertEqual(envelope.id, "marker-1")
|
||||
XCTAssertEqual(envelope.conversationJID, "room@conference.example.org")
|
||||
XCTAssertEqual(envelope.messageID, "msg-uuid")
|
||||
XCTAssertEqual(envelope.stanzaID, "stanza-7")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user