nandi/frqpublic Fork 0
1403956859648c3d39892e3994df8fee863ec653
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.

The chat screen, in Nim 87a28cc · on 1403956859648c3d39892e3994df8fee863ec653 · nandi · 16h ago
treactions.nim · 113 lines · 4.2 KBNim Blame HistoryRaw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
## Tallies, pills, and the rules about who may rewrite what.

import std/[sequtils, tables, unittest]
import frq/[model, reactions, edits]

suite "parseTally":
  test "the server's wire form":
    let t = parseTally("👍:alice,bob;🎉:carol")
    check t.len == 2
    check t[0].emoji == "👍"
    check t[0].nicks == @["alice", "bob"]
    check t[1].nicks == @["carol"]

  test "order is kept, because it is the order the pills are drawn in":
    check parseTally("a:1;b:2;c:3").mapIt(it.emoji) == @["a", "b", "c"]

  test "an empty tally is no pills":
    check parseTally("").len == 0

  test "a malformed part is skipped rather than fatal":
    check parseTally("👍:alice;garbage;:bob;🎉:").mapIt(it.emoji) == @["👍"]

suite "withReaction":
  setup:
    let base = @[Reaction(emoji: "👍", nicks: @["alice"])]

  test "adding a nick":
    check base.withReaction("👍", "bob", true)[0].nicks == @["alice", "bob"]

  test "adding an emoji nobody had yet":
    let got = base.withReaction("🎉", "bob", true)
    check got.len == 2
    check got[1].emoji == "🎉"

  test "the same nick twice does not double it":
    check base.withReaction("👍", "alice", true)[0].nicks == @["alice"]

  test "removing the last nick removes the pill":
    # An empty pill is a pill that says nothing.
    check base.withReaction("👍", "alice", false).len == 0

  test "removing one of several leaves the rest":
    let two = base.withReaction("👍", "bob", true)
    check two.withReaction("👍", "alice", false)[0].nicks == @["bob"]

  test "removing a nick that is not there changes nothing":
    check base.withReaction("👍", "zoe", false)[0].nicks == @["alice"]

suite "mine":
  setup:
    let m = Message(reactions: @[Reaction(emoji: "👍", nicks: @["alice"])])
  test "on it":
    check m.mine("👍", "alice")
  test "not on it":
    check not m.mine("👍", "bob")
  test "an emoji with no pill at all":
    check not m.mine("🎉", "alice")

suite "updateReaction":
  setup:
    var rooms = initOrderedTable[string, Room]()
    var r = initRoom("#test")
    r.messages = @[Message(id: "1", text: "hi"),
                   Message(id: "2", text: "there", editIds: @["2b"])]
    rooms["#test"] = r

  test "lands on the message it names":
    rooms.updateReaction("#test", "1", "👍", "alice", true)
    check rooms["#test"].messages[0].countOf("👍") == 1
    check rooms["#test"].messages[1].countOf("👍") == 0

  test "finds a line by a name a revision of it wore":
    # Somebody reacting to an already-rewritten line names the revision.
    rooms.updateReaction("#test", "2b", "🎉", "bob", true)
    check rooms["#test"].messages[1].countOf("🎉") == 1

  test "a reaction on a line we do not hold does nothing":
    rooms.updateReaction("#test", "999", "👍", "alice", true)
    check rooms["#test"].messages.allIt(it.reactions.len == 0)

  test "a room we do not hold does nothing":
    rooms.updateReaction("#gone", "1", "👍", "alice", true)
    check rooms["#test"].messages[0].reactions.len == 0

suite "applyEdit":
  setup:
    var rooms = initOrderedTable[string, Room]()
    var r = initRoom("#test")
    r.messages = @[Message(id: "1", frm: "alice", text: "orignal")]
    rooms["#test"] = r

  test "the sender may rewrite their own line":
    check rooms.applyEdit("#test", "1", "alice", "original", "rev1") == erApplied
    check rooms["#test"].messages[0].text == "original"
    check rooms["#test"].messages[0].edited

  test "the revision joins the names the line answers to":
    # So a reply naming the revision still finds the line it belongs to.
    discard rooms.applyEdit("#test", "1", "alice", "original", "rev1")
    check rooms["#test"].messages[0].answersTo("rev1")

  test "nobody else may":
    # A client that believed the wire alone would let a hostile relay put
    # words in somebody else's mouth.
    check rooms.applyEdit("#test", "1", "mallory", "nonsense", "r") == erRefused
    check rooms["#test"].messages[0].text == "orignal"

  test "case does not decide authorship":
    check rooms.applyEdit("#test", "1", "ALICE", "original", "r") == erApplied

  test "an edit of a line we do not hold is absent, not applied":
    check rooms.applyEdit("#test", "999", "alice", "x", "r") == erAbsent
    check rooms.applyEdit("#gone", "1", "alice", "x", "r") == erAbsent