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

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}