Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: update event names for OZ standards and test them
  • Loading branch information
shrugs committed Dec 4, 2017
commit 677d05743c1df9344827d0159a97923d83adad7b
10 changes: 6 additions & 4 deletions contracts/ownership/rbac/RBAC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import './Roles.sol';
* See //contracts/examples/RBACExample.sol for an example of usage.
* 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.
* It's also recommended that you define constants in the contract, like ROLE_ADMIN below,
* to avoid typos.
*/
contract RBAC {
using Roles for Roles.Role;

mapping (string => Roles.Role) private roles;

event LogRoleAdded(address addr, string roleName);
event LogRoleRemoved(address addr, string roleName);
event RoleAdded(address addr, string roleName);
event RoleRemoved(address addr, string roleName);

/**
* A constant role name for indicating admins.
Expand All @@ -43,7 +45,7 @@ contract RBAC {
internal
{
roles[roleName].add(addr);
LogRoleAdded(addr, roleName);
RoleAdded(addr, roleName);
}

/**
Expand All @@ -55,7 +57,7 @@ contract RBAC {
internal
{
roles[roleName].remove(addr);
LogRoleRemoved(addr, roleName);
RoleRemoved(addr, roleName);
}

/**
Expand Down
22 changes: 20 additions & 2 deletions test/RBAC.js → test/RBAC.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
const RBACMock = artifacts.require('./helpers/RBACMock.sol')
const RBACMock = artifacts.require('./mocks/RBACMock.sol')

import expectThrow from './helpers/expectThrow'
import expectEvent from './helpers/expectEvent'

require('chai')
.use(require('chai-as-promised'))
.should()

const ROLE_ADVISOR = 'advisor';

contract('RBAC', function(accounts) {
let mock

const [
admin,
anyone,
futureAdvisor,
...advisors
] = accounts

Expand Down Expand Up @@ -60,9 +64,23 @@ contract('RBAC', function(accounts) {
.should.be.fulfilled
})
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
})

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', () => {
Expand Down
16 changes: 16 additions & 0 deletions test/helpers/expectEvent.js
Original file line number Diff line number Diff line change
@@ -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,
};
19 changes: 10 additions & 9 deletions test/helpers/RBACMock.sol → test/mocks/RBACMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,36 @@ import '../../contracts/ownership/rbac/RBAC.sol';

contract RBACMock is RBAC {

string constant ROLE_ADVISOR = "advisor";

modifier onlyAdminOrAdvisor()
{
require(
hasRole(msg.sender, "admin") ||
hasRole(msg.sender, "advisor")
hasRole(msg.sender, ROLE_ADMIN) ||
hasRole(msg.sender, ROLE_ADVISOR)
);
_;
}

function RBACMock(address[] _advisors)
public
{
addRole(msg.sender, "admin");
addRole(msg.sender, "advisor");
addRole(msg.sender, ROLE_ADVISOR);

for (uint256 i = 0; i < _advisors.length; i++) {
addRole(_advisors[i], "advisor");
addRole(_advisors[i], ROLE_ADVISOR);
}
}

function onlyAdminsCanDoThis()
onlyRole("admin")
onlyAdmin
view
external
{
}

function onlyAdvisorsCanDoThis()
onlyRole("advisor")
onlyRole(ROLE_ADVISOR)
view
external
{
Expand All @@ -60,9 +61,9 @@ contract RBACMock is RBAC {
{
// revert if the user isn't an advisor
// (perhaps you want to soft-fail here instead?)
checkRole(_addr, "advisor");
checkRole(_addr, ROLE_ADVISOR);

// remove the advisor's role
removeRole(_addr, "advisor");
removeRole(_addr, ROLE_ADVISOR);
}
}