PublicRole.behavior.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const shouldFail = require('../../helpers/shouldFail');
  2. const { ZERO_ADDRESS } = require('../../helpers/constants');
  3. const expectEvent = require('../../helpers/expectEvent');
  4. require('../../helpers/setup');
  5. function capitalize (str) {
  6. return str.replace(/\b\w/g, l => l.toUpperCase());
  7. }
  8. function shouldBehaveLikePublicRole (authorized, otherAuthorized, [anyone], rolename, manager) {
  9. rolename = capitalize(rolename);
  10. describe('should behave like public role', function () {
  11. beforeEach('check preconditions', async function () {
  12. (await this.contract[`is${rolename}`](authorized)).should.equal(true);
  13. (await this.contract[`is${rolename}`](otherAuthorized)).should.equal(true);
  14. (await this.contract[`is${rolename}`](anyone)).should.equal(false);
  15. });
  16. if (manager === undefined) { // Managed roles are only assigned by the manager, and none are set at construction
  17. it('emits events during construction', async function () {
  18. await expectEvent.inConstruction(this.contract, `${rolename}Added`, {
  19. account: authorized,
  20. });
  21. });
  22. }
  23. it('reverts when querying roles for the null account', async function () {
  24. await shouldFail.reverting(this.contract[`is${rolename}`](ZERO_ADDRESS));
  25. });
  26. describe('access control', function () {
  27. context('from authorized account', function () {
  28. const from = authorized;
  29. it('allows access', async function () {
  30. await this.contract[`only${rolename}Mock`]({ from });
  31. });
  32. });
  33. context('from unauthorized account', function () {
  34. const from = anyone;
  35. it('reverts', async function () {
  36. await shouldFail.reverting(this.contract[`only${rolename}Mock`]({ from }));
  37. });
  38. });
  39. });
  40. describe('add', function () {
  41. const from = manager === undefined ? authorized : manager;
  42. context(`from ${manager ? 'the manager' : 'a role-haver'} account`, function () {
  43. it('adds role to a new account', async function () {
  44. await this.contract[`add${rolename}`](anyone, { from });
  45. (await this.contract[`is${rolename}`](anyone)).should.equal(true);
  46. });
  47. it(`emits a ${rolename}Added event`, async function () {
  48. const { logs } = await this.contract[`add${rolename}`](anyone, { from });
  49. expectEvent.inLogs(logs, `${rolename}Added`, { account: anyone });
  50. });
  51. it('reverts when adding role to an already assigned account', async function () {
  52. await shouldFail.reverting(this.contract[`add${rolename}`](authorized, { from }));
  53. });
  54. it('reverts when adding role to the null account', async function () {
  55. await shouldFail.reverting(this.contract[`add${rolename}`](ZERO_ADDRESS, { from }));
  56. });
  57. });
  58. });
  59. describe('remove', function () {
  60. // Non-managed roles have no restrictions on the mocked '_remove' function (exposed via 'remove').
  61. const from = manager || anyone;
  62. context(`from ${manager ? 'the manager' : 'any'} account`, function () {
  63. it('removes role from an already assigned account', async function () {
  64. await this.contract[`remove${rolename}`](authorized, { from });
  65. (await this.contract[`is${rolename}`](authorized)).should.equal(false);
  66. (await this.contract[`is${rolename}`](otherAuthorized)).should.equal(true);
  67. });
  68. it(`emits a ${rolename}Removed event`, async function () {
  69. const { logs } = await this.contract[`remove${rolename}`](authorized, { from });
  70. expectEvent.inLogs(logs, `${rolename}Removed`, { account: authorized });
  71. });
  72. it('reverts when removing from an unassigned account', async function () {
  73. await shouldFail.reverting(this.contract[`remove${rolename}`](anyone), { from });
  74. });
  75. it('reverts when removing role from the null account', async function () {
  76. await shouldFail.reverting(this.contract[`remove${rolename}`](ZERO_ADDRESS), { from });
  77. });
  78. });
  79. });
  80. describe('renouncing roles', function () {
  81. it('renounces an assigned role', async function () {
  82. await this.contract[`renounce${rolename}`]({ from: authorized });
  83. (await this.contract[`is${rolename}`](authorized)).should.equal(false);
  84. });
  85. it(`emits a ${rolename}Removed event`, async function () {
  86. const { logs } = await this.contract[`renounce${rolename}`]({ from: authorized });
  87. expectEvent.inLogs(logs, `${rolename}Removed`, { account: authorized });
  88. });
  89. it('reverts when renouncing unassigned role', async function () {
  90. await shouldFail.reverting(this.contract[`renounce${rolename}`]({ from: anyone }));
  91. });
  92. });
  93. });
  94. }
  95. module.exports = {
  96. shouldBehaveLikePublicRole,
  97. };