feat: update event names for OZ standards and test them
This commit is contained in:
@ -11,14 +11,16 @@ import './Roles.sol';
|
|||||||
* See //contracts/examples/RBACExample.sol for an example of usage.
|
* See //contracts/examples/RBACExample.sol for an example of usage.
|
||||||
* This RBAC method uses strings to key roles. It may be beneficial
|
* This RBAC method uses strings to key roles. It may be beneficial
|
||||||
* for you to write your own implementation of this interface using Enums or similar.
|
* for you to write your own implementation of this interface using Enums or similar.
|
||||||
|
* It's also recommended that you define constants in the contract, like ROLE_ADMIN below,
|
||||||
|
* to avoid typos.
|
||||||
*/
|
*/
|
||||||
contract RBAC {
|
contract RBAC {
|
||||||
using Roles for Roles.Role;
|
using Roles for Roles.Role;
|
||||||
|
|
||||||
mapping (string => Roles.Role) private roles;
|
mapping (string => Roles.Role) private roles;
|
||||||
|
|
||||||
event LogRoleAdded(address addr, string roleName);
|
event RoleAdded(address addr, string roleName);
|
||||||
event LogRoleRemoved(address addr, string roleName);
|
event RoleRemoved(address addr, string roleName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constant role name for indicating admins.
|
* A constant role name for indicating admins.
|
||||||
@ -43,7 +45,7 @@ contract RBAC {
|
|||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
roles[roleName].add(addr);
|
roles[roleName].add(addr);
|
||||||
LogRoleAdded(addr, roleName);
|
RoleAdded(addr, roleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +57,7 @@ contract RBAC {
|
|||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
roles[roleName].remove(addr);
|
roles[roleName].remove(addr);
|
||||||
LogRoleRemoved(addr, roleName);
|
RoleRemoved(addr, roleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,17 +1,21 @@
|
|||||||
const RBACMock = artifacts.require('./helpers/RBACMock.sol')
|
const RBACMock = artifacts.require('./mocks/RBACMock.sol')
|
||||||
|
|
||||||
import expectThrow from './helpers/expectThrow'
|
import expectThrow from './helpers/expectThrow'
|
||||||
|
import expectEvent from './helpers/expectEvent'
|
||||||
|
|
||||||
require('chai')
|
require('chai')
|
||||||
.use(require('chai-as-promised'))
|
.use(require('chai-as-promised'))
|
||||||
.should()
|
.should()
|
||||||
|
|
||||||
|
const ROLE_ADVISOR = 'advisor';
|
||||||
|
|
||||||
contract('RBAC', function(accounts) {
|
contract('RBAC', function(accounts) {
|
||||||
let mock
|
let mock
|
||||||
|
|
||||||
const [
|
const [
|
||||||
admin,
|
admin,
|
||||||
anyone,
|
anyone,
|
||||||
|
futureAdvisor,
|
||||||
...advisors
|
...advisors
|
||||||
] = accounts
|
] = accounts
|
||||||
|
|
||||||
@ -60,9 +64,23 @@ contract('RBAC', function(accounts) {
|
|||||||
.should.be.fulfilled
|
.should.be.fulfilled
|
||||||
})
|
})
|
||||||
it('allows admins to #adminRemoveRole', async () => {
|
it('allows admins to #adminRemoveRole', async () => {
|
||||||
await mock.adminRemoveRole(advisors[3], 'advisor', { from: admin })
|
await mock.adminRemoveRole(advisors[3], ROLE_ADVISOR, { from: admin })
|
||||||
.should.be.fulfilled
|
.should.be.fulfilled
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('announces a RoleAdded event on addRole', async () => {
|
||||||
|
expectEvent.inTransaction(
|
||||||
|
mock.adminAddRole(futureAdvisor, ROLE_ADVISOR, { from: admin }),
|
||||||
|
'RoleAdded'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('announces a RoleRemoved event on removeRole', async () => {
|
||||||
|
expectEvent.inTransaction(
|
||||||
|
mock.adminRemoveRole(futureAdvisor, ROLE_ADVISOR, { from: admin }),
|
||||||
|
'RoleRemoved'
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
context('in adversarial conditions', () => {
|
context('in adversarial conditions', () => {
|
||||||
16
test/helpers/expectEvent.js
Normal file
16
test/helpers/expectEvent.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const assert = require('chai').assert;
|
||||||
|
|
||||||
|
const inLogs = async (logs, eventName) => {
|
||||||
|
const event = logs.find(e => e.event === eventName);
|
||||||
|
assert.exists(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inTransaction = async (tx, eventName) => {
|
||||||
|
const { logs } = await tx;
|
||||||
|
return inLogs(logs, eventName);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
inLogs,
|
||||||
|
inTransaction,
|
||||||
|
};
|
||||||
@ -5,11 +5,13 @@ import '../../contracts/ownership/rbac/RBAC.sol';
|
|||||||
|
|
||||||
contract RBACMock is RBAC {
|
contract RBACMock is RBAC {
|
||||||
|
|
||||||
|
string constant ROLE_ADVISOR = "advisor";
|
||||||
|
|
||||||
modifier onlyAdminOrAdvisor()
|
modifier onlyAdminOrAdvisor()
|
||||||
{
|
{
|
||||||
require(
|
require(
|
||||||
hasRole(msg.sender, "admin") ||
|
hasRole(msg.sender, ROLE_ADMIN) ||
|
||||||
hasRole(msg.sender, "advisor")
|
hasRole(msg.sender, ROLE_ADVISOR)
|
||||||
);
|
);
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
@ -17,23 +19,22 @@ contract RBACMock is RBAC {
|
|||||||
function RBACMock(address[] _advisors)
|
function RBACMock(address[] _advisors)
|
||||||
public
|
public
|
||||||
{
|
{
|
||||||
addRole(msg.sender, "admin");
|
addRole(msg.sender, ROLE_ADVISOR);
|
||||||
addRole(msg.sender, "advisor");
|
|
||||||
|
|
||||||
for (uint256 i = 0; i < _advisors.length; i++) {
|
for (uint256 i = 0; i < _advisors.length; i++) {
|
||||||
addRole(_advisors[i], "advisor");
|
addRole(_advisors[i], ROLE_ADVISOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onlyAdminsCanDoThis()
|
function onlyAdminsCanDoThis()
|
||||||
onlyRole("admin")
|
onlyAdmin
|
||||||
view
|
view
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
function onlyAdvisorsCanDoThis()
|
function onlyAdvisorsCanDoThis()
|
||||||
onlyRole("advisor")
|
onlyRole(ROLE_ADVISOR)
|
||||||
view
|
view
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
@ -60,9 +61,9 @@ contract RBACMock is RBAC {
|
|||||||
{
|
{
|
||||||
// revert if the user isn't an advisor
|
// revert if the user isn't an advisor
|
||||||
// (perhaps you want to soft-fail here instead?)
|
// (perhaps you want to soft-fail here instead?)
|
||||||
checkRole(_addr, "advisor");
|
checkRole(_addr, ROLE_ADVISOR);
|
||||||
|
|
||||||
// remove the advisor's role
|
// remove the advisor's role
|
||||||
removeRole(_addr, "advisor");
|
removeRole(_addr, ROLE_ADVISOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user