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// 🤖 The notification-tap resolution ladder (NotificationRoute): parked key →
5// snapshot scan → only-space. The silent-drop bug this pins: a stale or
6// missing SharedThreadKeys park used to strand the tap on the chat list.
7final class NotificationRouteTests: XCTestCase {
8
9 private func inst(_ origin: String, archived: Bool = false) -> SavedInstance {
10 var i = SavedInstance(origin: origin, deviceToken: "t", screenName: "s",
11 userPub: "pub", userPriv: "priv")
12 i.archived = archived
13 return i
14 }
15
16 func testParkedKeyWins() {
17 let a = inst("https://a.example"), b = inst("https://b.example")
18 let r = NotificationRoute.resolve(
19 threadID: "th1", instances: [a, b],
20 entryOrigin: { _ in "https://b.example" },
21 snapshotHasThread: { _, _ in XCTFail("snapshot consulted despite park"); return false })
22 guard case .parkedKey(let hit) = r else { return XCTFail("\(r)") }
23 XCTAssertEqual(hit.origin, b.origin)
24 }
25
26 func testStaleParkFallsBackToSnapshot() {
27 // The park points at an origin that's no longer signed in (re-added
28 // space) — the snapshot scan must still find the thread's real home.
29 let a = inst("https://a.example"), b = inst("https://b.example")
30 let r = NotificationRoute.resolve(
31 threadID: "th1", instances: [a, b],
32 entryOrigin: { _ in "https://gone.example" },
33 snapshotHasThread: { origin, thread in origin == "https://b.example" && thread == "th1" })
34 guard case .snapshot(let hit) = r else { return XCTFail("\(r)") }
35 XCTAssertEqual(hit.origin, b.origin)
36 }
37
38 func testMissingParkFallsBackToSnapshot() {
39 let a = inst("https://a.example"), b = inst("https://b.example")
40 let r = NotificationRoute.resolve(
41 threadID: "th1", instances: [a, b],
42 entryOrigin: { _ in nil },
43 snapshotHasThread: { origin, _ in origin == "https://a.example" })
44 guard case .snapshot(let hit) = r else { return XCTFail("\(r)") }
45 XCTAssertEqual(hit.origin, a.origin)
46 }
47
48 func testSingleSpaceAlwaysResolves() {
49 // Nothing recorded anywhere (wiped keychain, brand-new thread): with
50 // one signed-in space the tap still routes there.
51 let a = inst("https://a.example")
52 let r = NotificationRoute.resolve(
53 threadID: "new-thread", instances: [a],
54 entryOrigin: { _ in nil },
55 snapshotHasThread: { _, _ in false })
56 guard case .onlySpace(let hit) = r else { return XCTFail("\(r)") }
57 XCTAssertEqual(hit.origin, a.origin)
58 }
59
60 func testSingleActiveSpaceSkipsArchived() {
61 let live = inst("https://live.example")
62 let parked = inst("https://old.example", archived: true)
63 let r = NotificationRoute.resolve(
64 threadID: "th1", instances: [live, parked],
65 entryOrigin: { _ in nil },
66 snapshotHasThread: { _, _ in false })
67 guard case .onlySpace(let hit) = r else { return XCTFail("\(r)") }
68 XCTAssertEqual(hit.origin, live.origin)
69 }
70
71 func testMultiSpaceUnknownThreadStaysUnresolved() {
72 let a = inst("https://a.example"), b = inst("https://b.example")
73 let r = NotificationRoute.resolve(
74 threadID: "th1", instances: [a, b],
75 entryOrigin: { _ in nil },
76 snapshotHasThread: { _, _ in false })
77 guard case .unresolved = r else { return XCTFail("\(r)") }
78 }
79}
80