Added Entity and Entity Reference Revisions which got dropped somewhere along the...
[yaffs-website] / web / modules / contrib / entity / tests / src / Unit / EntityAccessControlHandlerTest.php
1 <?php
2
3 namespace Drupal\Tests\entity\Unit;
4
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\EntityPublishedInterface;
12 use Drupal\Core\Entity\EntityTypeInterface;
13 use Drupal\Core\Extension\ModuleHandlerInterface;
14 use Drupal\Core\Language\Language;
15 use Drupal\Core\Language\LanguageInterface;
16 use Drupal\Core\Session\AccountInterface;
17 use Drupal\entity\EntityAccessControlHandler;
18 use Drupal\entity\EntityPermissionProvider;
19 use Drupal\Tests\UnitTestCase;
20 use Drupal\user\EntityOwnerInterface;
21 use Prophecy\Argument;
22
23 /**
24  * @coversDefaultClass \Drupal\entity\EntityAccessControlHandler
25  * @group entity
26  */
27 class EntityAccessControlHandlerTest extends UnitTestCase {
28
29   /**
30    * {@inheritdoc}
31    */
32   protected function setUp() {
33     parent::setUp();
34
35     $module_handler = $this->prophesize(ModuleHandlerInterface::class);
36     $module_handler->invokeAll(Argument::any(), Argument::any())->willReturn([]);
37     $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
38     $cache_contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);
39
40     $container = new ContainerBuilder();
41     $container->set('module_handler', $module_handler->reveal());
42     $container->set('cache_contexts_manager', $cache_contexts_manager->reveal());
43     \Drupal::setContainer($container);
44   }
45
46   /**
47    * @covers ::checkAccess
48    * @covers ::checkEntityPermissions
49    * @covers ::checkEntityOwnerPermissions
50    * @covers ::checkCreateAccess
51    *
52    * @dataProvider accessProvider
53    */
54   public function testAccess(EntityInterface $entity, $operation, $account, $allowed) {
55     $handler = new EntityAccessControlHandler($entity->getEntityType());
56     $handler->setStringTranslation($this->getStringTranslationStub());
57     $result = $handler->access($entity, $operation, $account);
58     $this->assertEquals($allowed, $result);
59   }
60
61   /**
62    * @covers ::checkCreateAccess
63    *
64    * @dataProvider createAccessProvider
65    */
66   public function testCreateAccess(EntityTypeInterface $entity_type, $bundle, $account, $allowed) {
67     $handler = new EntityAccessControlHandler($entity_type);
68     $handler->setStringTranslation($this->getStringTranslationStub());
69     $result = $handler->createAccess($bundle, $account);
70     $this->assertEquals($allowed, $result);
71   }
72
73   /**
74    * Data provider for testAccess().
75    *
76    * @return array
77    *   A list of testAccess method arguments.
78    */
79   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');
83     $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
84     $entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
85     $entity = $this->buildMockEntity($entity_type->reveal(), 6);
86
87     $data = [];
88     // Admin permission.
89     $admin_user = $this->buildMockUser(5, 'administer green_entity');
90     $data[] = [$entity->reveal(), 'view', $admin_user->reveal(), TRUE];
91     $data[] = [$entity->reveal(), 'update', $admin_user->reveal(), TRUE];
92     $data[] = [$entity->reveal(), 'delete', $admin_user->reveal(), TRUE];
93
94     // View, Update, delete permissions, entity without an owner.
95     $second_entity = $this->buildMockEntity($entity_type->reveal());
96     foreach (['view', 'update', 'delete'] as $operation) {
97       $first_user = $this->buildMockUser(6, $operation . ' green_entity');
98       $second_user = $this->buildMockUser(7, 'access content');
99
100       $data[] = [$second_entity->reveal(), $operation, $first_user->reveal(), TRUE];
101       $data[] = [$second_entity->reveal(), $operation, $second_user->reveal(), FALSE];
102     }
103
104     // Update and delete permissions.
105     foreach (['update', 'delete'] as $operation) {
106       // Owner, non-owner, user with "any" permission.
107       $first_user = $this->buildMockUser(6, $operation . ' own green_entity');
108       $second_user = $this->buildMockUser(7, $operation . ' own green_entity');
109       $third_user = $this->buildMockUser(8, $operation . ' any green_entity');
110
111       $data[] = [$entity->reveal(), $operation, $first_user->reveal(), TRUE];
112       $data[] = [$entity->reveal(), $operation, $second_user->reveal(), FALSE];
113       $data[] = [$entity->reveal(), $operation, $third_user->reveal(), TRUE];
114     }
115
116     // View permissions.
117     $first_user = $this->buildMockUser(9, 'view green_entity');
118     $second_user = $this->buildMockUser(10, 'view first green_entity');
119     $third_user = $this->buildMockUser(14, 'view own unpublished green_entity');
120     $fourth_user = $this->buildMockUser(14, 'access content');
121
122     $first_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'first');
123     $second_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'second');
124     $third_entity = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
125
126     // The first user can view the two published entities.
127     $data[] = [$first_entity->reveal(), 'view', $first_user->reveal(), TRUE];
128     $data[] = [$second_entity->reveal(), 'view', $first_user->reveal(), TRUE];
129     $data[] = [$third_entity->reveal(), 'view', $first_user->reveal(), FALSE];
130
131     // The second user can only view published entities of bundle "first".
132     $data[] = [$first_entity->reveal(), 'view', $second_user->reveal(), TRUE];
133     $data[] = [$second_entity->reveal(), 'view', $second_user->reveal(), FALSE];
134     $data[] = [$third_entity->reveal(), 'view', $second_user->reveal(), FALSE];
135
136     // The third user can view their own unpublished entity.
137     $data[] = [$first_entity->reveal(), 'view', $third_user->reveal(), FALSE];
138     $data[] = [$second_entity->reveal(), 'view', $third_user->reveal(), FALSE];
139     $data[] = [$third_entity->reveal(), 'view', $third_user->reveal(), TRUE];
140
141     // The fourth user can't view anything.
142     $data[] = [$first_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
143     $data[] = [$second_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
144     $data[] = [$third_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
145
146     return $data;
147   }
148
149   /**
150    * Data provider for testCreateAccess().
151    *
152    * @return array
153    *   A list of testCreateAccess method arguments.
154    */
155   public function createAccessProvider() {
156     $data = [];
157
158     $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
159     $entity_type->id()->willReturn('green_entity');
160     $entity_type->getAdminPermission()->willReturn('administer green_entity');
161     $entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
162     $entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
163
164     // User with the admin permission.
165     $account = $this->buildMockUser('6', 'administer green_entity');
166     $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
167
168     // Ordinary user.
169     $account = $this->buildMockUser('6', 'create green_entity');
170     $data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
171
172     // Ordinary user, entity with a bundle.
173     $account = $this->buildMockUser('6', 'create first_bundle green_entity');
174     $data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
175
176     // User with no permissions.
177     $account = $this->buildMockUser('6', 'access content');
178     $data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
179
180     return $data;
181   }
182
183   /**
184    * Builds a mock entity.
185    *
186    * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
187    *   The entity type.
188    * @param string $owner_id
189    *   The owner ID.
190    * @param string $bundle
191    *   The bundle.
192    * @param bool $published
193    *   Whether the entity is published.
194    *
195    * @return \Prophecy\Prophecy\ObjectProphecy
196    *   The entity mock.
197    */
198   protected function buildMockEntity(EntityTypeInterface $entity_type, $owner_id = NULL, $bundle = NULL, $published = NULL) {
199     $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
200     $entity = $this->prophesize(ContentEntityInterface::class);
201     if (isset($published)) {
202       $entity->willImplement(EntityPublishedInterface::class);
203     }
204     if ($owner_id) {
205       $entity->willImplement(EntityOwnerInterface::class);
206     }
207     if (isset($published)) {
208       $entity->isPublished()->willReturn($published);
209     }
210     if ($owner_id) {
211       $entity->getOwnerId()->willReturn($owner_id);
212     }
213
214     $entity->bundle()->willReturn($bundle ?: $entity_type->id());
215     $entity->isNew()->willReturn(FALSE);
216     $entity->uuid()->willReturn('fake uuid');
217     $entity->id()->willReturn('fake id');
218     $entity->getRevisionId()->willReturn(NULL);
219     $entity->language()->willReturn(new Language(['id' => $langcode]));
220     $entity->getEntityTypeId()->willReturn($entity_type->id());
221     $entity->getEntityType()->willReturn($entity_type);
222     $entity->getCacheContexts()->willReturn([]);
223     $entity->getCacheTags()->willReturn([]);
224     $entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
225
226     return $entity;
227   }
228
229   /**
230    * Builds a mock user.
231    *
232    * @param int $uid
233    *   The user ID.
234    * @param string $permission
235    *   The permission to grant.
236    *
237    * @return \Prophecy\Prophecy\ObjectProphecy
238    *   The user mock.
239    */
240   protected function buildMockUser($uid, $permission) {
241     $account = $this->prophesize(AccountInterface::class);
242     $account->id()->willReturn($uid);
243     $account->hasPermission($permission)->willReturn(TRUE);
244     $account->hasPermission(Argument::any())->willReturn(FALSE);
245
246     return $account;
247   }
248
249 }