nandi/frqpublic Fork 0
87a28ccbc1ad41565d24fa8c4f68e1f9426fd61e
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

treactions.nim · 113 lines · 4.2 KBNim Blame HistoryRaw
The chat screen, in Nim 87a28cc nandi 19h ago1## Tallies, pills, and the rules about who may rewrite what.
2
3import std/[sequtils, tables, unittest]
4import frq/[model, reactions, edits]
5
6suite "parseTally":
7 test "the server's wire form":
8 let t = parseTally("👍:alice,bob;🎉:carol")
9 check t.len == 2
10 check t[0].emoji == "👍"
11 check t[0].nicks == @["alice", "bob"]
12 check t[1].nicks == @["carol"]
13
14 test "order is kept, because it is the order the pills are drawn in":
15 check parseTally("a:1;b:2;c:3").mapIt(it.emoji) == @["a", "b", "c"]
16
17 test "an empty tally is no pills":
18 check parseTally("").len == 0
19
20 test "a malformed part is skipped rather than fatal":
21 check parseTally("👍:alice;garbage;:bob;🎉:").mapIt(it.emoji) == @["👍"]
22
23suite "withReaction":
24 setup:
25 let base = @[Reaction(emoji: "👍", nicks: @["alice"])]
26
27 test "adding a nick":
28 check base.withReaction("👍", "bob", true)[0].nicks == @["alice", "bob"]
29
30 test "adding an emoji nobody had yet":
31 let got = base.withReaction("🎉", "bob", true)
32 check got.len == 2
33 check got[1].emoji == "🎉"
34
35 test "the same nick twice does not double it":
36 check base.withReaction("👍", "alice", true)[0].nicks == @["alice"]
37
38 test "removing the last nick removes the pill":
39 # An empty pill is a pill that says nothing.
40 check base.withReaction("👍", "alice", false).len == 0
41
42 test "removing one of several leaves the rest":
43 let two = base.withReaction("👍", "bob", true)
44 check two.withReaction("👍", "alice", false)[0].nicks == @["bob"]
45
46 test "removing a nick that is not there changes nothing":
47 check base.withReaction("👍", "zoe", false)[0].nicks == @["alice"]
48
49suite "mine":
50 setup:
51 let m = Message(reactions: @[Reaction(emoji: "👍", nicks: @["alice"])])
52 test "on it":
53 check m.mine("👍", "alice")
54 test "not on it":
55 check not m.mine("👍", "bob")
56 test "an emoji with no pill at all":
57 check not m.mine("🎉", "alice")
58
59suite "updateReaction":
60 setup:
61 var rooms = initOrderedTable[string, Room]()
62 var r = initRoom("#test")
63 r.messages = @[Message(id: "1", text: "hi"),
64 Message(id: "2", text: "there", editIds: @["2b"])]
65 rooms["#test"] = r
66
67 test "lands on the message it names":
68 rooms.updateReaction("#test", "1", "👍", "alice", true)
69 check rooms["#test"].messages[0].countOf("👍") == 1
70 check rooms["#test"].messages[1].countOf("👍") == 0
71
72 test "finds a line by a name a revision of it wore":
73 # Somebody reacting to an already-rewritten line names the revision.
74 rooms.updateReaction("#test", "2b", "🎉", "bob", true)
75 check rooms["#test"].messages[1].countOf("🎉") == 1
76
77 test "a reaction on a line we do not hold does nothing":
78 rooms.updateReaction("#test", "999", "👍", "alice", true)
79 check rooms["#test"].messages.allIt(it.reactions.len == 0)
80
81 test "a room we do not hold does nothing":
82 rooms.updateReaction("#gone", "1", "👍", "alice", true)
83 check rooms["#test"].messages[0].reactions.len == 0
84
85suite "applyEdit":
86 setup:
87 var rooms = initOrderedTable[string, Room]()
88 var r = initRoom("#test")
89 r.messages = @[Message(id: "1", frm: "alice", text: "orignal")]
90 rooms["#test"] = r
91
92 test "the sender may rewrite their own line":
93 check rooms.applyEdit("#test", "1", "alice", "original", "rev1") == erApplied
94 check rooms["#test"].messages[0].text == "original"
95 check rooms["#test"].messages[0].edited
96
97 test "the revision joins the names the line answers to":
98 # So a reply naming the revision still finds the line it belongs to.
99 discard rooms.applyEdit("#test", "1", "alice", "original", "rev1")
100 check rooms["#test"].messages[0].answersTo("rev1")
101
102 test "nobody else may":
103 # A client that believed the wire alone would let a hostile relay put
104 # words in somebody else's mouth.
105 check rooms.applyEdit("#test", "1", "mallory", "nonsense", "r") == erRefused
106 check rooms["#test"].messages[0].text == "orignal"
107
108 test "case does not decide authorship":
109 check rooms.applyEdit("#test", "1", "ALICE", "original", "r") == erApplied
110
111 test "an edit of a line we do not hold is absent, not applied":
112 check rooms.applyEdit("#test", "999", "alice", "x", "r") == erAbsent
113 check rooms.applyEdit("#gone", "1", "alice", "x", "r") == erAbsent