eleven / ocho Public

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

Plain git — no account needed to clone.

Download

Download this file

1import XCTest
2@testable import LChatCore
3
4// The unread rule shared by refresh() and applyReadFrame(), and the ReadState
5// storage behind it. The watermark half must match the web's seeding in
6// shell.js loadThreads (same server field, same comparison); the manual-unread
7// flag is native-only, deliberately device-local (the server mark is
8// forward-only, so "unread again" can't ride the watermark itself).
9final class ReadSyncTests: XCTestCase {
10 func testIsUnread() {
11 // Someone else's message past the watermark lights the dot…
12 XCTAssertTrue(ThreadStore.isUnread(lastAt: 100, lastMine: false, seen: 50, manualUnreadAt: 0))
13 // …a watermark covering it (read on ANY device) clears it…
14 XCTAssertFalse(ThreadStore.isUnread(lastAt: 100, lastMine: false, seen: 100, manualUnreadAt: 0))
15 XCTAssertFalse(ThreadStore.isUnread(lastAt: 100, lastMine: false, seen: 150, manualUnreadAt: 0))
16 // …and your own last message never counts as unread, watermark or not.
17 XCTAssertFalse(ThreadStore.isUnread(lastAt: 100, lastMine: true, seen: 0, manualUnreadAt: 0))
18
19 // Mark-as-unread: the flag on exactly the newest message wins over a
20 // covering watermark…
21 XCTAssertTrue(ThreadStore.isUnread(lastAt: 100, lastMine: false, seen: 100, manualUnreadAt: 100))
22 // …retires itself once a newer message arrives (the watermark rule
23 // takes over)…
24 XCTAssertTrue(ThreadStore.isUnread(lastAt: 120, lastMine: false, seen: 100, manualUnreadAt: 100))
25 XCTAssertFalse(ThreadStore.isUnread(lastAt: 120, lastMine: false, seen: 120, manualUnreadAt: 100))
26 // …and never overrides the own-message rule.
27 XCTAssertFalse(ThreadStore.isUnread(lastAt: 100, lastMine: true, seen: 100, manualUnreadAt: 100))
28
29 // An EMPTY thread (no messages, so lastAt 0) is never unread: 0 also
30 // means "no manual flag", and the bare `manualUnreadAt == lastAt`
31 // matched 0 == 0 — every empty thread relit its dot on every refresh
32 // (the App Studio phantom dot, caught by the debug event window).
33 XCTAssertFalse(ThreadStore.isUnread(lastAt: 0, lastMine: false, seen: 0, manualUnreadAt: 0))
34 }
35
36 func testManualUnreadStorage() {
37 let inst = "test-\(UUID().uuidString)"
38 XCTAssertEqual(ReadState.manualUnreadAt(instance: inst, thread: "t"), 0, "unset reads as 0")
39 ReadState.setManualUnread(instance: inst, thread: "t", at: 42)
40 XCTAssertEqual(ReadState.manualUnreadAt(instance: inst, thread: "t"), 42)
41 ReadState.setManualUnread(instance: inst, thread: "t", at: 0)
42 XCTAssertEqual(ReadState.manualUnreadAt(instance: inst, thread: "t"), 0, "0 clears the flag")
43 UserDefaults.standard.removeObject(forKey: "lchat.unread|\(inst)|t")
44 }
45}
46