records_test.gno
4.43 Kb · 135 lines
1package gns
2
3import (
4 "testing"
5)
6
7func TestTypedRecords(cur realm, t *testing.T) {
8 reset()
9 doRegister(cur, "alice", alice, 100000)
10
11 testing.SetRealm(testing.NewUserRealm(alice))
12 SetAddress(cross(cur), "alice", alice.String())
13 SetText(cross(cur), "alice", "com.github", "moul")
14 SetCoinAddress(cross(cur), "alice", "60", []byte{0xde, 0xad})
15 SetContentHash(cross(cur), "alice", []byte{0x12, 0x20})
16 SetPublicKey(cross(cur), "alice", []byte{0x01, 0x02})
17 SetABI(cross(cur), "alice", "application/json", []byte("{}"))
18 SetInterface(cross(cur), "alice", "0x1", "gno.land/r/demo/foo")
19 SetRecord(cross(cur), "alice", "com.example", "game", []byte("hi"))
20
21 addr, ok := Address("alice")
22 isTrue(t, ok, "address set")
23 eqStr(t, alice.String(), addr, "address value")
24
25 txt, ok := Text("alice", "com.github")
26 isTrue(t, ok, "text set")
27 eqStr(t, "moul", txt, "text value")
28
29 coin, ok := CoinAddress("alice", "60")
30 isTrue(t, ok, "coin set")
31 eqInt(t, 2, int64(len(coin)), "coin len")
32
33 _, ok = ContentHash("alice")
34 isTrue(t, ok, "contenthash set")
35 _, ok = PublicKey("alice")
36 isTrue(t, ok, "pubkey set")
37 _, ok = ABI("alice", "application/json")
38 isTrue(t, ok, "abi set")
39
40 iface, ok := Interface("alice", "0x1")
41 isTrue(t, ok, "interface set")
42 eqStr(t, "gno.land/r/demo/foo", iface, "interface value")
43
44 rec, ok := Record("alice", "com.example", "game")
45 isTrue(t, ok, "record set")
46 eqStr(t, "hi", string(rec), "record value")
47}
48
49func TestTextDeletePhysical(cur realm, t *testing.T) {
50 reset()
51 doRegister(cur, "alice", alice, 100000)
52
53 testing.SetRealm(testing.NewUserRealm(alice))
54 SetText(cross(cur), "alice", "url", "https://example.com")
55 _, ok := Text("alice", "url")
56 isTrue(t, ok, "url present")
57
58 // empty value physically removes it
59 testing.SetRealm(testing.NewUserRealm(alice))
60 SetText(cross(cur), "alice", "url", "")
61 _, ok = Text("alice", "url")
62 isFalse(t, ok, "url removed")
63
64 n := getRaw("alice")
65 eqInt(t, 0, int64(n.Records.Count), "record count back to zero")
66}
67
68func TestRevisionBumps(cur realm, t *testing.T) {
69 reset()
70 doRegister(cur, "alice", alice, 100000)
71 r0 := getRaw("alice").Revision
72
73 testing.SetRealm(testing.NewUserRealm(alice))
74 SetText(cross(cur), "alice", "a", "1")
75 r1 := getRaw("alice").Revision
76 isTrue(t, r1 > r0, "revision increments on record change")
77}
78
79func TestResolveExactAndAncestor(cur realm, t *testing.T) {
80 reset()
81 doRegister(cur, "company", alice, 100000)
82
83 // open subname policy so we can create a child
84 testing.SetRealm(testing.NewUserRealm(alice))
85 SetRegistrationPolicy(cross(cur), "company", RegistrationPolicy{Mode: ModeOpen})
86 testing.SetRealm(testing.NewUserRealm(alice))
87 CreateSubname(cross(cur), "company", "api", alice, SubnameOptions{Duration: 100000})
88
89 // text only on the parent
90 testing.SetRealm(testing.NewUserRealm(alice))
91 SetText(cross(cur), "company", "url", "https://company.example")
92
93 // exact on child: not found
94 exact := Resolve("api.company", RecordQuery{Kind: "text", Key1: "url"}, Exact)
95 isFalse(t, exact.Found, "exact child has no url")
96
97 // nearest ancestor: inherits from company
98 inh := Resolve("api.company", RecordQuery{Kind: "text", Key1: "url"}, NearestAncestor)
99 isTrue(t, inh.Found, "ancestor url found")
100 eqStr(t, "company", inh.SourceName, "source is parent")
101 eqStr(t, "https://company.example", string(inh.Value), "inherited value")
102}
103
104// Multiple record updates are done by calling the typed setters repeatedly
105// (from a client, via a single `gnokey maketx run` that calls a helper N times);
106// GNS does not need an in-realm batch entry point.
107func TestSetTTLAndMultipleRecords(cur realm, t *testing.T) {
108 reset()
109 doRegister(cur, "alice", alice, 100000)
110
111 testing.SetRealm(testing.NewUserRealm(alice))
112 SetText(cross(cur), "alice", "email", "[email protected]")
113 testing.SetRealm(testing.NewUserRealm(alice))
114 SetText(cross(cur), "alice", "url", "https://x.example")
115 testing.SetRealm(testing.NewUserRealm(alice))
116 SetTTL(cross(cur), "alice", 3600)
117
118 v, ok := Text("alice", "email")
119 isTrue(t, ok, "email set")
120 eqStr(t, "[email protected]", v, "email value")
121 v, ok = Text("alice", "url")
122 isTrue(t, ok, "url set")
123 eqStr(t, "https://x.example", v, "url value")
124
125 n := getRaw("alice")
126 eqInt(t, 3600, int64(n.TTL), "ttl set")
127}
128
129func TestReservedNamespaceRejectedPure(t *testing.T) {
130 reset()
131 // the reserved-namespace guard is a pure lookup used by SetRecord.
132 isTrue(t, reservedNamespaces["gno"], "gno reserved")
133 isTrue(t, reservedNamespaces["system"], "system reserved")
134 isFalse(t, reservedNamespaces["com.example"], "app namespace allowed")
135}