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

pkg_test.gno

5.77 Kb · 165 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 TestValidPkgPath(t *testing.T) {
 11	cases := []struct {
 12		name string
 13		path string
 14		want bool
 15	}{
 16		{"a realm", "gno.land/r/moul/home", true},
 17		{"a pure package", "gno.land/p/moul/forge/v1", true},
 18		{"deep", "gno.land/r/moul/x/daily/asciiart/v0", true},
 19		{"an address namespace", "gno.land/r/g1abc/thing", true},
 20		{"underscores and dashes", "gno.land/r/ns/a-b_c", true},
 21		// Shape only. A realm cannot ask the chain whether a path is deployed,
 22		// so anything stricter would be a check that only sometimes works.
 23		{"not deployed but well formed", "gno.land/r/nobody/nothing", true},
 24		{"empty", "", false},
 25		{"two parts", "gno.land/r", false},
 26		{"a traversal", "gno.land/r/../etc", false},
 27		{"trailing slash", "gno.land/r/moul/home/", false},
 28		{"an empty element", "gno.land//r/moul", false},
 29		{"a space", "gno.land/r/moul/my home", false},
 30		{"a colon", "gno.land/r/moul/home:tab", false},
 31	}
 32	for _, tc := range cases {
 33		t.Run(tc.name, func(t *testing.T) {
 34			uassert.Equal(t, tc.want, ValidPkgPath(tc.path))
 35		})
 36	}
 37}
 38
 39func TestPublishPackageIndexesForgeWide(t *testing.T) {
 40	f, r := newRepo(t)
 41
 42	p, err := f.PublishPackage(carol, 200, r.ID, "gno.land/r/moul/home", "refs/heads/main", oid("a"), "")
 43	urequire.NoError(t, err)
 44	uassert.Equal(t, "gno.land/r/moul/home", p.Path)
 45	uassert.Equal(t, r.ID, p.RepoID)
 46	uassert.Equal(t, int64(200), p.PublishedAt)
 47
 48	// The lookup an explorer makes: it starts from the path and does not know
 49	// the repo yet, which is the whole reason the index is forge-wide.
 50	uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
 51	uassert.Equal(t, "", f.PackageRepo("gno.land/r/someone/else"))
 52	uassert.Equal(t, 1, f.PackageCount())
 53	uassert.Equal(t, 1, r.PackageCount())
 54}
 55
 56// One repo publishes many paths: gno-contracts publishes 193.
 57func TestPublishManyPackages(t *testing.T) {
 58	f, r := newRepo(t)
 59
 60	paths := []string{
 61		"gno.land/r/moul/home",
 62		"gno.land/p/moul/forge/v1",
 63		"gno.land/r/moul/blog",
 64	}
 65	for _, path := range paths {
 66		_, err := f.PublishPackage(alice, 200, r.ID, path, "", "", "")
 67		urequire.NoError(t, err)
 68	}
 69	uassert.Equal(t, 3, r.PackageCount())
 70
 71	var seen []string
 72	r.IteratePackages(0, 0, func(p *Package) bool {
 73		seen = append(seen, p.Path)
 74		return false
 75	})
 76	// Path order, which is what the tree gives and what a file list wants.
 77	urequire.Equal(t, 3, len(seen))
 78	uassert.Equal(t, "gno.land/p/moul/forge/v1", seen[0])
 79	uassert.Equal(t, "gno.land/r/moul/blog", seen[1])
 80	uassert.Equal(t, "gno.land/r/moul/home", seen[2])
 81}
 82
 83// Re-publishing the same path from the same repo is a redeploy, and overwrites.
 84func TestRepublishOverwrites(t *testing.T) {
 85	f, r := newRepo(t)
 86
 87	_, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", oid("a"), "v1.0.0")
 88	urequire.NoError(t, err)
 89	_, err = f.PublishPackage(alice, 300, r.ID, "gno.land/r/moul/home", "", oid("b"), "v1.1.0")
 90	urequire.NoError(t, err)
 91
 92	uassert.Equal(t, 1, f.PackageCount())
 93	got := f.PackageAt("gno.land/r/moul/home")
 94	urequire.True(t, got != nil)
 95	uassert.Equal(t, oid("b"), got.OID)
 96	uassert.Equal(t, "v1.1.0", got.Tag)
 97	uassert.Equal(t, int64(300), got.PublishedAt)
 98}
 99
100// Silently moving a claimed path would let any repo owner capture another
101// project's package in every explorer that reads this index.
102func TestPublishRefusesAnotherReposPath(t *testing.T) {
103	f, r := newRepo(t)
104	_, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
105	urequire.NoError(t, err)
106
107	other, err := f.CreateRepo(eve, 210, "eve/squat", "", "")
108	urequire.NoError(t, err)
109
110	_, err = f.PublishPackage(eve, 220, other.ID, "gno.land/r/moul/home", "", "", "")
111	uassert.ErrorIs(t, err, ErrPackageClaimed)
112	uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
113}
114
115func TestPublishAuthorityAndValidation(t *testing.T) {
116	f, r := newRepo(t)
117
118	// dave is a reader, eve is nothing: neither may publish.
119	_, err := f.PublishPackage(dave, 200, r.ID, "gno.land/r/moul/home", "", "", "")
120	uassert.ErrorIs(t, err, ErrUnauthorized)
121	_, err = f.PublishPackage(eve, 200, r.ID, "gno.land/r/moul/home", "", "", "")
122	uassert.ErrorIs(t, err, ErrUnauthorized)
123
124	_, err = f.PublishPackage(alice, 200, "nobody/nothing", "gno.land/r/x/y", "", "", "")
125	uassert.ErrorIs(t, err, ErrRepoNotFound)
126
127	_, err = f.PublishPackage(alice, 200, r.ID, "not a path", "", "", "")
128	uassert.ErrorIs(t, err, ErrInvalidPkgPath)
129
130	_, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "main", "", "")
131	uassert.ErrorIs(t, err, ErrInvalidRefName)
132
133	_, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "nothex", "")
134	uassert.ErrorIs(t, err, ErrInvalidOID)
135
136	urequire.NoError(t, r.SetArchived(alice, true))
137	_, err = f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
138	uassert.ErrorIs(t, err, ErrRepoArchived)
139}
140
141func TestUnpublishClearsBothHalvesOfTheIndex(t *testing.T) {
142	f, r := newRepo(t)
143	_, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
144	urequire.NoError(t, err)
145
146	uassert.ErrorIs(t, f.UnpublishPackage(dave, r.ID, "gno.land/r/moul/home"), ErrUnauthorized)
147	uassert.ErrorIs(t, f.UnpublishPackage(alice, r.ID, "gno.land/r/nothing"), ErrPackageNotFound)
148
149	urequire.NoError(t, f.UnpublishPackage(alice, r.ID, "gno.land/r/moul/home"))
150	uassert.Equal(t, 0, f.PackageCount())
151	uassert.Equal(t, 0, r.PackageCount())
152	uassert.Equal(t, "", f.PackageRepo("gno.land/r/moul/home"))
153}
154
155// A fork is not a publisher of its parent's paths.
156func TestForkInheritsNoPackages(t *testing.T) {
157	f, r := newRepo(t)
158	_, err := f.PublishPackage(alice, 200, r.ID, "gno.land/r/moul/home", "", "", "")
159	urequire.NoError(t, err)
160
161	child, err := f.Fork(eve, 210, r.ID, "eve/forge")
162	urequire.NoError(t, err)
163	uassert.Equal(t, 0, child.PackageCount())
164	uassert.Equal(t, r.ID, f.PackageRepo("gno.land/r/moul/home"))
165}