Skip to content

Commit

Permalink
govdao executors, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
leohhhn committed Feb 12, 2025
1 parent f50a9d6 commit f662b84
Show file tree
Hide file tree
Showing 6 changed files with 540 additions and 101 deletions.
39 changes: 39 additions & 0 deletions examples/gno.land/r/gnoland/users/v1/admin.gno
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package v1

import (
"std"

"gno.land/p/demo/dao"

"gno.land/r/gov/dao/bridge"
susers "gno.land/r/sys/users"
)

var paused = false // until a DAO can be owner of ownable/pausable
Expand All @@ -17,3 +20,39 @@ func NewSetPausedExecutor(newPausedValue bool) dao.Executor {

return bridge.GovDAO().NewGovDAOExecutor(cb)
}

// ProposeNewName allows GovDAO to propose a new name for an existing user
// The associated address and all previous names of a user that changes a name
// are preserved, and all resolve to the new name.
func ProposeNewName(addr std.Address, newName string) dao.Executor {
cb := func() error {
if matched := reUsername.MatchString(newName); !matched {
return ErrInvalidUsername
}

userData := susers.ResolveAddress(addr)
if err := userData.UpdateName(newName); err != nil {
return err
}

return nil
}

return bridge.GovDAO().NewGovDAOExecutor(cb)
}

// ProposeDeleteUser allows GovDAO to propose propose deletion of a user
// This will make the associated address and names unresolvable.
// WARN: After deletion, the same address WILL NOT be able to register a new name.
func ProposeDeleteUser(addr std.Address) dao.Executor {
cb := func() error {
userData := susers.ResolveAddress(addr)
if err := userData.Delete(); err != nil {
return err
}

return nil
}

return bridge.GovDAO().NewGovDAOExecutor(cb)
}
7 changes: 2 additions & 5 deletions examples/gno.land/r/gnoland/users/v1/render.gno
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,9 @@ will gain permission to deploy packages and realms to package paths with the pat

if !paused {
out += md.H2("Actions\n\n")
items = []string{
"Register: " + ufmt.Sprintf(" [[Connect]](%s) - [[gnokey]](%s)\n\n", connectRegisterUrl, txlink.Call("Register")),
"Update Name: " + ufmt.Sprintf(" [[Connect]](%s) - [[gnokey]](%s)\n\n", connectUpdateNameUrl, txlink.Call("UpdateName")),
}
out += md.BulletList(items)
out += "Register: " + ufmt.Sprintf(" [[Connect]](%s) - [[gnokey]](%s)\n\n", connectRegisterUrl, txlink.Call("Register"))
}

out += md.HorizontalRule()
out += "\n\n"

Expand Down
43 changes: 2 additions & 41 deletions examples/gno.land/r/gnoland/users/v1/users.gno
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"regexp"
"std"

"gno.land/r/sys/users"
susers "gno.land/r/sys/users"
)

const (
Expand All @@ -30,46 +30,7 @@ func Register(username string) error {
}

registrant := std.PrevRealm().Addr()
if err := users.RegisterUser(username, registrant); err != nil {
return err
}

return nil
}

// UpdateName allows a user to update their name.
// The associated address and all previous names of a user that changes a name
// are preserved, and all resolve to the new name.
func UpdateName(newName string) error {
std.AssertOriginCall()

if paused {
return ErrPaused
}

if matched := reUsername.MatchString(newName); !matched {
return ErrInvalidUsername
}

userData := users.ResolveAddress(std.PrevRealm().Addr())
if err := userData.UpdateName(newName); err != nil {
return err
}

return nil
}

// DeleteUser makes all names associated with the `PrevRealm()` address unresolvable.
// WARN: After deletion, the same address WILL NOT be able to register a new name.
func DeleteUser() error {
std.AssertOriginCall()

if paused {
return ErrPaused
}

userData := users.ResolveAddress(std.PrevRealm().Addr())
if err := userData.Delete(); err != nil {
if err := susers.RegisterUser(username, registrant); err != nil {
return err
}

Expand Down
58 changes: 3 additions & 55 deletions examples/gno.land/r/gnoland/users/v1/users_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"gno.land/p/demo/uassert"
"gno.land/p/demo/urequire"

"gno.land/r/sys/users"
susers "gno.land/r/sys/users"
)

var (
Expand All @@ -23,7 +23,7 @@ func TestRegister_Valid(t *testing.T) {
std.TestSetOrigCaller(aliceAddr)

uassert.NoError(t, Register(alice))
res, latest := users.ResolveName(alice)
res, latest := susers.ResolveName(alice)

uassert.NotEqual(t, nil, res)
uassert.Equal(t, alice, res.Name())
Expand All @@ -48,57 +48,5 @@ func TestRegister_Invalid(t *testing.T) {

// Name taken
urequire.NoError(t, Register(bob))
uassert.Error(t, Register(bob), users.ErrNameTaken.Error())
}

func TestUpdateName_Valid(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(aliceAddr))
std.TestSetOrigCaller(aliceAddr)

newalice := "newalice123"
// resolve old name
urequire.NoError(t, UpdateName(newalice))

res, latest := users.ResolveName(alice)
uassert.NotEqual(t, nil, res)
uassert.Equal(t, newalice, res.Name())
uassert.Equal(t, aliceAddr, res.Addr())
uassert.False(t, res.IsDeleted())
uassert.False(t, latest)
}

func TestUpdateName_Invalid(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(aliceAddr))
std.TestSetOrigCaller(aliceAddr)

// Invalid names
uassert.Error(t, UpdateName("alice"), ErrInvalidUsername.Error()) // vanity
uassert.Error(t, UpdateName(""), ErrInvalidUsername.Error()) // empty
uassert.Error(t, UpdateName(" "), ErrInvalidUsername.Error()) // empty
uassert.Error(t, UpdateName("123"), ErrInvalidUsername.Error()) // only numbers
uassert.Error(t, UpdateName("alice&#($)"), ErrInvalidUsername.Error()) // non-allowed chars
uassert.Error(t, UpdateName("Alice123"), ErrInvalidUsername.Error()) // upper-case
uassert.Error(t, UpdateName("toolongusernametoolongusernametoolongusername123"),
ErrInvalidUsername.Error()) // too long

urequire.Error(t, UpdateName(bob), users.ErrNameTaken.Error())
}

func TestDeleteUser(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(aliceAddr))
std.TestSetOrigCaller(aliceAddr)

urequire.NoError(t, DeleteUser())
res, _ := users.ResolveName(alice)
uassert.Equal(t, nil, res)
res = users.ResolveAddress(aliceAddr)
uassert.Equal(t, nil, res)
}

func TestDeleteUser_Invalid(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(aliceAddr))
std.TestSetOrigCaller(aliceAddr)

// Already deleted user
urequire.Error(t, DeleteUser(), users.ErrUserNotExistOrDeleted.Error())
uassert.Error(t, Register(bob), susers.ErrNameTaken.Error())
}
Loading

0 comments on commit f662b84

Please sign in to comment.