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
74 * Returns a mock Entity Type Manager.
76 * @return \Drupal\Core\Entity\EntityTypeManagerInterface
77 * The mocked entity type manager.
79 protected function getEntityTypeManager() {
80 $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
81 return $entity_type_manager->reveal();
87 protected function setUp() {
90 $this->anon = $this->getMock(AccountInterface::class);
92 ->expects($this->any())
93 ->method('hasPermission')
94 ->will($this->returnValue(FALSE));
96 ->expects($this->any())
98 ->will($this->returnValue(0));
100 $this->member = $this->getMock(AccountInterface::class);
102 ->expects($this->any())
103 ->method('hasPermission')
104 ->will($this->returnValueMap([
105 ['administer foobar form display', TRUE],
108 ->expects($this->any())
110 ->will($this->returnValue(2));
112 $this->parent_member = $this->getMock(AccountInterface::class);
114 ->expects($this->any())
115 ->method('hasPermission')
116 ->will($this->returnValueMap([
120 ->expects($this->any())
122 ->will($this->returnValue(3));
124 $entity_form_display_entity_type = $this->getMock(ConfigEntityTypeInterface::class);
125 $entity_form_display_entity_type->expects($this->any())
126 ->method('getAdminPermission')
127 ->will($this->returnValue('Llama'));
128 $entity_form_display_entity_type
129 ->expects($this->any())
131 ->will($this->returnValueMap([
132 ['langcode', 'langcode'],
134 $entity_form_display_entity_type->expects($this->any())
135 ->method('entityClassImplements')
136 ->will($this->returnValue(TRUE));
137 $entity_form_display_entity_type->expects($this->any())
138 ->method('getConfigPrefix')
141 $this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
143 ->expects($this->any())
144 ->method('getImplementations')
145 ->will($this->returnValue([]));
147 ->expects($this->any())
148 ->method('invokeAll')
149 ->will($this->returnValue([]));
151 $storage_access_control_handler = new EntityFormDisplayAccessControlHandler($entity_form_display_entity_type);
152 $storage_access_control_handler->setModuleHandler($this->moduleHandler);
154 $entity_type_manager = $this->getMock(EntityTypeManagerInterface::class);
156 ->expects($this->any())
157 ->method('getStorage')
159 ['entity_display', $this->getMock(EntityStorageInterface::class)],
162 ->expects($this->any())
163 ->method('getAccessControlHandler')
165 ['entity_display', $storage_access_control_handler],
168 ->expects($this->any())
169 ->method('getDefinition')
170 ->will($this->returnValue($entity_form_display_entity_type));
172 $entity_field_manager = $this->getMock(EntityFieldManagerInterface::class);
173 $entity_field_manager->expects($this->any())
174 ->method('getFieldDefinitions')
175 ->will($this->returnValue([]));
177 $entity_manager = new EntityManager();
178 $container = new Container();
179 $container->set('entity.manager', $entity_manager);
180 $container->set('entity_type.manager', $entity_type_manager);
181 $container->set('entity_field.manager', $entity_field_manager);
182 $container->set('language_manager', $this->getMock(LanguageManagerInterface::class));
183 $container->set('plugin.manager.field.widget', $this->prophesize(PluginManagerInterface::class));
184 $container->set('plugin.manager.field.field_type', $this->getMock(FieldTypePluginManagerInterface::class));
185 $container->set('plugin.manager.field.formatter', $this->prophesize(FormatterPluginManager::class));
186 $container->set('uuid', $this->getMock(UuidInterface::class));
187 $container->set('renderer', $this->getMock(RendererInterface::class));
188 $container->set('cache_contexts_manager', $this->prophesize(CacheContextsManager::class));
189 // Inject the container into entity.manager so it can defer to
190 // entity_type.manager.
191 $entity_manager->setContainer($container);
192 \Drupal::setContainer($container);
194 $this->entity = new EntityFormDisplay([
195 'targetEntityType' => 'foobar',
196 'bundle' => 'bazqux',
198 'id' => 'foobar.bazqux.default',
199 'uuid' => '6f2f259a-f3c7-42ea-bdd5-111ad1f85ed1',
200 ], 'entity_display');
202 $this->accessControlHandler = $storage_access_control_handler;
206 * Assert method to verify the access by operations.
208 * @param array $allow_operations
209 * A list of allowed operations.
210 * @param \Drupal\Core\Session\AccountInterface $user
211 * The account to use for get access.
213 public function assertAllowOperations(array $allow_operations, AccountInterface $user) {
214 foreach (['view', 'update', 'delete'] as $operation) {
215 $expected = in_array($operation, $allow_operations);
216 $actual = $this->accessControlHandler->access($this->entity, $operation, $user);
217 $this->assertSame($expected, $actual, "Access problem with '$operation' operation.");
223 * @covers ::checkAccess
225 public function testAccess() {
226 $this->assertAllowOperations([], $this->anon);
227 $this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
228 $this->assertAllowOperations(['view', 'update', 'delete'], $this->parent_member);
230 $this->entity->enforceIsNew(TRUE)->save();
231 // Unfortunately, EntityAccessControlHandler has a static cache, which we
232 // therefore must reset manually.
233 $this->accessControlHandler->resetCache();
235 $this->assertAllowOperations([], $this->anon);
236 $this->assertAllowOperations(['view', 'update'], $this->member);
237 $this->assertAllowOperations(['view', 'update'], $this->parent_member);