eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1import XCTest
2@testable import LChatCore
3
4// 🤖 Incoming-webhook events (issue #610, docs/webhooks.md): the hooks sidecar
5// posts typed `webhooks.<ns>` payloads into ordinary threads. Native claims
6// none of them — MessagePayload.isRenderableChat is the gate that keeps
7// unclaimed typed events out of the feed and out of notifications, exactly as
8// the web's foldEvent/isAppType gate does (test/event-vectors/webhooks.json is
9// the twin of this fixture; keep the payloads in step). These vectors pin two
10// things: the payload DECODES tolerantly (the unknown hook/req envelope never
11// fails MessagePayload), and it stays non-renderable.
12final class WebhooksVectorTests: XCTestCase {
13 func testWebhookEventsDecodeAndStayNonRenderable() throws {
14 let url = try XCTUnwrap(
15 Bundle.module.url(forResource: "Fixtures/webhooks-vector", withExtension: "json"),
16 "missing fixture webhooks-vector.json")
17 let raw = try JSONSerialization.jsonObject(with: Data(contentsOf: url)) as? [String: Any]
18 let vectors = try XCTUnwrap(raw?["vectors"] as? [[String: Any]], "fixture has no vectors")
19 XCTAssertFalse(vectors.isEmpty)
20
21 for vector in vectors {
22 let name = vector["name"] as? String ?? "?"
23 let event = try XCTUnwrap(vector["event"] as? [String: Any], "\(name): no event")
24 let data = try JSONSerialization.data(withJSONObject: event)
25 // Tolerant decode: the hook/req envelope is unknown to native and
26 // must be ignored, never a decode failure.
27 let p = try JSONDecoder().decode(MessagePayload.self, from: data)
28
29 XCTAssertEqual(p.type, event["type"] as? String, "\(name): type must round-trip")
30 XCTAssertEqual(p.name, event["name"] as? String, "\(name): attribution name")
31 XCTAssertEqual(p.uid, event["uid"] as? String, "\(name): attribution uid")
32 // The contract: an unclaimed typed event renders nothing — no
33 // bubble, no notification. A future consumer surface may claim a
34 // webhooks.* type deliberately; flipping this assertion then must
35 // be a conscious cross-platform change with the web's gate.
36 XCTAssertFalse(p.isRenderableChat, "\(name): webhook events must not render as chat")
37 XCTAssertFalse(p.isReactionEvent, "\(name): webhook events are not reactions")
38 }
39 }
40}
41