nandi/frqpublic Fork 0
284b59c6810a1b2abace25c071e9d166cd0dafc9
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.

tstore.nim · 119 lines · 3.7 KBNim Blame HistoryRaw
Four more modules into Nim: members, glyphs, emoji, store 3975b4b nandi 11h ago1## What survives a restart. Every case runs against a real directory under a
2## temporary XDG_CONFIG_HOME, because the thing being tested is files.
3
4import std/[os, tables, unittest]
5import frq/[store, model]
6
7template withTempConfig(body: untyped) =
8 let dir = getTempDir() / "frq-test-store-" & $getCurrentProcessId()
9 removeDir(dir)
10 createDir(dir)
11 putEnv("XDG_CONFIG_HOME", dir)
12 defer:
13 delEnv("XDG_CONFIG_HOME")
14 removeDir(dir)
15 body
16
17suite "the session":
18 test "absent when nothing was saved":
19 withTempConfig:
20 check loadSession()[1] == false
21
22 test "round-trips":
23 withTempConfig:
24 check saveSession(SavedSession(brokerToken: "tok", handle: "alice",
25 did: "did:plc:x", nick: "alice"))
26 let (s, ok) = loadSession()
27 check ok
28 check s.brokerToken == "tok"
29 check s.handle == "alice"
30 check s.did == "did:plc:x"
31
32 test "one with no broker token is not a session":
33 # The token is the whole point of saving one.
34 withTempConfig:
35 check saveSession(SavedSession(handle: "alice"))
36 check loadSession()[1] == false
37
38 test "a file that will not parse is treated as absent":
39 # A stale credential is not worth an error at startup.
40 withTempConfig:
41 createDir(configDir())
42 writeFile(sessionFile(), "{ this is not json")
43 check loadSession()[1] == false
44
45 test "is written so nobody else can read it":
46 withTempConfig:
47 check saveSession(SavedSession(brokerToken: "tok"))
48 let perms = getFilePermissions(sessionFile())
49 check fpGroupRead notin perms
50 check fpOthersRead notin perms
51
52 test "clearing it leaves nothing behind":
53 withTempConfig:
54 check saveSession(SavedSession(brokerToken: "tok"))
55 clearSession()
56 check loadSession()[1] == false
57
58 test "clearing one that is not there is not an error":
59 withTempConfig:
60 clearSession()
61
62suite "the rooms":
63 test "none when nothing was saved":
64 withTempConfig:
65 check loadRooms().len == 0
66
67 test "round-trip, with the markers":
68 # A phone that kept the names and lost the markers comes back to a
69 # hundred lines it has already read.
70 withTempConfig:
71 var rooms = initOrderedTable[string, Room]()
72 var a = initRoom("#one")
73 a.accessed = 5
74 a.lastReadId = "m1"
75 a.lastReadAt = 1234
76 rooms["#one"] = a
77 rooms["#two"] = initRoom("#two")
78 check saveRooms(rooms)
79
80 let got = loadRooms()
81 check got.len == 2
82 check got[0].name == "#one"
83 check got[0].accessed == 5
84 check got[0].lastReadId == "m1"
85 check got[0].lastReadAt == 1234
86
87 test "order is kept — most recently used first is the file's own order":
88 withTempConfig:
89 var rooms = initOrderedTable[string, Room]()
90 for n in ["#c", "#a", "#b"]: rooms[n] = initRoom(n)
91 check saveRooms(rooms)
92 check loadRooms().len == 3
93 check loadRooms()[0].name == "#c"
94
95 test "a record with no name is dropped rather than defaulted":
96 withTempConfig:
97 createDir(configDir())
98 writeFile(roomsFile(), """[{"name":"#ok"},{"accessed":3}]""")
99 let got = loadRooms()
100 check got.len == 1
101 check got[0].name == "#ok"
102
103 test "a file that will not parse is no rooms, not an error":
104 withTempConfig:
105 createDir(configDir())
106 writeFile(roomsFile(), "not json at all")
107 check loadRooms().len == 0
108
109suite "the preferences":
110 test "round-trip":
111 withTempConfig:
112 check savePrefs({"hideJoinPart": true, "showUsers": false}.toTable)
113 let got = loadPrefs()
114 check got["hideJoinPart"] == true
115 check got["showUsers"] == false
116
117 test "absent is empty":
118 withTempConfig:
119 check loadPrefs().len == 0