PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/moul/gnopm/registry/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / gnopm / registry
Files
7 (README)(gnomod.toml)
Exported functions
7
Module
gno.land/r/moul/gnopm/registry/v0
gno
0.9

Files (7)

  • README.mdmarkdown
  • gnomod.tomltoml
  • registry.gnogno
  • render.gnogno
  • helpers_test.gnogno
  • registry_test.gnogno
  • render_test.gnogno
registry_test.gnogno
1package registry23import (4	"strings"5	"testing"67	"gno.land/p/nt/uassert/v0"8

Functions

  • ClaimCount() int

  • HasClaims(pkgPath string) bool

  • OwnerClaim(pkgPath string) (repo string, commit string, dir string, ok bool)

  • PackageCount() int

  • Register(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pkgPath string, repo string, commit string, dir string, ref string)

  • Render(path string) string

  • Withdraw(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pkgPath string)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗
)
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}
130

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.