Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

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}