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}