home_test.gno
3.08 Kb · 106 lines
1package home
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/testutils/v0"
8 "gno.land/p/nt/uassert/v0"
9)
10
11var notAdmin = testutils.TestAddress("mallory")
12
13// reset restores the globals to what init() sets, so assertions do not depend
14// on which tests ran before. Realm globals persist for the whole test binary.
15func reset() {
16 todos = []string{"fill this todo list..."}
17 status = "Online"
18 memeImgURL = "https://i.imgflip.com/7ze8dc.jpg"
19}
20
21// ExampleRender pins the dashboard's default output. It resets state first so
22// the example is deterministic regardless of test ordering (Go runs examples
23// after tests, and the tests below mutate these globals).
24func ExampleRender() {
25 reset()
26 print(Render(""))
27 // Output:
28 // # Manfred's (gn)home Dashboard
29 //
30 // ## Meme
31 // 
32 //
33 // ## Status
34 // Online
35 //
36 // ## Personal ToDo List
37 // - [ ] fill this todo list...
38}
39
40// TestRenderIgnoresPath documents that Render serves the same dashboard for
41// any path — it takes no sub-routes.
42func TestRenderIgnoresPath(t *testing.T) {
43 reset()
44 uassert.Equal(t, Render(""), Render("/anything"))
45}
46
47// TestRenderReflectsState checks Render tracks the admin-mutable fields.
48func TestRenderReflectsState(cur realm, t *testing.T) {
49 reset()
50 testing.SetRealm(testing.NewUserRealm(admin))
51
52 UpdateStatus(cross(cur), "Away")
53 AddNewTodo(cross(cur), "ship the thing")
54
55 out := Render("")
56 uassert.True(t, strings.Contains(out, "## Status\nAway\n"), "status should show Away")
57 uassert.True(t, strings.Contains(out, "- [ ] ship the thing\n"), "new todo should be listed")
58 uassert.True(t, strings.Contains(out, "- [ ] fill this todo list...\n"), "original todo should remain")
59}
60
61// TestDeleteTodo removes by index and keeps the rest.
62func TestDeleteTodo(cur realm, t *testing.T) {
63 reset()
64 testing.SetRealm(testing.NewUserRealm(admin))
65
66 AddNewTodo(cross(cur), "first")
67 AddNewTodo(cross(cur), "second")
68 DeleteTodo(cross(cur), 1) // drop "first"
69
70 out := Render("")
71 uassert.False(t, strings.Contains(out, "- [ ] first\n"), "deleted todo should be gone")
72 uassert.True(t, strings.Contains(out, "- [ ] second\n"), "other todo should remain")
73}
74
75// TestDeleteTodoOutOfRange covers both bounds of the index check.
76func TestDeleteTodoOutOfRange(cur realm, t *testing.T) {
77 reset()
78 testing.SetRealm(testing.NewUserRealm(admin))
79
80 uassert.AbortsWithMessage(t, cur, "Invalid todo index", func() {
81 DeleteTodo(cross(cur), -1)
82 })
83 uassert.AbortsWithMessage(t, cur, "Invalid todo index", func() {
84 DeleteTodo(cross(cur), len(todos))
85 })
86}
87
88// TestAdminGating checks every mutator rejects a non-admin caller.
89func TestAdminGating(cur realm, t *testing.T) {
90 reset()
91 testing.SetRealm(testing.NewUserRealm(notAdmin))
92
93 uassert.AbortsWithMessage(t, cur, "restricted to admin", func() {
94 AddNewTodo(cross(cur), "nope")
95 })
96 uassert.AbortsWithMessage(t, cur, "restricted to admin", func() {
97 DeleteTodo(cross(cur), 0)
98 })
99 uassert.AbortsWithMessage(t, cur, "restricted to admin", func() {
100 UpdateStatus(cross(cur), "hacked")
101 })
102
103 // State must be untouched.
104 uassert.Equal(t, "Online", status)
105 uassert.Equal(t, 1, len(todos))
106}