227 lines
7.1 KiB
Go
227 lines
7.1 KiB
Go
package tutustest
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/tutus-one/tutus-chain/pkg/core/native/nativenames"
|
|
"github.com/tutus-one/tutus-chain/pkg/util"
|
|
"github.com/tutus-one/tutus-chain/pkg/vm/stackitem"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Standard role IDs matching role_registry.go and role_registry_domain.go
|
|
const (
|
|
// Basic roles
|
|
RoleAdmin uint64 = 1
|
|
RoleValidator uint64 = 2
|
|
RoleNotary uint64 = 3
|
|
RoleOracle uint64 = 4
|
|
RoleStateRoot uint64 = 5
|
|
RoleNeoFSInner uint64 = 6
|
|
RoleNeoFSOuter uint64 = 7
|
|
RoleP2PNotary uint64 = 8
|
|
|
|
// Government service roles
|
|
RoleEducator uint64 = 20
|
|
RoleHealthProvider uint64 = 21
|
|
RoleLifeCoach uint64 = 22
|
|
RoleTributeAdmin uint64 = 23
|
|
RoleOpusSupervisor uint64 = 24
|
|
RolePalamAuditor uint64 = 25
|
|
RolePalamJudge uint64 = 26
|
|
RoleBridgeOperator uint64 = 27
|
|
RoleInvestmentMgr uint64 = 28
|
|
RoleJudge uint64 = 29
|
|
|
|
// Domain committee roles (CRIT-002)
|
|
RoleCommitteeLegal uint64 = 100
|
|
RoleCommitteeHealth uint64 = 101
|
|
RoleCommitteeEducation uint64 = 102
|
|
RoleCommitteeEconomy uint64 = 103
|
|
RoleCommitteeIdentity uint64 = 104
|
|
RoleCommitteeGovernance uint64 = 105
|
|
)
|
|
|
|
// RoleHelper provides utilities for testing RoleRegistry operations.
|
|
type RoleHelper struct {
|
|
*Executor
|
|
t testing.TB
|
|
RoleReg *ContractInvoker
|
|
Designate *ContractInvoker
|
|
}
|
|
|
|
// NewRoleHelper creates a helper for testing role-based operations.
|
|
func NewRoleHelper(t testing.TB, e *Executor) *RoleHelper {
|
|
return &RoleHelper{
|
|
Executor: e,
|
|
t: t,
|
|
RoleReg: e.CommitteeInvoker(e.NativeHash(t, nativenames.RoleRegistry)),
|
|
Designate: e.CommitteeInvoker(e.NativeHash(t, nativenames.Designation)),
|
|
}
|
|
}
|
|
|
|
// GrantRole grants a role to an account (requires committee authority).
|
|
func (r *RoleHelper) GrantRole(account util.Uint160, roleID uint64) {
|
|
r.RoleReg.Invoke(r.t, true, "grantRole", account, roleID)
|
|
}
|
|
|
|
// RevokeRole revokes a role from an account (requires committee authority).
|
|
func (r *RoleHelper) RevokeRole(account util.Uint160, roleID uint64) {
|
|
r.RoleReg.Invoke(r.t, true, "revokeRole", account, roleID)
|
|
}
|
|
|
|
// HasRole checks if an account has a specific role.
|
|
func (r *RoleHelper) HasRole(account util.Uint160, roleID uint64) bool {
|
|
var hasRole bool
|
|
r.RoleReg.InvokeAndCheck(r.t, func(t testing.TB, stack []stackitem.Item) {
|
|
hasRole = stack[0].Value().(bool)
|
|
}, "hasRole", account, roleID)
|
|
return hasRole
|
|
}
|
|
|
|
// RequireRole asserts that an account has a specific role.
|
|
func (r *RoleHelper) RequireRole(account util.Uint160, roleID uint64) {
|
|
require.True(r.t, r.HasRole(account, roleID), "account should have role %d", roleID)
|
|
}
|
|
|
|
// RequireNoRole asserts that an account does not have a specific role.
|
|
func (r *RoleHelper) RequireNoRole(account util.Uint160, roleID uint64) {
|
|
require.False(r.t, r.HasRole(account, roleID), "account should not have role %d", roleID)
|
|
}
|
|
|
|
// GetRoleMembers returns all members with a specific role.
|
|
func (r *RoleHelper) GetRoleMembers(roleID uint64) []util.Uint160 {
|
|
var members []util.Uint160
|
|
r.RoleReg.InvokeAndCheck(r.t, func(t testing.TB, stack []stackitem.Item) {
|
|
arr, ok := stack[0].Value().([]stackitem.Item)
|
|
if !ok {
|
|
return
|
|
}
|
|
for _, item := range arr {
|
|
bs, err := item.TryBytes()
|
|
require.NoError(t, err)
|
|
members = append(members, util.Uint160(bs))
|
|
}
|
|
}, "getRoleMembers", roleID)
|
|
return members
|
|
}
|
|
|
|
// SetupEducator grants the Educator role to an account.
|
|
func (r *RoleHelper) SetupEducator(account util.Uint160) {
|
|
r.GrantRole(account, RoleEducator)
|
|
}
|
|
|
|
// SetupHealthProvider grants the HealthProvider role to an account.
|
|
func (r *RoleHelper) SetupHealthProvider(account util.Uint160) {
|
|
r.GrantRole(account, RoleHealthProvider)
|
|
}
|
|
|
|
// SetupJudge grants the Judge role to an account.
|
|
func (r *RoleHelper) SetupJudge(account util.Uint160) {
|
|
r.GrantRole(account, RoleJudge)
|
|
}
|
|
|
|
// SetupLifeCoach grants the LifeCoach role to an account.
|
|
func (r *RoleHelper) SetupLifeCoach(account util.Uint160) {
|
|
r.GrantRole(account, RoleLifeCoach)
|
|
}
|
|
|
|
// SetupTributeAdmin grants the TributeAdmin role to an account.
|
|
func (r *RoleHelper) SetupTributeAdmin(account util.Uint160) {
|
|
r.GrantRole(account, RoleTributeAdmin)
|
|
}
|
|
|
|
// SetupOpusSupervisor grants the OpusSupervisor role to an account.
|
|
func (r *RoleHelper) SetupOpusSupervisor(account util.Uint160) {
|
|
r.GrantRole(account, RoleOpusSupervisor)
|
|
}
|
|
|
|
// SetupPalamAuditor grants the PalamAuditor role to an account.
|
|
func (r *RoleHelper) SetupPalamAuditor(account util.Uint160) {
|
|
r.GrantRole(account, RolePalamAuditor)
|
|
}
|
|
|
|
// SetupPalamJudge grants the PalamJudge role to an account.
|
|
func (r *RoleHelper) SetupPalamJudge(account util.Uint160) {
|
|
r.GrantRole(account, RolePalamJudge)
|
|
}
|
|
|
|
// SetupBridgeOperator grants the BridgeOperator role to an account.
|
|
func (r *RoleHelper) SetupBridgeOperator(account util.Uint160) {
|
|
r.GrantRole(account, RoleBridgeOperator)
|
|
}
|
|
|
|
// SetupInvestmentManager grants the InvestmentManager role to an account.
|
|
func (r *RoleHelper) SetupInvestmentManager(account util.Uint160) {
|
|
r.GrantRole(account, RoleInvestmentMgr)
|
|
}
|
|
|
|
// SetupDomainCommittee grants a domain committee role to an account.
|
|
func (r *RoleHelper) SetupDomainCommittee(account util.Uint160, domain string) {
|
|
var roleID uint64
|
|
switch domain {
|
|
case "legal":
|
|
roleID = RoleCommitteeLegal
|
|
case "health":
|
|
roleID = RoleCommitteeHealth
|
|
case "education":
|
|
roleID = RoleCommitteeEducation
|
|
case "economy":
|
|
roleID = RoleCommitteeEconomy
|
|
case "identity":
|
|
roleID = RoleCommitteeIdentity
|
|
case "governance":
|
|
roleID = RoleCommitteeGovernance
|
|
default:
|
|
require.Fail(r.t, "unknown domain: %s", domain)
|
|
}
|
|
r.GrantRole(account, roleID)
|
|
}
|
|
|
|
// RoleScenario represents a test scenario with role assignments.
|
|
type RoleScenario struct {
|
|
helper *RoleHelper
|
|
accounts map[string]SingleSigner
|
|
roles map[string][]uint64
|
|
}
|
|
|
|
// NewRoleScenario creates a new role scenario builder.
|
|
func (r *RoleHelper) NewScenario() *RoleScenario {
|
|
return &RoleScenario{
|
|
helper: r,
|
|
accounts: make(map[string]SingleSigner),
|
|
roles: make(map[string][]uint64),
|
|
}
|
|
}
|
|
|
|
// WithAccount adds a named account to the scenario.
|
|
func (s *RoleScenario) WithAccount(name string, acc SingleSigner) *RoleScenario {
|
|
s.accounts[name] = acc
|
|
return s
|
|
}
|
|
|
|
// WithRole assigns a role to a named account.
|
|
func (s *RoleScenario) WithRole(accountName string, roleID uint64) *RoleScenario {
|
|
s.roles[accountName] = append(s.roles[accountName], roleID)
|
|
return s
|
|
}
|
|
|
|
// Setup executes all role assignments in the scenario.
|
|
func (s *RoleScenario) Setup() map[string]SingleSigner {
|
|
for name, roles := range s.roles {
|
|
acc, ok := s.accounts[name]
|
|
require.True(s.helper.t, ok, "account %s not found", name)
|
|
for _, roleID := range roles {
|
|
s.helper.GrantRole(acc.ScriptHash(), roleID)
|
|
}
|
|
}
|
|
return s.accounts
|
|
}
|
|
|
|
// Get returns a named account from the scenario.
|
|
func (s *RoleScenario) Get(name string) SingleSigner {
|
|
acc, ok := s.accounts[name]
|
|
require.True(s.helper.t, ok, "account %s not found", name)
|
|
return acc
|
|
}
|