View source
<?php
namespace Drupal\Tests\panopoly_magic\Unit;
use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\Context\ContextInterface;
use Drupal\panopoly_magic\BlockPreviewInterface;
use Drupal\panopoly_magic\BlockPreviewRenderer;
use Drupal\Tests\UnitTestCase;
class BlockPreviewRendererTest extends UnitTestCase {
protected $blockManager;
protected $contextHandler;
protected $renderer;
public function setUp() {
$this->blockManager = $this
->prophesize(BlockManagerInterface::class);
$this->contextHandler = $this
->prophesize(ContextHandlerInterface::class);
$this->renderer = new BlockPreviewRenderer($this->blockManager
->reveal(), $this->contextHandler
->reveal());
$this->renderer
->setStringTranslation($this
->getStringTranslationStub());
}
public function testPlainBlock() {
$block_id = 'system_powered_by_block';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Powered by Drupal',
];
$block_plugin = $this
->prophesize(BlockPluginInterface::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Powered by Drupal',
]);
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$rendered = $this->renderer
->buildBlockPreview($block_id);
$this
->assertEquals([
'#markup' => 'Powered by Drupal',
], $rendered);
}
protected function mockContextDefinition($required = FALSE) {
$context_definition = $this
->prophesize(ContextDefinitionInterface::class);
$context_definition
->isRequired()
->willReturn($required);
return $context_definition;
}
public function testPlainContextAwareBlock() {
$block_id = 'context_aware_block';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Feel the context',
];
$block_context_mapping = [
'slot_1' => '@service.context1',
];
$block_context_definitions = [
'slot_1' => $this
->mockContextDefinition(TRUE),
'slot_2' => $this
->mockContextDefinition(TRUE),
'slot_3' => $this
->mockContextDefinition(FALSE),
];
$contexts = [
'@service.context1' => $this
->prophesize(ContextInterface::class)
->reveal(),
'@service.context2' => $this
->prophesize(ContextInterface::class)
->reveal(),
'@service.context3' => $this
->prophesize(ContextInterface::class)
->reveal(),
];
$block_plugin = $this
->prophesize(BlockBase::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Feel the context',
]);
$block_plugin
->getContextMapping()
->willReturn($block_context_mapping);
$block_plugin
->getContextDefinitions()
->willReturn($block_context_definitions);
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$this->contextHandler
->getMatchingContexts($contexts, $block_context_definitions['slot_2'])
->willReturn([
'@service.context2' => $contexts['@service.context2'],
'@service.context3' => $contexts['@service.context3'],
])
->shouldBeCalledTimes(1);
$this->contextHandler
->applyContextMapping($block_plugin
->reveal(), $contexts, [
'slot_1' => '@service.context1',
'slot_2' => '@service.context2',
])
->shouldBeCalledTimes(1);
$rendered = $this->renderer
->buildBlockPreview($block_id, $contexts);
$this
->assertEquals([
'#markup' => 'Feel the context',
], $rendered);
}
public function testBlockWithPreview() {
$block_id = 'block_with_preview';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Block with preview',
];
$block_plugin = $this
->prophesize(BlockWithPreviewInterface::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Normal block content',
])
->shouldNotBeCalled();
$block_plugin
->buildPreview()
->willReturn([
'#markup' => 'Block preview content',
])
->shouldBeCalledTimes(1);
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$rendered = $this->renderer
->buildBlockPreview($block_id);
$this
->assertEquals([
'#markup' => 'Block preview content',
], $rendered);
}
public function previewCallback(BlockPluginInterface $block_plugin) {
return [
'#markup' => 'Block preview callback content',
];
}
public function testBlockWithPreviewCallback() {
$block_id = 'block_with_preview_callback';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Block with preview callback',
'preview_callback' => [
$this,
'previewCallback',
],
];
$block_plugin = $this
->prophesize(BlockPluginInterface::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Normal block content',
])
->shouldNotBeCalled();
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$rendered = $this->renderer
->buildBlockPreview($block_id);
$this
->assertEquals([
'#markup' => 'Block preview callback content',
], $rendered);
}
public function testBlockWithPreviewImage() {
$block_id = 'block_with_preview_image';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Block with preview image',
'preview_image' => 'http://example.com/image.png',
'preview_alt' => 'Preview image alt',
];
$block_plugin = $this
->prophesize(BlockPluginInterface::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Normal block content',
])
->shouldNotBeCalled();
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$rendered = $this->renderer
->buildBlockPreview($block_id);
$expected = [
'#theme' => 'image',
'#uri' => 'http://example.com/image.png',
'#alt' => 'Preview image alt',
];
$this
->assertEquals($expected, $rendered);
}
public function testException1() {
$block_id = 'context_aware_block';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Feel the context',
];
$block_plugin = $this
->prophesize(BlockBase::class);
$block_plugin
->build()
->willReturn([
'#markup' => 'Feel the context',
])
->shouldNotBeCalled();
$block_plugin
->getContextMapping()
->willReturn([]);
$block_plugin
->getContextDefinitions()
->willReturn([]);
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$this->contextHandler
->applyContextMapping($block_plugin
->reveal(), [], [])
->willThrow(new ContextException("TEST"));
$rendered = $this->renderer
->buildBlockPreview($block_id, []);
$this
->assertEquals([
'#markup' => 'Missing required context',
], $rendered);
}
public function testException2() {
$block_id = 'system_powered_by_block';
$block_definition = [
'id' => $block_id,
'admin_label' => 'Powered by Drupal',
];
$block_plugin = $this
->prophesize(BlockPluginInterface::class);
$block_plugin
->build()
->willThrow(new ContextException("TEST"));
$this->blockManager
->getDefinition($block_id)
->willReturn($block_definition);
$this->blockManager
->createInstance($block_id)
->willReturn($block_plugin
->reveal());
$rendered = $this->renderer
->buildBlockPreview($block_id);
$this
->assertEquals([
'#markup' => 'Missing required context',
], $rendered);
}
}
interface BlockWithPreviewInterface extends BlockPluginInterface, BlockPreviewInterface {
}