registry_test.gno
5.22 Kb · 129 lines
1package registry
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/uassert/v0"
8)
9
10func TestRegisterAndWithdraw(cur realm, t *testing.T) {
11 reset()
12 testing.SetRealm(testing.NewUserRealm(alice))
13 Register(cross(cur), otherPkg, repoURL, sha1Zero, "p/moul/md", "refs/heads/main")
14
15 uassert.Equal(t, 1, PackageCount())
16 uassert.Equal(t, 1, ClaimCount())
17 uassert.True(t, HasClaims(otherPkg))
18 uassert.False(t, HasClaims("gno.land/p/moul/nope/v0"))
19
20 testing.SetRealm(testing.NewUserRealm(alice))
21 Withdraw(cross(cur), otherPkg)
22 uassert.Equal(t, 0, PackageCount())
23 uassert.False(t, HasClaims(otherPkg))
24}
25
26// A claim is the claimant's own. Nobody else may take it back, and the refusal
27// has to abort rather than silently do nothing: a Withdraw that quietly did
28// nothing reads to the caller exactly like one that worked.
29func TestWithdrawIsNotTransferable(cur realm, t *testing.T) {
30 reset()
31 testing.SetRealm(testing.NewUserRealm(alice))
32 Register(cross(cur), otherPkg, repoURL, sha1Zero, "", "")
33
34 testing.SetRealm(testing.NewUserRealm(bob))
35 uassert.AbortsContains(t, cur, "no such claim", func() {
36 Withdraw(cross(cur), otherPkg)
37 })
38 uassert.True(t, HasClaims(otherPkg), "alice's claim survived bob")
39}
40
41func TestRegisterAborts(cur realm, t *testing.T) {
42 reset()
43 cases := []struct {
44 name string
45 pkgPath, repo, commit, dir, ref string
46 contains string
47 }{
48 {"bad path", "nonsense", repoURL, sha1Zero, "", "", "invalid package path"},
49 {"non-https repo", otherPkg, "javascript:alert(1)", sha1Zero, "", "", "invalid repository URL"},
50 {"abbreviated commit", otherPkg, repoURL, "0123456", "", "", "invalid commit id"},
51 {"absolute dir", otherPkg, repoURL, sha1Zero, "/etc", "", "invalid directory"},
52 {"unqualified ref", otherPkg, repoURL, sha1Zero, "", "main", "invalid ref name"},
53 }
54 for _, tc := range cases {
55 testing.SetRealm(testing.NewUserRealm(alice))
56 uassert.AbortsContains(t, cur, tc.contains, func() {
57 Register(cross(cur), tc.pkgPath, tc.repo, tc.commit, tc.dir, tc.ref)
58 }, tc.name)
59 }
60 uassert.Equal(t, 0, ClaimCount(), "nothing was stored")
61}
62
63// OwnerClaim is the only read that filters, and it filters on the one thing
64// about a claim the chain can prove. An address namespace belongs to that
65// account with nothing registered anywhere, so it is testable without
66// r/sys/users, which a test cannot write to.
67func TestOwnerClaim(cur realm, t *testing.T) {
68 reset()
69
70 testing.SetRealm(testing.NewUserRealm(bob))
71 Register(cross(cur), alicePkg, "https://github.com/bob/impostor", sha1One, "", "")
72 _, _, _, ok := OwnerClaim(alicePkg)
73 uassert.False(t, ok, "a stranger's claim is not the owner's")
74
75 testing.SetRealm(testing.NewUserRealm(alice))
76 Register(cross(cur), alicePkg, repoURL, sha1Zero, "scratch", "")
77 repo, commit, dir, ok := OwnerClaim(alicePkg)
78 uassert.True(t, ok, "the namespace holder's claim is found")
79 uassert.Equal(t, repoURL, repo)
80 uassert.Equal(t, sha1Zero, commit)
81 uassert.Equal(t, "scratch", dir)
82
83 _, _, _, ok = OwnerClaim("gno.land/p/moul/nothing/v0")
84 uassert.False(t, ok, "an unclaimed path has no owner claim")
85}
86
87// Re-registering moves the caller's own claim and creates no second one.
88func TestReregister(cur realm, t *testing.T) {
89 reset()
90 testing.SetRealm(testing.NewUserRealm(alice))
91 Register(cross(cur), otherPkg, repoURL, sha1Zero, "p/moul/md", "")
92 testing.SkipHeights(10)
93 testing.SetRealm(testing.NewUserRealm(alice))
94 Register(cross(cur), otherPkg, repoURL, sha1One, "p/moul/md", "refs/tags/v1")
95
96 uassert.Equal(t, 1, ClaimCount())
97 got := Render(otherPkg)
98 uassert.True(t, strings.Contains(got, sha1One[:12]), "the new commit renders")
99 uassert.False(t, strings.Contains(got, sha1Zero[:12]), "the old one is gone")
100 uassert.True(t, strings.Contains(got, "| last updated | block"), "an updated claim says when")
101}
102
103// A package path arrives at Render already split on "/", so the routing is the
104// rejoin. Anything that does not reassemble into a path is a miss, and a miss
105// must not render as an empty package page.
106func TestRenderRouting(t *testing.T) {
107 reset()
108 uassert.True(t, strings.Contains(Render("nonsense"), "Not found"), "one bad element")
109 uassert.True(t, strings.Contains(Render("a/b/c"), "Not found"), "too few elements")
110 uassert.True(t, strings.Contains(Render("help"), "How this registry works"), "help page")
111 uassert.True(t, strings.Contains(Render(""), "gnopm source registry"), "home")
112 uassert.True(t, strings.Contains(Render(otherPkg), "Nobody has claimed"), "valid but unclaimed")
113}
114
115// The page ranks the owner's claim above a stranger's and says which is which.
116// Rendering them identically is the whole mistake this realm exists to avoid,
117// so the separation is pinned rather than left to review.
118func TestRenderSeparatesOwnerFromStranger(t *testing.T) {
119 seedFixture()
120
121 got := Render(alicePkg)
122 iOwner := strings.Index(got, "Claimed by the namespace owner")
123 iOthers := strings.Index(got, "Claimed by others")
124 uassert.True(t, iOwner >= 0, "the owner section exists")
125 uassert.True(t, iOthers >= 0, "the others section exists")
126 uassert.True(t, iOwner < iOthers, "the owner is ranked first")
127 uassert.True(t, strings.Contains(got, "impostor"), "a stranger's claim is shown, not hidden")
128 uassert.True(t, strings.Contains(got, "do not own"), "and is labelled as not the owner's")
129}