3 namespace Drupal\Tests\Core\Entity\Access;
5 use Drupal\Component\Plugin\PluginManagerInterface;
6 use Drupal\Component\Uuid\UuidInterface;
7 use Drupal\Core\Cache\Context\CacheContextsManager;
8 use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
9 use Drupal\Core\DependencyInjection\Container;
10 use Drupal\Core\Entity\Entity\Access\EntityFormDisplayAccessControlHandler;
11 use Drupal\Core\Entity\Entity\EntityFormDisplay;
12 use Drupal\Core\Entity\EntityFieldManagerInterface;
13 use Drupal\Core\Entity\EntityManager;
14 use Drupal\Core\Entity\EntityStorageInterface;
15 use Drupal\Core\Entity\EntityTypeManagerInterface;
16 use Drupal\Core\Extension\ModuleHandlerInterface;
17 use Drupal\Core\Field\FieldTypePluginManagerInterface;
18 use Drupal\Core\Field\FormatterPluginManager;
19 use Drupal\Core\Language\LanguageManagerInterface;
20 use Drupal\Core\Render\RendererInterface;
21 use Drupal\Core\Session\AccountInterface;
22 use Drupal\Tests\UnitTestCase;
25 * @coversDefaultClass \Drupal\Core\Entity\Entity\Access\EntityFormDisplayAccessControlHandler
28 class EntityFormDisplayAccessControlHandlerTest extends UnitTestCase {
31 * The field storage config access controller to test.
33 * @var \Drupal\field\FieldStorageConfigAccessControlHandler
35 protected $accessControlHandler;
38 * The mock module handler.
40 * @var \Drupal\Core\Extension\ModuleHandlerInterface
42 protected $moduleHandler;
45 * The mock account without field storage config access.
47 * @var \Drupal\Core\Session\AccountInterface
52 * The mock account with EntityFormDisplay access.
54 * @var \Drupal\Core\Session\AccountInterface
59 * The mock account with EntityFormDisplay access via parent access check.
61 * @var \Drupal\Core\Session\AccountInterface
63 protected $parent_member;
66 * The EntityFormDisplay entity used for testing.
68 * @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface
73 * Returns a mock Entity Type Manager.
75 * @return \Drupal\Core\Entity\EntityTypeManagerInterface
76 * The mocked entity type manager.
78 protected function getEntityTypeManager() {
79 $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
80 return $entity_type_manager->reveal();
86 protected function setUp() {
89 $this->anon = $this->getMock(AccountInterface::class);
91 ->expects($this->any())
92 ->method('hasPermission')
93 ->will($this->returnValue(FALSE));
95 ->expects($this->any())
97 ->will($this->returnValue(0));
99 $this->member = $this->getMock(AccountInterface::class);
101 ->expects($this->any())
102 ->method('hasPermission')
103 ->will($this->returnValueMap([
104 ['administer foobar form display', TRUE],
107 ->expects($this->any())
109 ->will($this->returnValue(2));
111 $this->parent_member = $this->getMock(AccountInterface::class);
113 ->expects($this->any())
114 ->method('hasPermission')
115 ->will($this->returnValueMap([
119 ->expects($this->any())
121 ->will($this->returnValue(3));
123 $entity_form_display_entity_type = $this->getMock(ConfigEntityTypeInterface::class);
124 $entity_form_display_entity_type->expects($this->any())
125 ->method('getAdminPermission')
126 ->will($this->returnValue('Llama'));
127 $entity_form_display_entity_type
128 ->expects($this->any())
130 ->will($this->returnValueMap([
131 ['langcode', 'langcode'],
133 $entity_form_display_entity_type->expects($this->any())
134 ->method('entityClassImplements')
135 ->will($this->returnValue(TRUE));
136 $entity_form_display_entity_type->expects($this->any())
137 ->method('getConfigPrefix')
140 $this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
142 ->expects($this->any())
143 ->method('getImplementations')
144 ->will($this->returnValue([]));
146 ->expects($this->any())
147 ->method('invokeAll')
148 ->will($this->returnValue([]));
150 $storage_access_control_handler = new EntityFormDisplayAccessControlHandler($entity_form_display_entity_type);
151 $storage_access_control_handler->setModuleHandler($this->moduleHandler);
153 $entity_type_manager = $this->getMock(EntityTypeManagerInterface::class);
155 ->expects($this->any())
156 ->method('getStorage')
158 ['entity_display', $this->getMock(EntityStorageInterface::class)],
161 ->expects($this->any())
162 ->method('getAccessControlHandler')
164 ['entity_display', $storage_access_control_handler],
167 ->expects($this->any())
168 ->method('getDefinition')
169 ->will($this->returnValue($entity_form_display_entity_type));
171 $entity_field_manager = $this->getMock(EntityFieldManagerInterface::class);
172 $entity_field_manager->expects($this->any())
173 ->method('getFieldDefinitions')
174 ->will($this->returnValue([]));
176 $entity_manager = new EntityManager();
177 $container = new Container();
178 $container->set('entity.manager', $entity_manager);
179 $container->set('entity_type.manager', $entity_type_manager);
180 $container->set('entity_field.manager', $entity_field_manager);
181 $container->set('language_manager', $this->getMock(LanguageManagerInterface::class));
182 $container->set('plugin.manager.field.widget', $this->prophesize(PluginManagerInterface::class));
183 $container->set('plugin.manager.field.field_type', $this->getMock(FieldTypePluginManagerInterface::class));
184 $container->set('plugin.manager.field.formatter', $this->prophesize(FormatterPluginManager::class));
185 $container->set('uuid', $this->getMock(UuidInterface::class));
186 $container->set('renderer', $this->getMock(RendererInterface::class));
187 $container->set('cache_contexts_manager', $this->prophesize(CacheContextsManager::class));
188 // Inject the container into entity.manager so it can defer to
189 // entity_type.manager.
190 $entity_manager->setContainer($container);
191 \Drupal::setContainer($container);
193 $this->entity = new EntityFormDisplay([
194 'targetEntityType' => 'foobar',
195 'bundle' => 'bazqux',
197 'id' => 'foobar.bazqux.default',
198 'uuid' => '6f2f259a-f3c7-42ea-bdd5-111ad1f85ed1',
199 ], 'entity_display');
201 $this->accessControlHandler = $storage_access_control_handler;
205 * Assert method to verify the access by operations.
207 * @param array $allow_operations
208 * A list of allowed operations.
209 * @param \Drupal\Core\Session\AccountInterface $user
210 * The account to use for get access.
212 public function assertAllowOperations(array $allow_operations, AccountInterface $user) {
213 foreach (['view', 'update', 'delete'] as $operation) {
214 $expected = in_array($operation, $allow_operations);
215 $actual = $this->accessControlHandler->access($this->entity, $operation, $user);
216 $this->assertSame($expected, $actual, "Access problem with '$operation' operation.");
222 * @covers ::checkAccess
224 public function testAccess() {
225 $this->assertAllowOperations([], $this->anon);
226 $this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
227 $this->assertAllowOperations(['view', 'update', 'delete'], $this->parent_member);
229 $this->entity->enforceIsNew(TRUE)->save();
230 // Unfortunately, EntityAccessControlHandler has a static cache, which we
231 // therefore must reset manually.
232 $this->accessControlHandler->resetCache();
234 $this->assertAllowOperations([], $this->anon);
235 $this->assertAllowOperations(['view', 'update'], $this->member);
236 $this->assertAllowOperations(['view', 'update'], $this->parent_member);