3 namespace Drupal\Tests\layout_builder\Unit;
5 use Drupal\block_content\Access\RefinableDependentAccessInterface;
6 use Drupal\Component\Plugin\Context\ContextInterface;
7 use Drupal\Core\Access\AccessResult;
8 use Drupal\Core\Block\BlockManagerInterface;
9 use Drupal\Core\Block\BlockPluginInterface;
10 use Drupal\Core\Cache\Cache;
11 use Drupal\Core\DependencyInjection\ContainerBuilder;
12 use Drupal\Core\Entity\EntityInterface;
13 use Drupal\Core\Plugin\Context\ContextHandlerInterface;
14 use Drupal\Core\Session\AccountInterface;
15 use Drupal\layout_builder\Access\LayoutPreviewAccessAllowed;
16 use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
17 use Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray;
18 use Drupal\layout_builder\SectionComponent;
19 use Drupal\Tests\UnitTestCase;
22 * @coversDefaultClass \Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray
23 * @group layout_builder
25 class BlockComponentRenderArrayTest extends UnitTestCase {
30 * @var \Drupal\Core\Session\AccountInterface
35 * The block plugin manager.
37 * @var \Drupal\Core\Block\BlockManagerInterface
39 protected $blockManager;
42 * Dataprovider for test functions that should test block types.
44 public function providerBlockTypes() {
54 protected function setUp() {
57 $this->blockManager = $this->prophesize(BlockManagerInterface::class);
58 $this->account = $this->prophesize(AccountInterface::class);
60 $container = new ContainerBuilder();
61 $container->set('plugin.manager.block', $this->blockManager->reveal());
62 $container->set('context.handler', $this->prophesize(ContextHandlerInterface::class));
63 \Drupal::setContainer($container);
67 * @covers ::onBuildRender
69 * @dataProvider providerBlockTypes
71 public function testOnBuildRender($refinable_dependent_access) {
73 if ($refinable_dependent_access) {
74 $block = $this->prophesize(TestBlockPluginWithRefinableDependentAccessInterface::class);
75 $layout_entity = $this->prophesize(EntityInterface::class);
76 $layout_entity = $layout_entity->reveal();
77 $context = $this->prophesize(ContextInterface::class);
78 $context->getContextValue()->willReturn($layout_entity);
79 $contexts['layout_builder.entity'] = $context->reveal();
81 $block->setAccessDependency($layout_entity)->shouldBeCalled();
84 $block = $this->prophesize(BlockPluginInterface::class);
86 $access_result = AccessResult::allowed();
87 $block->access($this->account->reveal(), TRUE)->willReturn($access_result)->shouldBeCalled();
88 $block->getCacheContexts()->willReturn([]);
89 $block->getCacheTags()->willReturn(['test']);
90 $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
91 $block->getConfiguration()->willReturn([]);
92 $block->getPluginId()->willReturn('block_plugin_id');
93 $block->getBaseId()->willReturn('block_plugin_id');
94 $block->getDerivativeId()->willReturn(NULL);
96 $block_content = ['#markup' => 'The block content.'];
97 $block->build()->willReturn($block_content);
98 $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
100 $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
102 $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
104 $subscriber = new BlockComponentRenderArray($this->account->reveal());
109 '#configuration' => [],
110 '#plugin_id' => 'block_plugin_id',
111 '#base_plugin_id' => 'block_plugin_id',
112 '#derivative_plugin_id' => NULL,
113 'content' => $block_content,
116 $expected_cache = $expected_build + [
124 $subscriber->onBuildRender($event);
125 $result = $event->getBuild();
126 $this->assertEquals($expected_build, $result);
127 $event->getCacheableMetadata()->applyTo($result);
128 $this->assertEquals($expected_cache, $result);
132 * @covers ::onBuildRender
134 * @dataProvider providerBlockTypes
136 public function testOnBuildRenderDenied($refinable_dependent_access) {
138 if ($refinable_dependent_access) {
139 $block = $this->prophesize(TestBlockPluginWithRefinableDependentAccessInterface::class);
141 $layout_entity = $this->prophesize(EntityInterface::class);
142 $layout_entity = $layout_entity->reveal();
143 $context = $this->prophesize(ContextInterface::class);
144 $context->getContextValue()->willReturn($layout_entity);
145 $contexts['layout_builder.entity'] = $context->reveal();
147 $block->setAccessDependency($layout_entity)->shouldBeCalled();
150 $block = $this->prophesize(BlockPluginInterface::class);
153 $access_result = AccessResult::forbidden();
154 $block->access($this->account->reveal(), TRUE)->willReturn($access_result)->shouldBeCalled();
155 $block->getCacheContexts()->shouldNotBeCalled();
156 $block->getCacheTags()->shouldNotBeCalled();
157 $block->getCacheMaxAge()->shouldNotBeCalled();
158 $block->getConfiguration()->shouldNotBeCalled();
159 $block->getPluginId()->shouldNotBeCalled();
160 $block->getBaseId()->shouldNotBeCalled();
161 $block->getDerivativeId()->shouldNotBeCalled();
163 $block_content = ['#markup' => 'The block content.'];
164 $block->build()->willReturn($block_content);
165 $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
167 $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
169 $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
171 $subscriber = new BlockComponentRenderArray($this->account->reveal());
173 $expected_build = [];
182 $subscriber->onBuildRender($event);
183 $result = $event->getBuild();
184 $this->assertEquals($expected_build, $result);
185 $event->getCacheableMetadata()->applyTo($result);
186 $this->assertEquals($expected_cache, $result);
190 * @covers ::onBuildRender
192 * @dataProvider providerBlockTypes
194 public function testOnBuildRenderInPreview($refinable_dependent_access) {
196 if ($refinable_dependent_access) {
197 $block = $this->prophesize(TestBlockPluginWithRefinableDependentAccessInterface::class);
198 $block->setAccessDependency(new LayoutPreviewAccessAllowed())->shouldBeCalled();
200 $layout_entity = $this->prophesize(EntityInterface::class);
201 $layout_entity = $layout_entity->reveal();
202 $layout_entity->in_preview = TRUE;
203 $context = $this->prophesize(ContextInterface::class);
204 $context->getContextValue()->willReturn($layout_entity);
205 $contexts['layout_builder.entity'] = $context->reveal();
208 $block = $this->prophesize(BlockPluginInterface::class);
211 $block->access($this->account->reveal(), TRUE)->shouldNotBeCalled();
212 $block->getCacheContexts()->willReturn([]);
213 $block->getCacheTags()->willReturn(['test']);
214 $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
215 $block->getConfiguration()->willReturn([]);
216 $block->getPluginId()->willReturn('block_plugin_id');
217 $block->getBaseId()->willReturn('block_plugin_id');
218 $block->getDerivativeId()->willReturn(NULL);
220 $block_content = ['#markup' => 'The block content.'];
221 $block->build()->willReturn($block_content);
222 $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
224 $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
226 $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
228 $subscriber = new BlockComponentRenderArray($this->account->reveal());
233 '#configuration' => [],
234 '#plugin_id' => 'block_plugin_id',
235 '#base_plugin_id' => 'block_plugin_id',
236 '#derivative_plugin_id' => NULL,
237 'content' => $block_content,
240 $expected_cache = $expected_build + [
248 $subscriber->onBuildRender($event);
249 $result = $event->getBuild();
250 $this->assertEquals($expected_build, $result);
251 $event->getCacheableMetadata()->applyTo($result);
252 $this->assertEquals($expected_cache, $result);
256 * @covers ::onBuildRender
258 public function testOnBuildRenderNoBlock() {
259 $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn(NULL);
261 $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
264 $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
266 $subscriber = new BlockComponentRenderArray($this->account->reveal());
268 $expected_build = [];
277 $subscriber->onBuildRender($event);
278 $result = $event->getBuild();
279 $this->assertEquals($expected_build, $result);
280 $event->getCacheableMetadata()->applyTo($result);
281 $this->assertEquals($expected_cache, $result);
287 * Test interface for dependent access block plugins.
289 interface TestBlockPluginWithRefinableDependentAccessInterface extends BlockPluginInterface, RefinableDependentAccessInterface {