BlockContentAccessHandlerTest.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <?php
  2. namespace Drupal\Tests\block_content\Kernel;
  3. use Drupal\block_content\BlockContentAccessControlHandler;
  4. use Drupal\block_content\Entity\BlockContent;
  5. use Drupal\block_content\Entity\BlockContentType;
  6. use Drupal\Core\Access\AccessibleInterface;
  7. use Drupal\Core\Access\AccessResult;
  8. use Drupal\KernelTests\KernelTestBase;
  9. use Drupal\user\Entity\Role;
  10. use Drupal\user\Entity\User;
  11. /**
  12. * Tests the block content entity access handler.
  13. *
  14. * @coversDefaultClass \Drupal\block_content\BlockContentAccessControlHandler
  15. *
  16. * @group block_content
  17. */
  18. class BlockContentAccessHandlerTest extends KernelTestBase {
  19. /**
  20. * {@inheritdoc}
  21. */
  22. public static $modules = [
  23. 'block',
  24. 'block_content',
  25. 'system',
  26. 'user',
  27. ];
  28. /**
  29. * The BlockContent access controller to test.
  30. *
  31. * @var \Drupal\block_content\BlockContentAccessControlHandler
  32. */
  33. protected $accessControlHandler;
  34. /**
  35. * The BlockContent entity used for testing.
  36. *
  37. * @var \Drupal\block_content\Entity\BlockContent
  38. */
  39. protected $blockEntity;
  40. /**
  41. * The test role.
  42. *
  43. * @var \Drupal\user\RoleInterface
  44. */
  45. protected $role;
  46. /**
  47. * {@inheritdoc}
  48. */
  49. protected function setUp() {
  50. parent::setUp();
  51. $this->installSchema('system', ['sequence']);
  52. $this->installSchema('system', ['sequences']);
  53. $this->installSchema('user', ['users_data']);
  54. $this->installEntitySchema('user');
  55. $this->installEntitySchema('block_content');
  56. // Create a block content type.
  57. $block_content_type = BlockContentType::create([
  58. 'id' => 'square',
  59. 'label' => 'A square block type',
  60. 'description' => "Provides a block type that is square.",
  61. ]);
  62. $block_content_type->save();
  63. $this->blockEntity = BlockContent::create([
  64. 'info' => 'The Block',
  65. 'type' => 'square',
  66. ]);
  67. $this->blockEntity->save();
  68. // Create user 1 test does not have all permissions.
  69. User::create([
  70. 'name' => 'admin',
  71. ])->save();
  72. $this->role = Role::create([
  73. 'id' => 'roly',
  74. 'label' => 'roly poly',
  75. ]);
  76. $this->role->save();
  77. $this->accessControlHandler = new BlockContentAccessControlHandler(\Drupal::entityTypeManager()->getDefinition('block_content'), \Drupal::service('event_dispatcher'));
  78. }
  79. /**
  80. * @covers ::checkAccess
  81. *
  82. * @dataProvider providerTestAccess
  83. */
  84. public function testAccess($operation, $published, $reusable, $permissions, $parent_access, $expected_access) {
  85. $published ? $this->blockEntity->setPublished() : $this->blockEntity->setUnpublished();
  86. $reusable ? $this->blockEntity->setReusable() : $this->blockEntity->setNonReusable();
  87. $user = User::create([
  88. 'name' => 'Someone',
  89. 'mail' => 'hi@example.com',
  90. ]);
  91. if ($permissions) {
  92. foreach ($permissions as $permission) {
  93. $this->role->grantPermission($permission);
  94. }
  95. $this->role->save();
  96. }
  97. $user->addRole($this->role->id());
  98. $user->save();
  99. if ($parent_access) {
  100. $parent_entity = $this->prophesize(AccessibleInterface::class);
  101. $expected_parent_result = NULL;
  102. switch ($parent_access) {
  103. case 'allowed':
  104. $expected_parent_result = AccessResult::allowed();
  105. break;
  106. case 'neutral':
  107. $expected_parent_result = AccessResult::neutral();
  108. break;
  109. case 'forbidden':
  110. $expected_parent_result = AccessResult::forbidden();
  111. break;
  112. }
  113. $parent_entity->access($operation, $user, TRUE)
  114. ->willReturn($expected_parent_result)
  115. ->shouldBeCalled();
  116. $this->blockEntity->setAccessDependency($parent_entity->reveal());
  117. }
  118. $this->blockEntity->save();
  119. $result = $this->accessControlHandler->access($this->blockEntity, $operation, $user, TRUE);
  120. switch ($expected_access) {
  121. case 'allowed':
  122. $this->assertTrue($result->isAllowed());
  123. break;
  124. case 'forbidden':
  125. $this->assertTrue($result->isForbidden());
  126. break;
  127. case 'neutral':
  128. $this->assertTrue($result->isNeutral());
  129. break;
  130. default:
  131. $this->fail('Unexpected access type');
  132. }
  133. }
  134. /**
  135. * Dataprovider for testAccess().
  136. */
  137. public function providerTestAccess() {
  138. $cases = [
  139. 'view:published:reusable' => [
  140. 'view',
  141. TRUE,
  142. TRUE,
  143. [],
  144. NULL,
  145. 'allowed',
  146. ],
  147. 'view:unpublished:reusable' => [
  148. 'view',
  149. FALSE,
  150. TRUE,
  151. [],
  152. NULL,
  153. 'neutral',
  154. ],
  155. 'view:unpublished:reusable:admin' => [
  156. 'view',
  157. FALSE,
  158. TRUE,
  159. ['administer blocks'],
  160. NULL,
  161. 'allowed',
  162. ],
  163. 'view:published:reusable:admin' => [
  164. 'view',
  165. TRUE,
  166. TRUE,
  167. ['administer blocks'],
  168. NULL,
  169. 'allowed',
  170. ],
  171. 'view:published:non_reusable' => [
  172. 'view',
  173. TRUE,
  174. FALSE,
  175. [],
  176. NULL,
  177. 'forbidden',
  178. ],
  179. 'view:published:non_reusable:parent_allowed' => [
  180. 'view',
  181. TRUE,
  182. FALSE,
  183. [],
  184. 'allowed',
  185. 'allowed',
  186. ],
  187. 'view:published:non_reusable:parent_neutral' => [
  188. 'view',
  189. TRUE,
  190. FALSE,
  191. [],
  192. 'neutral',
  193. 'neutral',
  194. ],
  195. 'view:published:non_reusable:parent_forbidden' => [
  196. 'view',
  197. TRUE,
  198. FALSE,
  199. [],
  200. 'forbidden',
  201. 'forbidden',
  202. ],
  203. ];
  204. foreach (['update', 'delete'] as $operation) {
  205. $cases += [
  206. $operation . ':published:reusable' => [
  207. $operation,
  208. TRUE,
  209. TRUE,
  210. [],
  211. NULL,
  212. 'neutral',
  213. ],
  214. $operation . ':unpublished:reusable' => [
  215. $operation,
  216. FALSE,
  217. TRUE,
  218. [],
  219. NULL,
  220. 'neutral',
  221. ],
  222. $operation . ':unpublished:reusable:admin' => [
  223. $operation,
  224. FALSE,
  225. TRUE,
  226. ['administer blocks'],
  227. NULL,
  228. 'allowed',
  229. ],
  230. $operation . ':published:reusable:admin' => [
  231. $operation,
  232. TRUE,
  233. TRUE,
  234. ['administer blocks'],
  235. NULL,
  236. 'allowed',
  237. ],
  238. $operation . ':published:non_reusable' => [
  239. $operation,
  240. TRUE,
  241. FALSE,
  242. [],
  243. NULL,
  244. 'forbidden',
  245. ],
  246. $operation . ':published:non_reusable:parent_allowed' => [
  247. $operation,
  248. TRUE,
  249. FALSE,
  250. [],
  251. 'allowed',
  252. 'neutral',
  253. ],
  254. $operation . ':published:non_reusable:parent_neutral' => [
  255. $operation,
  256. TRUE,
  257. FALSE,
  258. [],
  259. 'neutral',
  260. 'neutral',
  261. ],
  262. $operation . ':published:non_reusable:parent_forbidden' => [
  263. $operation,
  264. TRUE,
  265. FALSE,
  266. [],
  267. 'forbidden',
  268. 'forbidden',
  269. ],
  270. ];
  271. return $cases;
  272. }
  273. }
  274. }