AccessControl.test.js 7.2 KB

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