handles_test.gno
3.50 Kb · 146 lines
1package handles
2
3import (
4 "testing"
5
6 "gno.land/p/nt/avl/v0"
7 "gno.land/p/nt/testutils/v0"
8)
9
10var (
11 alice = testutils.TestAddress("alice")
12 bob = testutils.TestAddress("bob")
13)
14
15// reset clears package state between tests so cases stay independent.
16func reset() {
17 byHandle = avl.Tree{}
18 byOwner = avl.Tree{}
19}
20
21func TestValidHandle(t *testing.T) {
22 cases := map[string]bool{
23 "moul": true,
24 "m": false, // too short
25 "ab": false, // too short
26 "Moul": false, // uppercase
27 "1moul": false, // starts with digit
28 "moul1": true,
29 "moul-1": false, // hyphen
30 "averylonghandlethatistoolong12": false, // too long
31 }
32 for h, want := range cases {
33 if got := validHandle(h); got != want {
34 t.Errorf("validHandle(%q) = %v, want %v", h, got, want)
35 }
36 }
37}
38
39func TestRegisterAndLookup(cur realm, t *testing.T) {
40 reset()
41
42 testing.SetRealm(testing.NewUserRealm(alice))
43 Register(cross(cur), "moul")
44
45 owner, ok := OwnerOf("moul")
46 if !ok || owner != alice {
47 t.Fatalf("OwnerOf(moul) = %v, %v; want %v, true", owner, ok, alice)
48 }
49 handle, ok := HandleOf(alice)
50 if !ok || handle != "moul" {
51 t.Fatalf("HandleOf(alice) = %q, %v; want moul, true", handle, ok)
52 }
53 if got := Count(); got != 1 {
54 t.Fatalf("Count() = %d, want 1", got)
55 }
56}
57
58func TestRegisterRejectsTakenHandle(cur realm, t *testing.T) {
59 reset()
60
61 testing.SetRealm(testing.NewUserRealm(alice))
62 Register(cross(cur), "moul")
63
64 testing.SetRealm(testing.NewUserRealm(bob))
65 defer func() {
66 if r := recover(); r == nil {
67 t.Errorf("expected panic registering a taken handle")
68 }
69 }()
70 Register(cur, "moul")
71}
72
73func TestRegisterRejectsSecondHandleForSameOwner(cur realm, t *testing.T) {
74 reset()
75
76 testing.SetRealm(testing.NewUserRealm(alice))
77 Register(cross(cur), "moul")
78
79 testing.SetRealm(testing.NewUserRealm(alice))
80 defer func() {
81 if r := recover(); r == nil {
82 t.Errorf("expected panic when the same owner registers twice")
83 }
84 }()
85 Register(cur, "second")
86}
87
88func TestTransferAndRelease(cur realm, t *testing.T) {
89 reset()
90
91 testing.SetRealm(testing.NewUserRealm(alice))
92 Register(cross(cur), "moul")
93
94 testing.SetRealm(testing.NewUserRealm(alice))
95 Transfer(cross(cur), bob)
96
97 if _, ok := HandleOf(alice); ok {
98 t.Fatalf("alice should no longer own a handle after transfer")
99 }
100 handle, ok := HandleOf(bob)
101 if !ok || handle != "moul" {
102 t.Fatalf("HandleOf(bob) = %q, %v; want moul, true", handle, ok)
103 }
104
105 testing.SetRealm(testing.NewUserRealm(bob))
106 Release(cross(cur))
107
108 if Count() != 0 {
109 t.Fatalf("Count() = %d, want 0 after release", Count())
110 }
111 if _, ok := OwnerOf("moul"); ok {
112 t.Fatalf("moul should be unclaimed after release")
113 }
114}
115
116func TestSetBioAndRender(cur realm, t *testing.T) {
117 reset()
118
119 testing.SetRealm(testing.NewUserRealm(alice))
120 Register(cross(cur), "moul")
121 SetBio(cross(cur), "building gno stuff")
122
123 out := Render("/moul")
124 if !contains(out, "moul") || !contains(out, "building gno stuff") {
125 t.Fatalf("Render(/moul) missing expected content: %s", out)
126 }
127
128 index := Render("")
129 if !contains(index, "moul") {
130 t.Fatalf("Render('') missing handle in index: %s", index)
131 }
132
133 missing := Render("/nobody")
134 if !contains(missing, "No handle named") {
135 t.Fatalf("Render(/nobody) should report missing handle: %s", missing)
136 }
137}
138
139func contains(s, substr string) bool {
140 for i := 0; i+len(substr) <= len(s); i++ {
141 if s[i:i+len(substr)] == substr {
142 return true
143 }
144 }
145 return false
146}