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

forge_test.gno

5.29 Kb · 160 lines
  1package forge
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nt/uassert/v0"
  7	"gno.land/p/nt/urequire/v0"
  8)
  9
 10func TestCreateRepo(t *testing.T) {
 11	f := New()
 12
 13	r, err := f.CreateRepo(alice, 42, "moul/forge", "desc", "")
 14	urequire.NoError(t, err)
 15	uassert.Equal(t, "refs/heads/main", r.DefaultRef, "default ref defaults")
 16	uassert.Equal(t, int64(42), r.CreatedAt)
 17	uassert.Equal(t, "owner", r.RoleOf(alice).String())
 18	uassert.Equal(t, 1, f.Size())
 19
 20	_, err = f.CreateRepo(bob, 43, "moul/forge", "", "")
 21	uassert.ErrorIs(t, err, ErrRepoExists)
 22
 23	_, err = f.CreateRepo(bob, 43, "Moul/Forge", "", "")
 24	uassert.ErrorIs(t, err, ErrInvalidRepoID)
 25
 26	_, err = f.CreateRepo(bob, 43, "moul/other", "", "main")
 27	uassert.ErrorIs(t, err, ErrInvalidRefName)
 28
 29	uassert.True(t, f.Repo("moul/nope") == nil, "missing repo is nil")
 30	uassert.True(t, f.HasRepo("moul/forge"))
 31}
 32
 33func TestMembership(t *testing.T) {
 34	_, r := newRepo(t)
 35
 36	uassert.True(t, r.Can(bob, RoleWriter), "maintainer covers writer")
 37	uassert.False(t, r.Can(carol, RoleMaintainer))
 38	uassert.Equal(t, "none", r.RoleOf(eve).String())
 39	uassert.Equal(t, 4, r.MemberCount())
 40
 41	// A writer cannot hand out roles.
 42	uassert.ErrorIs(t, r.SetMember(carol, eve, RoleWriter), ErrUnauthorized)
 43
 44	// An admin can promote up to admin, but cannot mint an owner...
 45	urequire.NoError(t, r.SetMember(alice, bob, RoleAdmin))
 46	uassert.ErrorIs(t, r.SetMember(bob, eve, RoleOwner), ErrUnauthorized)
 47	// ...nor demote one.
 48	uassert.ErrorIs(t, r.SetMember(bob, alice, RoleReader), ErrUnauthorized)
 49
 50	// The last owner cannot demote themselves: a repo with no owner is a repo
 51	// nobody can ever administer again.
 52	uassert.ErrorIs(t, r.SetMember(alice, alice, RoleReader), ErrLastOwner)
 53	urequire.NoError(t, r.SetMember(alice, bob, RoleOwner))
 54	urequire.NoError(t, r.SetMember(alice, alice, RoleReader))
 55	uassert.Equal(t, "reader", r.RoleOf(alice).String())
 56
 57	// Revoking removes the member outright.
 58	urequire.NoError(t, r.SetMember(bob, dave, RoleNone))
 59	uassert.Equal(t, "none", r.RoleOf(dave).String())
 60	uassert.Equal(t, 3, r.MemberCount())
 61
 62	uassert.ErrorIs(t, r.SetMember(bob, eve, Role(99)), ErrInvalidRole)
 63}
 64
 65func TestRepoSettings(t *testing.T) {
 66	_, r := newRepo(t)
 67
 68	uassert.ErrorIs(t, r.SetDescription(carol, "nope"), ErrUnauthorized)
 69	urequire.NoError(t, r.SetDescription(alice, "an on-chain forge for gno"))
 70	uassert.Equal(t, "an on-chain forge for gno", r.Description)
 71
 72	uassert.ErrorIs(t, r.SetMirrors(carol, []string{"https://example.com/x.git"}), ErrUnauthorized)
 73	uassert.ErrorIs(t, r.SetMirrors(bob, []string{"nope"}), ErrInvalidMirror)
 74	urequire.NoError(t, r.SetMirrors(bob, []string{"https://github.com/moul/gno-contracts.git"}))
 75	uassert.Equal(t, 1, len(r.Mirrors))
 76
 77	uassert.ErrorIs(t, r.SetPolicy(carol, 2, false), ErrUnauthorized)
 78	uassert.ErrorIs(t, r.SetPolicy(alice, 99, false), ErrTooMany)
 79	urequire.NoError(t, r.SetPolicy(alice, 2, true))
 80	uassert.Equal(t, 2, r.RequiredApprovals)
 81	uassert.True(t, r.AllowSelfApproval)
 82
 83	urequire.NoError(t, r.SetDefaultRef(bob, "refs/heads/trunk"))
 84	uassert.Equal(t, "refs/heads/trunk", r.DefaultRef)
 85
 86	// An archived repo takes no writes at all.
 87	urequire.NoError(t, r.SetArchived(alice, true))
 88	_, err := r.SetRef(alice, 101, "refs/heads/trunk", "", oid("a"), "")
 89	uassert.ErrorIs(t, err, ErrRepoArchived)
 90	_, err = r.OpenIssue(eve, 101, "hello", "", nil)
 91	uassert.ErrorIs(t, err, ErrRepoArchived)
 92	urequire.NoError(t, r.SetArchived(alice, false))
 93}
 94
 95func TestForkSnapshotsRefs(t *testing.T) {
 96	f, r := newRepo(t)
 97	urequire.NoError(t, r.SetMirrors(alice, []string{"https://github.com/moul/gno-contracts.git"}))
 98	_, err := r.SetRef(alice, 101, "refs/heads/main", "", oid("a"), "initial")
 99	urequire.NoError(t, err)
100	_, err = r.SetRef(alice, 102, "refs/tags/v0.1.0", "", oid("b"), "tag")
101	urequire.NoError(t, err)
102
103	child, err := f.Fork(eve, 110, "moul/forge", "eve/forge")
104	urequire.NoError(t, err)
105	uassert.Equal(t, "moul/forge", child.ParentID)
106	uassert.Equal(t, "owner", child.RoleOf(eve).String(), "the forker owns the fork")
107	uassert.Equal(t, 2, child.RefCount(), "refs are snapshotted")
108	uassert.Equal(t, 2, child.LogSize(), "and the snapshot is in the log")
109	uassert.Equal(t, oid("a"), child.Ref("refs/heads/main").OID)
110	uassert.Equal(t, 1, len(child.Mirrors), "the fork inherits where to fetch objects")
111
112	ok, bad := child.VerifyLog()
113	uassert.True(t, ok, "fork log is a valid chain")
114	uassert.Equal(t, int64(-1), bad)
115
116	_, err = f.Fork(eve, 111, "moul/nope", "eve/nope")
117	uassert.ErrorIs(t, err, ErrRepoNotFound)
118	_, err = f.Fork(eve, 111, "moul/forge", "eve/forge")
119	uassert.ErrorIs(t, err, ErrRepoExists)
120}
121
122func TestIterateReposAndNamespace(t *testing.T) {
123	f := New()
124	for _, id := range []string{"alice/one", "alice/two", "bob/three"} {
125		_, err := f.CreateRepo(alice, 1, id, "", "")
126		urequire.NoError(t, err)
127	}
128
129	var all []string
130	f.IterateRepos(0, 0, func(r *Repo) bool {
131		all = append(all, r.ID)
132		return false
133	})
134	uassert.Equal(t, "alice/one,alice/two,bob/three", join(all))
135
136	var ns []string
137	f.IterateNamespace("alice", func(r *Repo) bool {
138		ns = append(ns, r.ID)
139		return false
140	})
141	uassert.Equal(t, "alice/one,alice/two", join(ns))
142
143	var page []string
144	f.IterateRepos(1, 1, func(r *Repo) bool {
145		page = append(page, r.ID)
146		return false
147	})
148	uassert.Equal(t, "alice/two", join(page))
149}
150
151func join(ss []string) string {
152	out := ""
153	for i, s := range ss {
154		if i > 0 {
155			out += ","
156		}
157		out += s
158	}
159	return out
160}