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.

gns_test.gno

2.92 Kb · 97 lines
 1package gns
 2
 3import (
 4	"testing"
 5)
 6
 7func TestNormalize(t *testing.T) {
 8	reset()
 9
10	cases := []struct {
11		in  string
12		out string
13		ok  bool
14	}{
15		{"alice", "alice", true},
16		{"ALICE", "alice", true},
17		{"Wallet.Alice", "wallet.alice", true},
18		{"a", "a", true},
19		{"a1-b", "a1-b", true},
20		{"-alice", "", false}, // leading hyphen
21		{"alice-", "", false}, // trailing hyphen
22		{"", "", false},       // empty
23		{"a..b", "", false},   // empty label (double dot)
24		{"al ice", "", false}, // space
25		{"café", "", false},   // non-ASCII
26		{"a_b", "", false},    // underscore not allowed
27	}
28	for _, tc := range cases {
29		got, err := Normalize(tc.in)
30		if tc.ok {
31			noErr(t, err, "normalize "+tc.in)
32			eqStr(t, tc.out, got, "normalize "+tc.in)
33		} else {
34			isErr(t, err, "expected error for "+tc.in)
35		}
36	}
37}
38
39func TestNormalizeDepthAndLength(t *testing.T) {
40	reset()
41
42	deep := "a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a" // 17 labels > maxDepth
43	_, err := Normalize(deep)
44	isErr(t, err, "excessive depth rejected")
45
46	long := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" // 64 > 63
47	_, err = Normalize(long)
48	isErr(t, err, "excessive label length rejected")
49}
50
51func TestStatusAndOwnerLifecycle(cur realm, t *testing.T) {
52	reset()
53
54	eqStr(t, string(StatusAvailable), string(Status("alice")), "initial status")
55	isFalse(t, Exists("alice"), "not exists initially")
56
57	doRegister(cur, "alice", alice, 1000)
58
59	eqStr(t, string(StatusActive), string(Status("alice")), "post-register status")
60	isTrue(t, Exists("alice"), "exists after register")
61
62	owner, ok := OwnerOf("alice")
63	isTrue(t, ok, "ownerOf ok")
64	eqStr(t, alice.String(), owner, "owner is alice")
65
66	view, ok := GetName("alice")
67	isTrue(t, ok, "getName ok")
68	eqInt(t, 1, int64(view.Generation), "generation 1")
69	eqStr(t, "alice", view.Canonical, "canonical")
70
71	// advance past expiry, into grace (expiry ≈ +1000s, grace ends ≈ +1100s)
72	testing.SkipHeights(210) // +1050s
73	eqStr(t, string(StatusGrace), string(Status("alice")), "grace status")
74	_, ok = OwnerOf("alice")
75	isTrue(t, ok, "owner known during grace")
76
77	// advance well past grace -> Expired
78	testing.SkipHeights(200) // +1000s more, far beyond grace end
79	eqStr(t, string(StatusExpired), string(Status("alice")), "expired status")
80	isFalse(t, Exists("alice"), "not exists after grace")
81}
82
83func TestExpiredOwnerLosesAuthority(cur realm, t *testing.T) {
84	reset()
85	doRegister(cur, "alice", alice, 1000)
86
87	testing.SkipHeights(300) // beyond grace
88	eqStr(t, string(StatusExpired), string(Status("alice")), "expired")
89
90	// Invariant 2: an expired name grants no owner mutation authority. Tested
91	// against the single authorization gate directly (mutations funnel through
92	// it, then panic on the returned error).
93	n := getRaw("alice")
94	isTrue(t, n != nil, "raw name present")
95	errIs(t, authorize(alice, n, PermManageRecords), errUnauthorized, "expired owner authorize")
96	errIs(t, authorize(alice, n, PermTransfer), errUnauthorized, "expired owner transfer")
97}