oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1import XCTest
2
3@testable import CallsKit
4
5/// "Reconnecting…" only for a problem that lasts (spec §15.23). Paul,
6/// 2026-09-30: "I saw 'Reconnecting' appear occasionally over the video,
7/// but only for a second … I didn't notice any interruption."
8final class ReconnectWatchTests: XCTestCase {
9 private typealias Peer = ReconnectWatch.Peer
10 private let fine = Peer()
11
12 /// Runs the watch at 5 Hz from `from` to `to` seconds, and returns the
13 /// times at which the whole call's words were showing.
14 private func run(
15 _ watch: inout ReconnectWatch, from: Double, to: Double,
16 stream: (Double) -> Bool, people: (Double) -> [String: Peer]
17 ) -> (call: [Double], peers: [Double: Set<String>]) {
18 var call: [Double] = []
19 var peers: [Double: Set<String>] = [:]
20 var t = from
21 while t < to {
22 watch.observe(at: t, streamDown: stream(t), people: people(t))
23 if watch.call { call.append(t) }
24 if !watch.peers.isEmpty { peers[t] = watch.peers }
25 t = (t * 10 + 2).rounded() / 10
26 }
27 return (call, peers)
28 }
29
30 func testARoutineStreamRenewalIsNeverShown() {
31 // The stream ends on purpose and is back half a second later, over and
32 // over, and a slower resume of three and a half seconds as well.
33 var watch = ReconnectWatch()
34 let seen = run(
35 &watch, from: 0, to: 60,
36 stream: { t in (10..<10.6).contains(t) || (30..<33.5).contains(t) || (50..<50.4).contains(t) },
37 people: { _ in ["sam": self.fine] })
38 XCTAssertEqual(seen.call, [])
39 XCTAssertTrue(seen.peers.isEmpty)
40 }
41
42 func testAStreamDownFourSecondsIsShownAndHeldASecondPastRecovery() {
43 var watch = ReconnectWatch()
44 let seen = run(&watch, from: 0, to: 20, stream: { (5..<12).contains($0) }, people: { _ in ["sam": self.fine] })
45 XCTAssertEqual(seen.call.first, 9, "down at 5, said at 9")
46 XCTAssertEqual(seen.call.last, 12.8, "back at 12, said until a second after")
47 }
48
49 func testShortBlipsOnOnePersonAreNeverShown() {
50 var watch = ReconnectWatch()
51 let seen = run(
52 &watch, from: 0, to: 30, stream: { _ in false },
53 people: { t in
54 ["sam": Peer(connectionBad: (5..<7.5).contains(t), audioMissing: (15..<16.5).contains(t))]
55 })
56 XCTAssertEqual(seen.call, [])
57 XCTAssertTrue(seen.peers.isEmpty, "\(seen.peers)")
58 }
59
60 func testOnePersonsLastingTroubleIsSaidOnTheirTileAlone() {
61 var watch = ReconnectWatch()
62 let seen = run(
63 &watch, from: 0, to: 30, stream: { _ in false },
64 people: { t in ["sam": Peer(connectionBad: (5..<15).contains(t)), "ana": self.fine] })
65 XCTAssertEqual(seen.call, [], "not the whole call")
66 let times = seen.peers.keys.sorted()
67 XCTAssertEqual(times.first, 8, "disconnected at 5, said at 8")
68 XCTAssertEqual(times.last, 15.8, "held a second past recovery")
69 XCTAssertTrue(seen.peers.values.allSatisfy { $0 == ["sam"] })
70 }
71
72 func testAudioThatStopsFromSomeoneUnmutedIsSaidAfterTwoSeconds() {
73 var watch = ReconnectWatch()
74 let seen = run(
75 &watch, from: 0, to: 20, stream: { _ in false },
76 people: { t in ["sam": Peer(audioMissing: (5..<10).contains(t)), "ana": self.fine] })
77 XCTAssertEqual(seen.peers.keys.sorted().first, 7)
78 }
79
80 func testEveryonesTroubleIsTheWholeCall() {
81 var watch = ReconnectWatch()
82 let seen = run(
83 &watch, from: 0, to: 20, stream: { _ in false },
84 people: { t in
85 let bad = (5..<12).contains(t)
86 return ["sam": Peer(connectionBad: bad), "ana": Peer(connectionBad: bad)]
87 })
88 XCTAssertEqual(seen.call.first, 8)
89 XCTAssertTrue(seen.peers.isEmpty, "not two tiles as well")
90 }
91
92 func testTheWords() {
93 XCTAssertEqual(ReconnectWords.call, "Reconnecting…")
94 XCTAssertEqual(ReconnectWords.peer("Samuel"), "Reconnecting to Samuel…")
95 }
96
97 func testTheNoticeFollowsTheWatchNotThePhase() {
98 let notices = CallNotices.notices(
99 phase: "admitted", status: "In the meeting", sharingScreen: false, screenNote: "", floor: false)
100 XCTAssertFalse(notices.contains { $0.kind == .reconnecting })
101 }
102}
103