AccessControl.test.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. const { accounts, contract, web3 } = require('@openzeppelin/test-environment');
  2. const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
  3. const { expect } = require('chai');
  4. const AccessControlMock = contract.fromArtifact('AccessControlMock');
  5. describe('AccessControl', function () {
  6. const [ admin, authorized, otherAuthorized, other, otherAdmin ] = accounts;
  7. const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000';
  8. const ROLE = web3.utils.soliditySha3('ROLE');
  9. const OTHER_ROLE = web3.utils.soliditySha3('OTHER_ROLE');
  10. beforeEach(async function () {
  11. this.accessControl = await AccessControlMock.new({ from: admin });
  12. });
  13. describe('_setupRole', function () {
  14. it('cannot be called outside the constructor', async function () {
  15. await expectRevert(
  16. this.accessControl.setupRole(OTHER_ROLE, other),
  17. 'AccessControl: roles cannot be setup after construction'
  18. );
  19. });
  20. });
  21. describe('default admin', function () {
  22. it('deployer has default admin role', async function () {
  23. expect(await this.accessControl.hasRole(DEFAULT_ADMIN_ROLE, admin)).to.equal(true);
  24. });
  25. it('other roles\'s admin is the default admin role', async function () {
  26. expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(DEFAULT_ADMIN_ROLE);
  27. });
  28. it('default admin role\'s admin is itself', async function () {
  29. expect(await this.accessControl.getRoleAdmin(DEFAULT_ADMIN_ROLE)).to.equal(DEFAULT_ADMIN_ROLE);
  30. });
  31. });
  32. describe('granting', function () {
  33. it('admin can grant role to other accounts', async function () {
  34. const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  35. expectEvent(receipt, 'RoleGranted', { account: authorized, role: ROLE, sender: admin });
  36. expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(true);
  37. });
  38. it('non-admin cannot grant role to other accounts', async function () {
  39. await expectRevert(
  40. this.accessControl.grantRole(ROLE, authorized, { from: other }),
  41. 'AccessControl: sender must be an admin to grant'
  42. );
  43. });
  44. it('accounts can be granted a role multiple times', async function () {
  45. await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  46. const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  47. await expectEvent.not.inTransaction(receipt.tx, AccessControlMock, 'RoleGranted');
  48. });
  49. });
  50. describe('revoking', function () {
  51. it('roles that are not had can be revoked', async function () {
  52. expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false);
  53. const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin });
  54. await expectEvent.not.inTransaction(receipt.tx, AccessControlMock, 'RoleRevoked');
  55. });
  56. context('with granted role', function () {
  57. beforeEach(async function () {
  58. await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  59. });
  60. it('admin can revoke role', async function () {
  61. const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin });
  62. expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: admin });
  63. expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false);
  64. });
  65. it('non-admin cannot revoke role', async function () {
  66. await expectRevert(
  67. this.accessControl.revokeRole(ROLE, authorized, { from: other }),
  68. 'AccessControl: sender must be an admin to revoke'
  69. );
  70. });
  71. it('a role can be revoked multiple times', async function () {
  72. await this.accessControl.revokeRole(ROLE, authorized, { from: admin });
  73. const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: admin });
  74. await expectEvent.not.inTransaction(receipt.tx, AccessControlMock, 'RoleRevoked');
  75. });
  76. });
  77. });
  78. describe('renouncing', function () {
  79. it('roles that are not had can be renounced', async function () {
  80. const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized });
  81. await expectEvent.not.inTransaction(receipt.tx, AccessControlMock, 'RoleRevoked');
  82. });
  83. context('with granted role', function () {
  84. beforeEach(async function () {
  85. await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  86. });
  87. it('bearer can renounce role', async function () {
  88. const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized });
  89. expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: authorized });
  90. expect(await this.accessControl.hasRole(ROLE, authorized)).to.equal(false);
  91. });
  92. it('only the sender can renounce their roles', async function () {
  93. await expectRevert(
  94. this.accessControl.renounceRole(ROLE, authorized, { from: admin }),
  95. 'AccessControl: can only renounce roles for self'
  96. );
  97. });
  98. it('a role can be renounced multiple times', async function () {
  99. await this.accessControl.renounceRole(ROLE, authorized, { from: authorized });
  100. const receipt = await this.accessControl.renounceRole(ROLE, authorized, { from: authorized });
  101. await expectEvent.not.inTransaction(receipt.tx, AccessControlMock, 'RoleRevoked');
  102. });
  103. });
  104. });
  105. describe('enumerating', function () {
  106. it('role bearers can be enumerated', async function () {
  107. await this.accessControl.grantRole(ROLE, authorized, { from: admin });
  108. await this.accessControl.grantRole(ROLE, otherAuthorized, { from: admin });
  109. const memberCount = await this.accessControl.getRoleMemberCount(ROLE);
  110. expect(memberCount).to.bignumber.equal('2');
  111. const bearers = [];
  112. for (let i = 0; i < memberCount; ++i) {
  113. bearers.push(await this.accessControl.getRoleMember(ROLE, i));
  114. }
  115. expect(bearers).to.have.members([authorized, otherAuthorized]);
  116. });
  117. });
  118. describe('setting role admin', function () {
  119. beforeEach(async function () {
  120. await this.accessControl.setRoleAdmin(ROLE, OTHER_ROLE);
  121. await this.accessControl.grantRole(OTHER_ROLE, otherAdmin, { from: admin });
  122. });
  123. it('a role\'s admin role can be changed', async function () {
  124. expect(await this.accessControl.getRoleAdmin(ROLE)).to.equal(OTHER_ROLE);
  125. });
  126. it('the new admin can grant roles', async function () {
  127. const receipt = await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin });
  128. expectEvent(receipt, 'RoleGranted', { account: authorized, role: ROLE, sender: otherAdmin });
  129. });
  130. it('the new admin can revoke roles', async function () {
  131. await this.accessControl.grantRole(ROLE, authorized, { from: otherAdmin });
  132. const receipt = await this.accessControl.revokeRole(ROLE, authorized, { from: otherAdmin });
  133. expectEvent(receipt, 'RoleRevoked', { account: authorized, role: ROLE, sender: otherAdmin });
  134. });
  135. it('a role\'s previous admins no longer grant roles', async function () {
  136. await expectRevert(
  137. this.accessControl.grantRole(ROLE, authorized, { from: admin }),
  138. 'AccessControl: sender must be an admin to grant'
  139. );
  140. });
  141. it('a role\'s previous admins no longer revoke roles', async function () {
  142. await expectRevert(
  143. this.accessControl.revokeRole(ROLE, authorized, { from: admin }),
  144. 'AccessControl: sender must be an admin to revoke'
  145. );
  146. });
  147. });
  148. });