3 namespace Drupal\Tests\entity\Unit;
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Cache\Context\CacheContextsManager;
7 use Drupal\Core\DependencyInjection\ContainerBuilder;
8 use Drupal\Core\Entity\ContentEntityInterface;
9 use Drupal\Core\Entity\ContentEntityTypeInterface;
10 use Drupal\Core\Entity\EntityInterface;
11 use Drupal\Core\Entity\EntityTypeInterface;
12 use Drupal\Core\Extension\ModuleHandlerInterface;
13 use Drupal\Core\Language\Language;
14 use Drupal\Core\Language\LanguageInterface;
15 use Drupal\Core\Session\AccountInterface;
16 use Drupal\entity\EntityAccessControlHandler;
17 use Drupal\Tests\UnitTestCase;
18 use Drupal\user\EntityOwnerInterface;
19 use Prophecy\Argument;
22 * @coversDefaultClass \Drupal\entity\EntityAccessControlHandler
25 class EntityAccessControlHandlerTest extends UnitTestCase {
30 protected function setUp() {
33 $module_handler = $this->prophesize(ModuleHandlerInterface::class);
34 $module_handler->invokeAll(Argument::any(), Argument::any())->willReturn([]);
35 $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
36 $cache_contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);
38 $container = new ContainerBuilder();
39 $container->set('module_handler', $module_handler->reveal());
40 $container->set('cache_contexts_manager', $cache_contexts_manager->reveal());
41 \Drupal::setContainer($container);
45 * @covers ::checkAccess
46 * @covers ::checkEntityPermissions
47 * @covers ::checkEntityOwnerPermissions
48 * @covers ::checkCreateAccess
50 * @dataProvider accessProvider
52 public function testAccess(EntityInterface $entity, $operation, $account, $allowed) {
53 $handler = new EntityAccessControlHandler($entity->getEntityType());
54 $handler->setStringTranslation($this->getStringTranslationStub());
55 $result = $handler->access($entity, $operation, $account);
56 $this->assertEquals($allowed, $result);
60 * @covers ::checkCreateAccess
62 * @dataProvider createAccessProvider
64 public function testCreateAccess(EntityTypeInterface $entity_type, $bundle, $account, $allowed) {
65 $handler = new EntityAccessControlHandler($entity_type);
66 $handler->setStringTranslation($this->getStringTranslationStub());
67 $result = $handler->createAccess($bundle, $account);
68 $this->assertEquals($allowed, $result);
72 * Data provider for testAccess().
75 * A list of testAccess method arguments.
77 public function accessProvider() {
80 $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
81 $entity_type->id()->willReturn('green_entity');
82 $entity_type->getAdminPermission()->willReturn('administer green_entity');
84 // User with the admin permission can do anything.
85 $entity = $this->buildMockEntity($entity_type->reveal());
86 $account = $this->prophesize(AccountInterface::class);
87 $account->id()->willReturn(6);
88 $account->hasPermission('administer green_entity')->willReturn(TRUE);
89 $data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
90 $data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
91 $data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
93 // Entity with no owner.
94 $entity = $this->buildMockEntity($entity_type->reveal());
95 // User who has access.
96 $first_account = $this->prophesize(AccountInterface::class);
97 $first_account->id()->willReturn(6);
98 $first_account->hasPermission('view green_entity')->willReturn(TRUE);
99 $first_account->hasPermission(Argument::any())->willReturn(FALSE);
100 // User who doesn't have access.
101 $second_account = $this->prophesize(AccountInterface::class);
102 $second_account->id()->willReturn(7);
103 $second_account->hasPermission('view green_entity')->willReturn(FALSE);
104 $second_account->hasPermission(Argument::any())->willReturn(FALSE);
105 $data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
106 $data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
108 // Entity with owner.
109 $entity = $this->buildMockEntity($entity_type->reveal(), 6);
111 $first_account = $this->prophesize(AccountInterface::class);
112 $first_account->id()->willReturn(6);
113 $first_account->hasPermission('update own green_entity')->willReturn(TRUE);
114 $first_account->hasPermission(Argument::any())->willReturn(FALSE);
116 $second_account = $this->prophesize(AccountInterface::class);
117 $second_account->id()->willReturn(7);
118 $second_account->hasPermission('update own green_entity')->willReturn(TRUE);
119 $second_account->hasPermission(Argument::any())->willReturn(FALSE);
120 // User who can update any.
121 $third_account = $this->prophesize(AccountInterface::class);
122 $third_account->id()->willReturn(8);
123 $third_account->hasPermission('update any green_entity')->willReturn(TRUE);
124 $third_account->hasPermission(Argument::any())->willReturn(FALSE);
125 $data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
126 $data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
127 $data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
133 * Data provider for testCreateAccess().
136 * A list of testCreateAccess method arguments.
138 public function createAccessProvider() {
141 $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
142 $entity_type->id()->willReturn('green_entity');
143 $entity_type->getAdminPermission()->willReturn('administer green_entity');
145 // User with the admin permission.
146 $account = $this->prophesize(AccountInterface::class);
147 $account->id()->willReturn(6);
148 $account->hasPermission('administer green_entity')->willReturn(TRUE);
149 $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
152 $account = $this->prophesize(AccountInterface::class);
153 $account->id()->willReturn(6);
154 $account->hasPermission('create green_entity')->willReturn(TRUE);
155 $account->hasPermission(Argument::any())->willReturn(FALSE);
156 $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
158 // Ordinary user, entity with a bundle.
159 $account = $this->prophesize(AccountInterface::class);
160 $account->id()->willReturn(6);
161 $account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
162 $account->hasPermission(Argument::any())->willReturn(FALSE);
163 $data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
165 // User with no permissions.
166 $account = $this->prophesize(AccountInterface::class);
167 $account->id()->willReturn(6);
168 $account->hasPermission(Argument::any())->willReturn(FALSE);
169 $data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
175 * Builds a mock entity.
177 * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
179 * @param string $owner_id
182 * @return \Prophecy\Prophecy\ObjectProphecy
185 protected function buildMockEntity(EntityTypeInterface $entity_type, $owner_id = NULL) {
186 $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
187 $entity = $this->prophesize(ContentEntityInterface::class);
189 $entity->willImplement(EntityOwnerInterface::class);
190 $entity->getOwnerId()->willReturn($owner_id);
192 $entity->bundle()->willReturn($entity_type->id());
193 $entity->isNew()->willReturn(FALSE);
194 $entity->uuid()->willReturn('fake uuid');
195 $entity->language()->willReturn(new Language(['id' => $langcode]));
196 $entity->getEntityTypeId()->willReturn($entity_type->id());
197 $entity->getEntityType()->willReturn($entity_type);
198 $entity->getCacheContexts()->willReturn([]);
199 $entity->getCacheTags()->willReturn([]);
200 $entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);