subnames_test.gno
5.28 Kb · 151 lines
1package gns
2
3import (
4 "testing"
5)
6
7// setPolicy is a small helper: parent owner sets a registration policy.
8func setPolicy(cur realm, parent string, owner address, mode string) {
9 testing.SetRealm(testing.NewUserRealm(owner))
10 SetRegistrationPolicy(cross(cur), parent, RegistrationPolicy{Mode: mode})
11}
12
13func TestSubnameOpen(cur realm, t *testing.T) {
14 reset()
15 doRegister(cur, "company", alice, 100000)
16 setPolicy(cur, "company", alice, ModeOpen)
17
18 // anyone (bob) can claim an open subname
19 testing.SetRealm(testing.NewUserRealm(bob))
20 CreateSubname(cross(cur), "company", "bob", bob, SubnameOptions{Duration: 100000})
21
22 owner, ok := OwnerOf("bob.company")
23 isTrue(t, ok, "subname exists")
24 eqStr(t, bob.String(), owner, "subname owner is bob")
25
26 n := getRaw("bob.company")
27 eqStr(t, "company", n.Parent, "parent set")
28 eqInt(t, 2, int64(n.Depth), "depth 2")
29}
30
31func TestSubnameOwnerMode(cur realm, t *testing.T) {
32 reset()
33 doRegister(cur, "company", alice, 100000)
34 setPolicy(cur, "company", alice, ModeOwner)
35
36 // parent owner can create
37 testing.SetRealm(testing.NewUserRealm(alice))
38 CreateSubname(cross(cur), "company", "team", carol, SubnameOptions{Duration: 100000})
39 owner, ok := OwnerOf("team.company")
40 isTrue(t, ok, "owner-mode subname created by parent owner")
41 eqStr(t, carol.String(), owner, "assigned owner carol")
42
43 // authorization for a non-owner is rejected at the gate (pure check on the
44 // parent's ManageSubnames permission).
45 p := getRaw("company")
46 errIs(t, authorize(bob, p, PermManageSubnames), errUnauthorized, "bob cannot manage company subnames")
47}
48
49func TestSubnameClosedByDefault(cur realm, t *testing.T) {
50 reset()
51 doRegister(cur, "company", alice, 100000)
52 // default policy after registration is Closed
53 p := getRaw("company")
54 eqStr(t, ModeClosed, p.RegistrationPolicy.Mode, "default closed")
55}
56
57func TestParentGenerationInvalidatesChild(cur realm, t *testing.T) {
58 reset()
59 doRegister(cur, "company", alice, 1000)
60 setPolicy(cur, "company", alice, ModeOpen)
61 testing.SetRealm(testing.NewUserRealm(bob))
62 CreateSubname(cross(cur), "company", "api", bob, SubnameOptions{Duration: 1000000})
63
64 isTrue(t, Exists("api.company"), "child exists initially")
65
66 // expire the parent and re-register it (new generation)
67 testing.SkipHeights(500) // beyond parent grace
68 doRegister(cur, "company", carol, 1000)
69
70 // invariant 16 / recycling: the old child must NOT silently survive under
71 // the recycled parent (ParentGeneration mismatch).
72 eqStr(t, string(StatusExpired), string(Status("api.company")), "orphaned child invalid")
73 isFalse(t, Exists("api.company"), "recycled-parent child not resurrected")
74}
75
76func TestEmancipationRestrictOnly(t *testing.T) {
77 reset()
78 // invariant 5: a permanent policy can only become more restrictive.
79 base := ControlPolicy{
80 OwnerCanTransfer: true,
81 OwnerCanCreateSubnames: true,
82 RecordsMutable: true,
83 ParentCanReclaim: true,
84 ParentCanTransfer: true,
85 }
86 // try to RELAX ParentCanReclaim false->... and turn things on
87 req := ControlPolicy{
88 OwnerCanTransfer: true,
89 OwnerCanCreateSubnames: true,
90 RecordsMutable: true,
91 ParentCanReclaim: false, // restrict (allowed)
92 ParentCanTransfer: true,
93 Permanent: true,
94 }
95 got := mergeRestrictive(base, req)
96 isFalse(t, got.ParentCanReclaim, "reclaim restricted true->false")
97 isTrue(t, got.OwnerCanTransfer, "transfer kept true")
98 isTrue(t, got.Permanent, "permanent turned on")
99
100 // now, once permanent, attempting to RE-ENABLE reclaim must not work
101 relax := ControlPolicy{
102 OwnerCanTransfer: true,
103 OwnerCanCreateSubnames: true,
104 RecordsMutable: true,
105 ParentCanReclaim: true, // attempt to relax false->true
106 ParentCanTransfer: true,
107 Permanent: true,
108 }
109 got2 := mergeRestrictive(got, relax)
110 isFalse(t, got2.ParentCanReclaim, "cannot relax false->true (invariant 5)")
111}
112
113func TestLockPolicyEmancipatesChild(cur realm, t *testing.T) {
114 reset()
115 doRegister(cur, "company", alice, 100000)
116 setPolicy(cur, "company", alice, ModeOpen)
117 testing.SetRealm(testing.NewUserRealm(bob))
118 CreateSubname(cross(cur), "company", "wallet", bob, SubnameOptions{
119 Duration: 100000,
120 ControlPolicy: ControlPolicy{OwnerCanTransfer: true, RecordsMutable: true, ParentCanTransfer: true},
121 })
122
123 // child owner locks out parent transfer power
124 testing.SetRealm(testing.NewUserRealm(bob))
125 LockPolicy(cross(cur), "wallet.company", ControlPolicy{
126 OwnerCanTransfer: true,
127 RecordsMutable: true,
128 ParentCanTransfer: false, // remove parent power
129 Permanent: true,
130 })
131
132 child := getRaw("wallet.company")
133 isFalse(t, child.ControlPolicy.ParentCanTransfer, "parent transfer removed")
134 isTrue(t, child.ControlPolicy.Permanent, "now permanent")
135
136 // invariant 4: parent can no longer transfer the child
137 errIs(t, authorize(alice, child, PermTransfer), errUnauthorized, "parent lost transfer power")
138}
139
140func TestDeleteSubname(cur realm, t *testing.T) {
141 reset()
142 doRegister(cur, "company", alice, 100000)
143 setPolicy(cur, "company", alice, ModeOpen)
144 testing.SetRealm(testing.NewUserRealm(bob))
145 CreateSubname(cross(cur), "company", "temp", bob, SubnameOptions{Duration: 100000})
146 isTrue(t, Exists("temp.company"), "subname created")
147
148 testing.SetRealm(testing.NewUserRealm(bob))
149 DeleteSubname(cross(cur), "temp.company")
150 isFalse(t, Exists("temp.company"), "subname deleted")
151}