Move into nested docroot

This commit is contained in:
Rob Davies 2017-02-13 15:31:17 +00:00
parent 83a0d3a149
commit c8b70abde9
13405 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,28 @@
uuid: 1a6c0f14-78dc-4ede-bade-b8ce83881453
langcode: en
status: true
dependencies:
module:
- block_test
- system
theme:
- bartik
id: missing_schema
theme: bartik
region: sidebar_first
weight: 0
provider: null
plugin: system_branding_block
settings:
id: system_branding_block
label: 'Test missing schema on conditions'
provider: system
label_display: visible
use_site_logo: true
use_site_name: true
use_site_slogan: true
visibility:
missing_schema:
id: missing_schema
negate: 0
context_mapping: { }

View file

@ -0,0 +1,49 @@
<?php
/**
* @file
* Partial database to mimic the installation of the block_test module.
*/
use Drupal\Core\Database\Database;
use Symfony\Component\Yaml\Yaml;
$connection = Database::getConnection();
// Set the schema version.
$connection->insert('key_value')
->fields([
'collection' => 'system.schema',
'name' => 'block_test',
'value' => 'i:8000;',
])
->execute();
// Update core.extension.
$extensions = $connection->select('config')
->fields('config', ['data'])
->condition('collection', '')
->condition('name', 'core.extension')
->execute()
->fetchField();
$extensions = unserialize($extensions);
$extensions['module']['block_test'] = 8000;
$connection->update('config')
->fields([
'data' => serialize($extensions),
])
->condition('collection', '')
->condition('name', 'core.extension')
->execute();
// Install the block configuration.
$config = file_get_contents(__DIR__ . '/block.block.missing_schema.yml');
$config = Yaml::parse($config);
$connection->insert('config')
->fields(['data', 'name', 'collection'])
->values([
'name' => 'block.block.missing_schema',
'data' => serialize($config),
'collection' => '',
])
->execute();

View file

@ -0,0 +1,8 @@
name: 'Block test'
type: module
description: 'Provides test blocks.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- block

View file

@ -0,0 +1,62 @@
<?php
/**
* @file
* Provide test blocks.
*/
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Cache\Cache;
/**
* Implements hook_block_alter().
*/
function block_test_block_alter(&$block_info) {
if (\Drupal::state()->get('block_test_info_alter') && isset($block_info['test_block_instantiation'])) {
$block_info['test_block_instantiation']['category'] = t('Custom category');
}
}
/**
* Implements hook_block_view_BASE_BLOCK_ID_alter().
*/
function block_test_block_view_test_cache_alter(array &$build, BlockPluginInterface $block) {
if (\Drupal::state()->get('block_test_view_alter_suffix') !== NULL) {
$build['#attributes']['foo'] = 'bar';
}
if (\Drupal::state()->get('block_test_view_alter_append_pre_render_prefix') !== NULL) {
$build['#pre_render'][] = 'block_test_pre_render_alter_content';
}
}
/**
* Implements hook_block_build_BASE_BLOCK_ID_alter().
*/
function block_test_block_build_test_cache_alter(array &$build, BlockPluginInterface $block) {
// Test altering cache keys, contexts, tags and max-age.
if (\Drupal::state()->get('block_test_block_alter_cache_key') !== NULL) {
$build['#cache']['keys'][] = \Drupal::state()->get('block_test_block_alter_cache_key');
}
if (\Drupal::state()->get('block_test_block_alter_cache_context') !== NULL) {
$build['#cache']['contexts'][] = \Drupal::state()->get('block_test_block_alter_cache_context');
}
if (\Drupal::state()->get('block_test_block_alter_cache_tag') !== NULL) {
$build['#cache']['tags'] = Cache::mergeTags($build['#cache']['tags'], [\Drupal::state()->get('block_test_block_alter_cache_tag')]);
}
if (\Drupal::state()->get('block_test_block_alter_cache_max_age') !== NULL) {
$build['#cache']['max-age'] = \Drupal::state()->get('block_test_block_alter_cache_max_age');
}
// Test setting #create_placeholder.
if (\Drupal::state()->get('block_test_block_alter_create_placeholder') !== NULL) {
$build['#create_placeholder'] = \Drupal::state()->get('block_test_block_alter_create_placeholder');
}
}
/**
* #pre_render callback for a block to alter its content.
*/
function block_test_pre_render_alter_content($build) {
$build['#prefix'] = 'Hiya!<br>';
return $build;
}

View file

@ -0,0 +1,7 @@
block_test.test_multipleforms:
path: '/test-multiple-forms'
defaults:
_controller: '\Drupal\block_test\Controller\TestMultipleFormController::testMultipleForms'
_title: 'Multiple forms'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,6 @@
services:
block_test.multiple_static_context:
class: Drupal\block_test\ContextProvider\MultipleStaticContext
arguments: ['@current_user', '@entity.manager']
tags:
- { name: 'context_provider' }

View file

@ -0,0 +1,17 @@
id: test_block
theme: stark
weight: 0
status: true
langcode: en
region: '-1'
plugin: test_html
settings:
label: 'Test HTML block'
provider: block_test
label_display: 'hidden'
dependencies:
module:
- block_test
theme:
- classy
visibility: { }

View file

@ -0,0 +1,10 @@
block.settings.test_block_instantiation:
type: block_settings
label: 'Test block instantiation settings'
mapping:
display_message:
type: string
label: 'Message text'
condition.plugin.baloney_spam:
type: condition.plugin

View file

@ -0,0 +1,73 @@
<?php
namespace Drupal\block_test\ContextProvider;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Sets multiple contexts for a static value.
*/
class MultipleStaticContext implements ContextProviderInterface {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* The user storage.
*
* @var \Drupal\user\UserStorageInterface
*/
protected $userStorage;
/**
* Constructs a new MultipleStaticContext.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
*/
public function __construct(AccountInterface $account, EntityManagerInterface $entity_manager) {
$this->account = $account;
$this->userStorage = $entity_manager->getStorage('user');
}
/**
* {@inheritdoc}
*/
public function getRuntimeContexts(array $unqualified_context_ids) {
$current_user = $this->userStorage->load($this->account->id());
$context1 = new Context(new ContextDefinition('entity:user', 'User 1'), $current_user);
$context2 = new Context(new ContextDefinition('entity:user', 'User 2'), $current_user);
$cacheability = new CacheableMetadata();
$cacheability->setCacheContexts(['user']);
$context1->addCacheableDependency($cacheability);
$context2->addCacheableDependency($cacheability);
return [
'user1' => $context1,
'user2' => $context2,
];
}
/**
* {@inheritdoc}
*/
public function getAvailableContexts() {
return $this->getRuntimeContexts([]);
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace Drupal\block_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormState;
/**
* Controller for block_test module
*/
class TestMultipleFormController extends ControllerBase {
public function testMultipleForms() {
$form_state = new FormState();
$build = [
'form1' => $this->formBuilder()->buildForm('\Drupal\block_test\Form\TestForm', $form_state),
'form2' => $this->formBuilder()->buildForm('\Drupal\block_test\Form\FavoriteAnimalTestForm', $form_state),
];
// Output all attached placeholders trough drupal_set_message(), so we can
// see if there's only one in the tests.
$post_render_callable = function ($elements) {
$matches = [];
preg_match_all('<form\s(.*?)action="(.*?)"(.*)>', $elements, $matches);
$action_values = $matches[2];
foreach ($action_values as $action_value) {
drupal_set_message('Form action: ' . $action_value);
}
return $elements;
};
$build['#post_render'] = [$post_render_callable];
return $build;
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace Drupal\block_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class FavoriteAnimalTestForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'block_test_form_favorite_animal_test';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['favorite_animal'] = [
'#type' => 'textfield',
'#title' => $this->t('Your favorite animal.')
];
$form['submit_animal'] = [
'#type' => 'submit',
'#value' => $this->t('Submit your chosen animal'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message($this->t('Your favorite animal is: @favorite_animal', ['@favorite_animal' => $form['favorite_animal']['#value']]));
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace Drupal\block_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class TestForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'block_test_form_test';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Your .com email address.')
];
$form['show'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (strpos($form_state->getValue('email'), '.com') === FALSE) {
$form_state->setErrorByName('email', $this->t('This is not a .com email address.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message($this->t('Your email address is @email', ['@email' => $form['email']['#value']]));
}
}

View file

@ -0,0 +1,78 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\State\StateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a block to test access.
*
* @Block(
* id = "test_access",
* admin_label = @Translation("Test block access")
* )
*/
class TestAccessBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* Tests the test access block.
*
*
* @param array $configuration
* The plugin configuration, i.e. an array with configuration values keyed
* by configuration option name. The special key 'context' may be used to
* initialize the defined contexts by setting it to an array of context
* values keyed by context names.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\State\StateInterface $state
* The state.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, StateInterface $state) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->state = $state;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('state')
);
}
/**
* {@inheritdoc}
*/
protected function blockAccess(AccountInterface $account) {
return $this->state->get('test_block_access', FALSE) ? AccessResult::allowed()->setCacheMaxAge(0) : AccessResult::forbidden()->setCacheMaxAge(0);
}
/**
* {@inheritdoc}
*/
public function build() {
return ['#markup' => 'Hello test world'];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
}

View file

@ -0,0 +1,64 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Provides a basic block for testing block instantiation and configuration.
*
* @Block(
* id = "test_block_instantiation",
* admin_label = @Translation("Display message")
* )
*/
class TestBlockInstantiation extends BlockBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array(
'display_message' => 'no message set',
);
}
/**
* {@inheritdoc}
*/
protected function blockAccess(AccountInterface $account) {
return AccessResult::allowedIfHasPermission($account, 'access content');
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form['display_message'] = array(
'#type' => 'textfield',
'#title' => $this->t('Display message'),
'#default_value' => $this->configuration['display_message'],
);
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['display_message'] = $form_state->getValue('display_message');
}
/**
* {@inheritdoc}
*/
public function build() {
return array(
'#children' => $this->configuration['display_message'],
);
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a block to test caching.
*
* @Block(
* id = "test_cache",
* admin_label = @Translation("Test block caching")
* )
*/
class TestCacheBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$content = \Drupal::state()->get('block_test.content');
$build = array();
if (!empty($content)) {
$build['#markup'] = $content;
}
return $build;
}
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
return \Drupal::state()->get('block_test.cache_contexts', []);
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
return \Drupal::state()->get('block_test.cache_max_age', parent::getCacheMaxAge());
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\UserInterface;
/**
* Provides a context-aware block.
*
* @Block(
* id = "test_context_aware",
* admin_label = @Translation("Test context-aware block"),
* context = {
* "user" = @ContextDefinition("entity:user", required = FALSE)
* }
* )
*/
class TestContextAwareBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
/** @var $user \Drupal\user\UserInterface */
$user = $this->getContextValue('user');
return array(
'#prefix' => '<div id="' . $this->getPluginId() . '--username">',
'#suffix' => '</div>',
'#markup' => $user ? $user->getUsername() : 'No context mapping selected.' ,
);
}
/**
* {@inheritdoc}
*/
protected function blockAccess(AccountInterface $account) {
if ($this->getContextValue('user') instanceof UserInterface) {
drupal_set_message('User context found.');
}
return parent::blockAccess($account);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a context-aware block.
*
* @Block(
* id = "test_context_aware_unsatisfied",
* admin_label = @Translation("Test context-aware unsatisfied block"),
* context = {
* "user" = @ContextDefinition("entity:foobar")
* }
* )
*/
class TestContextAwareUnsatisfiedBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
return [
'#markup' => 'test',
];
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a block to test caching.
*
* @Block(
* id = "test_form_in_block",
* admin_label = @Translation("Test form block caching")
* )
*/
class TestFormBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
return \Drupal::formBuilder()->getForm('Drupal\block_test\Form\TestForm');
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a block to test HTML.
*
* @Block(
* id = "test_html",
* admin_label = @Translation("Test HTML block")
* )
*/
class TestHtmlBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
return array(
'#attributes' => \Drupal::state()->get('block_test.attributes'),
'#children' => \Drupal::state()->get('block_test.content'),
);
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a block with multiple forms.
*
* @Block(
* id = "test_multiple_forms_block",
* forms = {
* "secondary" = "\Drupal\block_test\PluginForm\EmptyBlockForm"
* },
* admin_label = @Translation("Multiple forms test block")
* )
*/
class TestMultipleFormsBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
return [];
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace Drupal\block_test\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a test settings validation block.
*
* @Block(
* id = "test_settings_validation",
* admin_label = @Translation("Test settings validation block"),
* )
*/
class TestSettingsValidationBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
return ['digits' => ['#type' => 'textfield']] + $form;
}
/**
* {@inheritdoc}
*/
public function blockValidate($form, FormStateInterface $form_state) {
if (!ctype_digit($form_state->getValue('digits'))) {
$form_state->setErrorByName('digits', $this->t('Only digits are allowed'));
}
}
/**
* {@inheritdoc}
*/
public function build() {
return ['#markup' => 'foo'];
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace Drupal\block_test\Plugin\Block;
/**
* Provides a block to test XSS in title.
*
* @Block(
* id = "test_xss_title",
* admin_label = "<script>alert('XSS subject');</script>"
* )
*/
class TestXSSTitleBlock extends TestCacheBlock {
}

View file

@ -0,0 +1,31 @@
<?php
namespace Drupal\block_test\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
/**
* Provides a 'baloney_spam' condition.
*
* @Condition(
* id = "baloney_spam",
* label = @Translation("Baloney spam"),
* )
*/
class BaloneySpam extends ConditionPluginBase {
/**
* {@inheritdoc}
*/
public function evaluate() {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function summary() {
return 'Summary';
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace Drupal\block_test\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
/**
* Provides a 'missing_schema' condition.
*
* @Condition(
* id = "missing_schema",
* label = @Translation("Missing schema"),
* )
*/
class MissingSchema extends ConditionPluginBase {
/**
* {@inheritdoc}
*/
public function evaluate() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function summary() {
return 'Summary';
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace Drupal\block_test\PluginForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormBase;
/**
* Provides a form for a block that is empty.
*/
class EmptyBlockForm extends PluginFormBase {
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
// Intentionally empty.
}
}

View file

@ -0,0 +1,7 @@
name: '<"Cat" & ''Mouse''>'
type: theme
description: 'Theme for testing special characters in block admin.'
core: 8.x
regions:
content: Content
help: Help

View file

@ -0,0 +1,16 @@
name: 'Block test theme'
type: theme
description: 'Theme for testing the block system'
version: VERSION
core: 8.x
regions:
sidebar_first: 'Left sidebar'
sidebar_second: 'Right sidebar'
content: Content
header: Header
footer: Footer
highlighted: Highlighted
help: Help
regions_hidden:
- sidebar_first
- sidebar_second

View file

@ -0,0 +1,9 @@
name: 'Block test views'
type: module
description: 'Provides a view and block to test block displays in views.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- block
- views

View file

@ -0,0 +1,45 @@
langcode: en
status: true
dependencies: { }
id: test_view_block
label: test_view_block
module: views
description: ''
tag: ''
base_table: views_test_data
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: null
display_options:
access:
type: none
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: some
options:
items_per_page: 5
style:
type: default
row:
type: fields
fields:
name:
id: name
table: views_test_data
field: name
title: test_view_block
block_1:
display_plugin: block
id: block_1
display_title: Block
position: null

View file

@ -0,0 +1,57 @@
langcode: en
status: true
dependencies:
module:
- user
id: test_view_block2
label: test_view_block2
module: views
description: ''
tag: ''
base_table: views_test_data
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: null
display_options:
access:
type: perm
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: some
options:
items_per_page: 5
style:
type: default
row:
type: fields
fields:
name:
id: name
table: views_test_data
field: name
title: test_view_block2
block_1:
display_plugin: block
id: block_1
display_title: Block
position: null
block_2:
display_plugin: block
id: block_2
display_title: Block
position: null
block_3:
display_plugin: block
id: block_3
display_title: Block
position: null

View file

@ -0,0 +1,93 @@
<?php
namespace Drupal\Tests\block\Kernel;
use Drupal\block\Entity\Block;
use Drupal\config\Tests\SchemaCheckTestTrait;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests the block config schema.
*
* @group block
*/
class BlockConfigSchemaTest extends KernelTestBase {
use SchemaCheckTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = array(
'block',
'aggregator',
'book',
'block_content',
'comment',
'forum',
'node',
'statistics',
// BlockManager->getModuleName() calls system_get_info().
'system',
'taxonomy',
'user',
'text',
);
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfig;
/**
* The block manager.
*
* @var \Drupal\Core\Block\BlockManagerInterface
*/
protected $blockManager;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->typedConfig = \Drupal::service('config.typed');
$this->blockManager = \Drupal::service('plugin.manager.block');
$this->installEntitySchema('block_content');
$this->installEntitySchema('taxonomy_term');
$this->installEntitySchema('node');
$this->installSchema('book', array('book'));
}
/**
* Tests the block config schema for block plugins.
*/
public function testBlockConfigSchema() {
foreach ($this->blockManager->getDefinitions() as $block_id => $definition) {
$id = strtolower($this->randomMachineName());
$block = Block::create(array(
'id' => $id,
'theme' => 'classy',
'weight' => 00,
'status' => TRUE,
'region' => 'content',
'plugin' => $block_id,
'settings' => array(
'label' => $this->randomMachineName(),
'provider' => 'system',
'label_display' => FALSE,
),
'visibility' => array(),
));
$block->save();
$config = $this->config("block.block.$id");
$this->assertEqual($config->get('id'), $id);
$this->assertConfigSchema($this->typedConfig, $config->getName(), $config->get());
}
}
}

View file

@ -0,0 +1,103 @@
<?php
namespace Drupal\Tests\block\Kernel;
use Drupal\Core\Form\FormState;
use Drupal\block\BlockInterface;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests that the block plugin can work properly without a supporting entity.
*
* @group block
*/
class BlockInterfaceTest extends KernelTestBase {
public static $modules = array('system', 'block', 'block_test', 'user');
/**
* Test configuration and subsequent form() and build() method calls.
*
* This test is attempting to test the existing block plugin api and all
* functionality that is expected to remain consistent. The arrays that are
* used for comparison can change, but only to include elements that are
* contained within BlockBase or the plugin being tested. Likely these
* comparison arrays should get smaller, not larger, as more form/build
* elements are moved into a more suitably responsible class.
*
* Instantiation of the plugin is the primary element being tested here. The
* subsequent method calls are just attempting to cause a failure if a
* dependency outside of the plugin configuration is required.
*/
public function testBlockInterface() {
$manager = $this->container->get('plugin.manager.block');
$configuration = array(
'label' => 'Custom Display Message',
);
$expected_configuration = array(
'id' => 'test_block_instantiation',
'label' => 'Custom Display Message',
'provider' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
'display_message' => 'no message set',
);
// Initial configuration of the block at construction time.
/** @var $display_block \Drupal\Core\Block\BlockPluginInterface */
$display_block = $manager->createInstance('test_block_instantiation', $configuration);
$this->assertIdentical($display_block->getConfiguration(), $expected_configuration, 'The block was configured correctly.');
// Updating an element of the configuration.
$display_block->setConfigurationValue('display_message', 'My custom display message.');
$expected_configuration['display_message'] = 'My custom display message.';
$this->assertIdentical($display_block->getConfiguration(), $expected_configuration, 'The block configuration was updated correctly.');
$definition = $display_block->getPluginDefinition();
$expected_form = array(
'provider' => array(
'#type' => 'value',
'#value' => 'block_test',
),
'admin_label' => array(
'#type' => 'item',
'#title' => t('Block description'),
'#plain_text' => $definition['admin_label'],
),
'label' => array(
'#type' => 'textfield',
'#title' => 'Title',
'#maxlength' => 255,
'#default_value' => 'Custom Display Message',
'#required' => TRUE,
),
'label_display' => array(
'#type' => 'checkbox',
'#title' => 'Display title',
'#default_value' => TRUE,
'#return_value' => 'visible',
),
'context_mapping' => array(),
'display_message' => array(
'#type' => 'textfield',
'#title' => t('Display message'),
'#default_value' => 'My custom display message.',
),
);
$form_state = new FormState();
// Ensure there are no form elements that do not belong to the plugin.
$actual_form = $display_block->buildConfigurationForm(array(), $form_state);
// Remove the visibility sections, as that just tests condition plugins.
unset($actual_form['visibility'], $actual_form['visibility_tabs']);
$this->assertIdentical($this->castSafeStrings($actual_form), $this->castSafeStrings($expected_form), 'Only the expected form elements were present.');
$expected_build = array(
'#children' => 'My custom display message.',
);
// Ensure the build array is proper.
$this->assertIdentical($display_block->build(), $expected_build, 'The plugin returned the appropriate build array.');
// Ensure the machine name suggestion is correct. In truth, this is actually
// testing BlockBase's implementation, not the interface itself.
$this->assertIdentical($display_block->getMachineNameSuggestion(), 'displaymessage', 'The plugin returned the expected machine name suggestion.');
}
}

View file

@ -0,0 +1,155 @@
<?php
namespace Drupal\Tests\block\Kernel;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\KernelTests\KernelTestBase;
use Drupal\block_test\Plugin\Block\TestHtmlBlock;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\block\Entity\Block;
use Drupal\block\BlockInterface;
/**
* Tests the storage of blocks.
*
* @group block
*/
class BlockStorageUnitTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('block', 'block_test', 'system');
/**
* The block storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface.
*/
protected $controller;
protected function setUp() {
parent::setUp();
$this->controller = $this->container->get('entity_type.manager')->getStorage('block');
}
/**
* Tests CRUD operations.
*/
public function testBlockCRUD() {
$this->assertTrue($this->controller instanceof ConfigEntityStorage, 'The block storage is loaded.');
// Run each test method in the same installation.
$this->createTests();
$this->loadTests();
$this->deleteTests();
}
/**
* Tests the creation of blocks.
*/
protected function createTests() {
// Attempt to create a block without a plugin.
try {
$entity = $this->controller->create(array());
$entity->getPlugin();
$this->fail('A block without a plugin was created with no exception thrown.');
}
catch (PluginException $e) {
$this->assertEqual('The block \'\' did not specify a plugin.', $e->getMessage(), 'An exception was thrown when a block was created without a plugin.');
}
// Create a block with only required values.
$entity = $this->controller->create(array(
'id' => 'test_block',
'theme' => 'stark',
'plugin' => 'test_html',
));
$entity->save();
$this->assertTrue($entity instanceof Block, 'The newly created entity is a Block.');
// Verify all of the block properties.
$actual_properties = $this->config('block.block.test_block')->get();
$this->assertTrue(!empty($actual_properties['uuid']), 'The block UUID is set.');
unset($actual_properties['uuid']);
// Ensure that default values are filled in.
$expected_properties = array(
'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
'status' => TRUE,
'dependencies' => array('module' => array('block_test'), 'theme' => array('stark')),
'id' => 'test_block',
'theme' => 'stark',
'region' => '-1',
'weight' => NULL,
'provider' => NULL,
'plugin' => 'test_html',
'settings' => array(
'id' => 'test_html',
'label' => '',
'provider' => 'block_test',
'label_display' => BlockInterface::BLOCK_LABEL_VISIBLE,
),
'visibility' => array(),
);
$this->assertIdentical($actual_properties, $expected_properties);
$this->assertTrue($entity->getPlugin() instanceof TestHtmlBlock, 'The entity has an instance of the correct block plugin.');
}
/**
* Tests the loading of blocks.
*/
protected function loadTests() {
$entity = $this->controller->load('test_block');
$this->assertTrue($entity instanceof Block, 'The loaded entity is a Block.');
// Verify several properties of the block.
$this->assertEqual($entity->getRegion(), '-1');
$this->assertTrue($entity->status());
$this->assertEqual($entity->getTheme(), 'stark');
$this->assertTrue($entity->uuid());
}
/**
* Tests the deleting of blocks.
*/
protected function deleteTests() {
$entity = $this->controller->load('test_block');
// Ensure that the storage isn't currently empty.
$config_storage = $this->container->get('config.storage');
$config = $config_storage->listAll('block.block.');
$this->assertFalse(empty($config), 'There are blocks in config storage.');
// Delete the block.
$entity->delete();
// Ensure that the storage is now empty.
$config = $config_storage->listAll('block.block.');
$this->assertTrue(empty($config), 'There are no blocks in config storage.');
}
/**
* Tests the installation of default blocks.
*/
public function testDefaultBlocks() {
\Drupal::service('theme_handler')->install(['classy']);
$entities = $this->controller->loadMultiple();
$this->assertTrue(empty($entities), 'There are no blocks initially.');
// Install the block_test.module, so that its default config is installed.
$this->installConfig(array('block_test'));
$entities = $this->controller->loadMultiple();
$entity = reset($entities);
$this->assertEqual($entity->id(), 'test_block', 'The default test block was loaded.');
}
}

View file

@ -0,0 +1,328 @@
<?php
namespace Drupal\Tests\block\Kernel;
use Drupal\Component\Utility\Html;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\LanguageInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\block\Entity\Block;
/**
* Tests the block view builder.
*
* @group block
*/
class BlockViewBuilderTest extends KernelTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('block', 'block_test', 'system', 'user');
/**
* The block being tested.
*
* @var \Drupal\block\Entity\BlockInterface
*/
protected $block;
/**
* The block storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $controller;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->controller = $this->container
->get('entity_type.manager')
->getStorage('block');
\Drupal::state()->set('block_test.content', 'Llamas &gt; unicorns!');
// Create a block with only required values.
$this->block = $this->controller->create(array(
'id' => 'test_block',
'theme' => 'stark',
'plugin' => 'test_cache',
));
$this->block->save();
$this->container->get('cache.render')->deleteAll();
$this->renderer = $this->container->get('renderer');
}
/**
* Tests the rendering of blocks.
*/
public function testBasicRendering() {
\Drupal::state()->set('block_test.content', '');
$entity = $this->controller->create(array(
'id' => 'test_block1',
'theme' => 'stark',
'plugin' => 'test_html',
));
$entity->save();
// Test the rendering of a block.
$entity = Block::load('test_block1');
$output = entity_view($entity, 'block');
$expected = array();
$expected[] = '<div id="block-test-block1">';
$expected[] = ' ';
$expected[] = ' ';
$expected[] = ' ';
$expected[] = ' </div>';
$expected[] = '';
$expected_output = implode("\n", $expected);
$this->assertEqual($this->renderer->renderRoot($output), $expected_output);
// Reset the HTML IDs so that the next render is not affected.
Html::resetSeenIds();
// Test the rendering of a block with a given title.
$entity = $this->controller->create(array(
'id' => 'test_block2',
'theme' => 'stark',
'plugin' => 'test_html',
'settings' => array(
'label' => 'Powered by Bananas',
),
));
$entity->save();
$output = entity_view($entity, 'block');
$expected = array();
$expected[] = '<div id="block-test-block2">';
$expected[] = ' ';
$expected[] = ' <h2>Powered by Bananas</h2>';
$expected[] = ' ';
$expected[] = ' ';
$expected[] = ' </div>';
$expected[] = '';
$expected_output = implode("\n", $expected);
$this->assertEqual($this->renderer->renderRoot($output), $expected_output);
}
/**
* Tests block render cache handling.
*/
public function testBlockViewBuilderCache() {
// Verify cache handling for a non-empty block.
$this->verifyRenderCacheHandling();
// Create an empty block.
$this->block = $this->controller->create(array(
'id' => 'test_block',
'theme' => 'stark',
'plugin' => 'test_cache',
));
$this->block->save();
\Drupal::state()->set('block_test.content', NULL);
// Verify cache handling for an empty block.
$this->verifyRenderCacheHandling();
}
/**
* Verifies render cache handling of the block being tested.
*
* @see ::testBlockViewBuilderCache()
*/
protected function verifyRenderCacheHandling() {
// Force a request via GET so we can test the render cache.
$request = \Drupal::request();
$request_method = $request->server->get('REQUEST_METHOD');
$request->setMethod('GET');
// Test that a cache entry is created.
$build = $this->getBlockRenderArray();
$cid = 'entity_view:block:test_block:' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
$this->renderer->renderRoot($build);
$this->assertTrue($this->container->get('cache.render')->get($cid), 'The block render element has been cached.');
// Re-save the block and check that the cache entry has been deleted.
$this->block->save();
$this->assertFalse($this->container->get('cache.render')->get($cid), 'The block render cache entry has been cleared when the block was saved.');
// Rebuild the render array (creating a new cache entry in the process) and
// delete the block to check the cache entry is deleted.
unset($build['#printed']);
// Re-add the block because \Drupal\block\BlockViewBuilder::buildBlock()
// removes it.
$build['#block'] = $this->block;
$this->renderer->renderRoot($build);
$this->assertTrue($this->container->get('cache.render')->get($cid), 'The block render element has been cached.');
$this->block->delete();
$this->assertFalse($this->container->get('cache.render')->get($cid), 'The block render cache entry has been cleared when the block was deleted.');
// Restore the previous request method.
$request->setMethod($request_method);
}
/**
* Tests block view altering.
*
* @see hook_block_view_alter()
* @see hook_block_view_BASE_BLOCK_ID_alter()
*/
public function testBlockViewBuilderViewAlter() {
// Establish baseline.
$build = $this->getBlockRenderArray();
$this->setRawContent((string) $this->renderer->renderRoot($build));
$this->assertIdentical(trim((string) $this->cssSelect('div')[0]), 'Llamas > unicorns!');
// Enable the block view alter hook that adds a foo=bar attribute.
\Drupal::state()->set('block_test_view_alter_suffix', TRUE);
Cache::invalidateTags($this->block->getCacheTagsToInvalidate());
$build = $this->getBlockRenderArray();
$this->setRawContent((string) $this->renderer->renderRoot($build));
$this->assertIdentical(trim((string) $this->cssSelect('[foo=bar]')[0]), 'Llamas > unicorns!');
\Drupal::state()->set('block_test_view_alter_suffix', FALSE);
\Drupal::state()->set('block_test.content', NULL);
Cache::invalidateTags($this->block->getCacheTagsToInvalidate());
// Advanced: cached block, but an alter hook adds a #pre_render callback to
// alter the eventual content.
\Drupal::state()->set('block_test_view_alter_append_pre_render_prefix', TRUE);
$build = $this->getBlockRenderArray();
$this->assertFalse(isset($build['#prefix']), 'The appended #pre_render callback has not yet run before rendering.');
$this->assertIdentical((string) $this->renderer->renderRoot($build), 'Hiya!<br>');
$this->assertTrue(isset($build['#prefix']) && $build['#prefix'] === 'Hiya!<br>', 'A cached block without content is altered.');
}
/**
* Tests block build altering.
*
* @see hook_block_build_alter()
* @see hook_block_build_BASE_BLOCK_ID_alter()
*/
public function testBlockViewBuilderBuildAlter() {
// Force a request via GET so we can test the render cache.
$request = \Drupal::request();
$request_method = $request->server->get('REQUEST_METHOD');
$request->setMethod('GET');
$default_keys = ['entity_view', 'block', 'test_block'];
$default_contexts = [];
$default_tags = ['block_view', 'config:block.block.test_block'];
$default_max_age = Cache::PERMANENT;
// hook_block_build_alter() adds an additional cache key.
$alter_add_key = $this->randomMachineName();
\Drupal::state()->set('block_test_block_alter_cache_key', $alter_add_key);
$this->assertBlockRenderedWithExpectedCacheability(array_merge($default_keys, [$alter_add_key]), $default_contexts, $default_tags, $default_max_age);
\Drupal::state()->set('block_test_block_alter_cache_key', NULL);
// hook_block_build_alter() adds an additional cache context.
$alter_add_context = 'url.query_args:' . $this->randomMachineName();
\Drupal::state()->set('block_test_block_alter_cache_context', $alter_add_context);
$this->assertBlockRenderedWithExpectedCacheability($default_keys, Cache::mergeContexts($default_contexts, [$alter_add_context]), $default_tags, $default_max_age);
\Drupal::state()->set('block_test_block_alter_cache_context', NULL);
// hook_block_build_alter() adds an additional cache tag.
$alter_add_tag = $this->randomMachineName();
\Drupal::state()->set('block_test_block_alter_cache_tag', $alter_add_tag);
$this->assertBlockRenderedWithExpectedCacheability($default_keys, $default_contexts, Cache::mergeTags($default_tags, [$alter_add_tag]), $default_max_age);
\Drupal::state()->set('block_test_block_alter_cache_tag', NULL);
// hook_block_build_alter() alters the max-age.
$alter_max_age = 300;
\Drupal::state()->set('block_test_block_alter_cache_max_age', $alter_max_age);
$this->assertBlockRenderedWithExpectedCacheability($default_keys, $default_contexts, $default_tags, $alter_max_age);
\Drupal::state()->set('block_test_block_alter_cache_max_age', NULL);
// hook_block_build_alter() alters cache keys, contexts, tags and max-age.
\Drupal::state()->set('block_test_block_alter_cache_key', $alter_add_key);
\Drupal::state()->set('block_test_block_alter_cache_context', $alter_add_context);
\Drupal::state()->set('block_test_block_alter_cache_tag', $alter_add_tag);
\Drupal::state()->set('block_test_block_alter_cache_max_age', $alter_max_age);
$this->assertBlockRenderedWithExpectedCacheability(array_merge($default_keys, [$alter_add_key]), Cache::mergeContexts($default_contexts, [$alter_add_context]), Cache::mergeTags($default_tags, [$alter_add_tag]), $alter_max_age);
\Drupal::state()->set('block_test_block_alter_cache_key', NULL);
\Drupal::state()->set('block_test_block_alter_cache_context', NULL);
\Drupal::state()->set('block_test_block_alter_cache_tag', NULL);
\Drupal::state()->set('block_test_block_alter_cache_max_age', NULL);
// hook_block_build_alter() sets #create_placeholder.
foreach ([TRUE, FALSE] as $value) {
\Drupal::state()->set('block_test_block_alter_create_placeholder', $value);
$build = $this->getBlockRenderArray();
$this->assertTrue(isset($build['#create_placeholder']));
$this->assertIdentical($value, $build['#create_placeholder']);
}
\Drupal::state()->set('block_test_block_alter_create_placeholder', NULL);
// Restore the previous request method.
$request->setMethod($request_method);
}
/**
* Asserts that a block is built/rendered/cached with expected cacheability.
*
* @param string[] $expected_keys
* The expected cache keys.
* @param string[] $expected_contexts
* The expected cache contexts.
* @param string[] $expected_tags
* The expected cache tags.
* @param int $expected_max_age
* The expected max-age.
*/
protected function assertBlockRenderedWithExpectedCacheability(array $expected_keys, array $expected_contexts, array $expected_tags, $expected_max_age) {
$required_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
// Check that the expected cacheability metadata is present in:
// - the built render array;
$this->pass('Built render array');
$build = $this->getBlockRenderArray();
$this->assertIdentical($expected_keys, $build['#cache']['keys']);
$this->assertIdentical($expected_contexts, $build['#cache']['contexts']);
$this->assertIdentical($expected_tags, $build['#cache']['tags']);
$this->assertIdentical($expected_max_age, $build['#cache']['max-age']);
$this->assertFalse(isset($build['#create_placeholder']));
// - the rendered render array;
$this->pass('Rendered render array');
$this->renderer->renderRoot($build);
// - the render cache item.
$this->pass('Render cache item');
$final_cache_contexts = Cache::mergeContexts($expected_contexts, $required_cache_contexts);
$cid = implode(':', $expected_keys) . ':' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys($final_cache_contexts)->getKeys());
$cache_item = $this->container->get('cache.render')->get($cid);
$this->assertTrue($cache_item, 'The block render element has been cached with the expected cache ID.');
$this->assertIdentical(Cache::mergeTags($expected_tags, ['rendered']), $cache_item->tags);
$this->assertIdentical($final_cache_contexts, $cache_item->data['#cache']['contexts']);
$this->assertIdentical($expected_tags, $cache_item->data['#cache']['tags']);
$this->assertIdentical($expected_max_age, $cache_item->data['#cache']['max-age']);
$this->container->get('cache.render')->delete($cid);
}
/**
* Get a fully built render array for a block.
*
* @return array
* The render array.
*/
protected function getBlockRenderArray() {
return $this->container->get('entity_type.manager')->getViewBuilder('block')->view($this->block, 'block');
}
}

View file

@ -0,0 +1,157 @@
<?php
namespace Drupal\Tests\block\Kernel\Migrate\d6;
use Drupal\block\Entity\Block;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
* Tests migration of blocks to configuration entities.
*
* @group migrate_drupal_6
*/
class MigrateBlockTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'block',
'views',
'comment',
'menu_ui',
'block_content',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['block_content']);
$this->installEntitySchema('block_content');
// Set Bartik and Seven as the default public and admin theme.
$config = $this->config('system.theme');
$config->set('default', 'bartik');
$config->set('admin', 'seven');
$config->save();
// Install one of D8's test themes.
\Drupal::service('theme_handler')->install(['test_theme']);
$this->executeMigrations([
'd6_filter_format',
'block_content_type',
'block_content_body_field',
'd6_custom_block',
'menu',
'd6_user_role',
'd6_block',
]);
block_rebuild();
}
/**
* Asserts various aspects of a block.
*
* @param string $id
* The block ID.
* @param array $visibility
* The block visibility settings.
* @param string $region
* The display region.
* @param string $theme
* The theme.
* @param string $weight
* The block weight.
* @param string $label
* The block label.
* @param string $label_display
* The block label display setting.
* @param bool $status
* (optional) Whether the block is expected to be enabled.
*/
public function assertEntity($id, $visibility, $region, $theme, $weight, $label, $label_display, $status = TRUE) {
$block = Block::load($id);
$this->assertTrue($block instanceof Block);
$this->assertSame($visibility, $block->getVisibility());
$this->assertSame($region, $block->getRegion());
$this->assertSame($theme, $block->getTheme());
$this->assertSame($weight, $block->getWeight());
$this->assertSame($status, $block->status());
$config = $this->config('block.block.' . $id);
$this->assertSame($label, $config->get('settings.label'));
$this->assertSame($label_display, $config->get('settings.label_display'));
}
/**
* Tests the block migration.
*/
public function testBlockMigration() {
$blocks = Block::loadMultiple();
$this->assertIdentical(9, count($blocks));
// User blocks
$visibility = [];
$visibility['request_path']['id'] = 'request_path';
$visibility['request_path']['negate'] = TRUE;
$visibility['request_path']['pages'] = "<front>\n/node/1\n/blog/*";
$this->assertEntity('user', $visibility, 'sidebar_first', 'bartik', 0, '', '0');
$visibility = [];
$this->assertEntity('user_1', $visibility, 'sidebar_first', 'bartik', 0, '', '0');
$visibility['user_role']['id'] = 'user_role';
$roles['authenticated'] = 'authenticated';
$visibility['user_role']['roles'] = $roles;
$context_mapping['user'] = '@user.current_user_context:current_user';
$visibility['user_role']['context_mapping'] = $context_mapping;
$visibility['user_role']['negate'] = FALSE;
$this->assertEntity('user_2', $visibility, 'sidebar_second', 'bartik', -9, '', '0');
$visibility = [];
$visibility['user_role']['id'] = 'user_role';
$visibility['user_role']['roles'] = [
'migrate_test_role_1' => 'migrate_test_role_1'
];
$context_mapping['user'] = '@user.current_user_context:current_user';
$visibility['user_role']['context_mapping'] = $context_mapping;
$visibility['user_role']['negate'] = FALSE;
$this->assertEntity('user_3', $visibility, 'sidebar_second', 'bartik', -6, '', '0');
// Check system block
$visibility = [];
$visibility['request_path']['id'] = 'request_path';
$visibility['request_path']['negate'] = TRUE;
$visibility['request_path']['pages'] = '/node/1';
$this->assertEntity('system', $visibility, 'footer_fifth', 'bartik', -5, '', '0');
// Check menu blocks
$visibility = [];
$this->assertEntity('menu', $visibility, 'header', 'bartik', -5, '', '0');
// Check custom blocks
$visibility['request_path']['id'] = 'request_path';
$visibility['request_path']['negate'] = FALSE;
$visibility['request_path']['pages'] = '<front>';
$this->assertEntity('block', $visibility, 'content', 'bartik', 0, 'Static Block', 'visible');
$visibility['request_path']['id'] = 'request_path';
$visibility['request_path']['negate'] = FALSE;
$visibility['request_path']['pages'] = '/node';
// bluemarine does not exist in Drupal 8 and the d6_block migration defines
// no mapping for its regions, so this block should have been defaulted
// to the 'content' region.
$this->assertEntity('block_1', $visibility, 'content', 'bluemarine', -4, 'Another Static Block', 'visible');
$visibility = [];
$this->assertEntity('block_2', $visibility, 'right', 'test_theme', -7, '', '0');
// Custom block with php code is not migrated.
$block = Block::load('block_3');
$this->assertFalse($block instanceof Block);
}
}

View file

@ -0,0 +1,169 @@
<?php
namespace Drupal\Tests\block\Kernel\Migrate\d7;
use Drupal\block\Entity\Block;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
* Tests migration of blocks to configuration entities.
*
* @group block
*/
class MigrateBlockTest extends MigrateDrupal7TestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'block',
'views',
'comment',
'menu_ui',
'block_content',
'node',
'text',
'filter',
'user',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(static::$modules);
$this->installEntitySchema('block_content');
// Set Bartik and Seven as the default public and admin theme.
$config = $this->config('system.theme');
$config->set('default', 'bartik');
$config->set('admin', 'seven');
$config->save();
// Install one of D8's test themes.
\Drupal::service('theme_handler')->install(['bartik']);
$this->executeMigrations([
'd7_filter_format',
'd7_user_role',
'block_content_type',
'block_content_body_field',
'd7_custom_block',
'd7_block',
]);
block_rebuild();
}
/**
* Asserts various aspects of a block.
*
* @param string $id
* The block ID.
* @param string $plugin_id
* The block's plugin ID.
* @param array $roles
* Role IDs the block is expected to have.
* @param string $pages
* The list of pages on which the block should appear.
* @param string $region
* The display region.
* @param string $theme
* The theme.
* @param string $weight
* The block weight.
* @param string $label
* The block label.
* @param string $label_display
* The block label display setting.
* @param bool $status
* (optional) Whether the block is expected to be enabled.
*/
public function assertEntity($id, $plugin_id, array $roles, $pages, $region, $theme, $weight, $label, $label_display, $status = TRUE) {
$block = Block::load($id);
$this->assertTrue($block instanceof Block);
/** @var \Drupal\block\BlockInterface $block */
$this->assertSame($plugin_id, $block->getPluginId());
$visibility = $block->getVisibility();
if ($roles) {
$this->assertSame($roles, array_values($visibility['user_role']['roles']));
$this->assertSame('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
}
if ($pages) {
$this->assertSame($pages, $visibility['request_path']['pages']);
}
$this->assertSame($region, $block->getRegion());
$this->assertSame($theme, $block->getTheme());
$this->assertSame($weight, $block->getWeight());
$this->assertSame($status, $block->status());
$config = $this->config('block.block.' . $id);
$this->assertSame($label, $config->get('settings.label'));
$this->assertSame($label_display, $config->get('settings.label_display'));
}
/**
* Tests the block migration.
*/
public function testBlockMigration() {
$this->assertEntity('bartik_system_main', 'system_main_block', [], '', 'content', 'bartik', 0, '', '0');
$this->assertEntity('bartik_search_form', 'search_form_block', [], '', 'sidebar_first', 'bartik', -1, '', '0');
$this->assertEntity('bartik_user_login', 'user_login_block', [], '', 'sidebar_first', 'bartik', 0, '', '0');
$this->assertEntity('bartik_system_powered_by', 'system_powered_by_block', [], '', 'footer_fifth', 'bartik', 10, '', '0');
$this->assertEntity('seven_system_main', 'system_main_block', [], '', 'content', 'seven', 0, '', '0');
$this->assertEntity('seven_user_login', 'user_login_block', [], '', 'content', 'seven', 10, '', '0');
// The d7_custom_block migration should have migrated a block containing a
// mildly amusing limerick. We'll need its UUID to determine
// bartik_block_1's plugin ID.
$uuid = BlockContent::load(1)->uuid();
$this->assertEntity('bartik_block_1', 'block_content:' . $uuid, ['authenticated'], '', 'highlighted', 'bartik', 0, 'Mildly amusing limerick of the day', 'visible');
// Assert that disabled blocks (or enabled blocks whose plugin IDs could
// be resolved) did not migrate.
$non_existent_blocks = [
'bartik_system_navigation',
'bartik_system_help',
'seven_user_new',
'seven_search_form',
'bartik_comment_recent',
'bartik_node_syndicate',
'bartik_node_recent',
'bartik_shortcut_shortcuts',
'bartik_system_management',
'bartik_system_user-menu',
'bartik_system_main-menu',
'bartik_user_new',
'bartik_user_online',
'seven_comment_recent',
'seven_node_syndicate',
'seven_shortcut_shortcuts',
'seven_system_powered-by',
'seven_system_navigation',
'seven_system_management',
'seven_system_user-menu',
'seven_system_main-menu',
'seven_user_online',
'bartik_blog_recent',
'bartik_book_navigation',
'bartik_locale_language',
'bartik_forum_active',
'bartik_forum_new',
'seven_blog_recent',
'seven_book_navigation',
'seven_locale_language',
'seven_forum_active',
'seven_forum_new',
'bartik_menu_menu-test-menu',
'bartik_statistics_popular',
'seven_menu_menu-test-menu',
'seven_statistics_popular',
'seven_block_1',
];
$this->assertTrue(empty(Block::loadMultiple($non_existent_blocks)));
}
}

View file

@ -0,0 +1,127 @@
<?php
namespace Drupal\Tests\block\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests block source plugin.
*
* @covers \Drupal\block\Plugin\migrate\source\Block
* @group block
*/
class BlockTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
// The source data.
$tests[0]['source_data']['blocks'] = [
[
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
],
[
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
],
];
$tests[0]['source_data']['blocks_roles'] = [
[
'module' => 'block',
'delta' => 1,
'rid' => 2,
],
[
'module' => 'block',
'delta' => 2,
'rid' => 2,
],
[
'module' => 'block',
'delta' => 2,
'rid' => 100,
],
];
$tests[0]['source_data']['role'] = [
[
'rid' => 2,
'name' => 'authenticated user',
],
];
$tests[0]['source_data']['system'] = [
[
'filename' => 'modules/system/system.module',
'name' => 'system',
'type' => 'module',
'owner' => '',
'status' => '1',
'throttle' => '0',
'bootstrap' => '0',
'schema_version' => '6055',
'weight' => '0',
'info' => 'a:0:{}',
]
];
// The expected results.
$tests[0]['expected_data'] = [
[
'bid' => 1,
'module' => 'block',
'delta' => '1',
'theme' => 'garland',
'status' => 1,
'weight' => 0,
'region' => 'left',
'visibility' => 0,
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
'roles' => [2]
],
[
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'status' => 1,
'weight' => 5,
'region' => 'right',
'visibility' => 0,
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
'roles' => [2]
],
];
return $tests;
}
}

View file

@ -0,0 +1,103 @@
<?php
namespace Drupal\Tests\block\Unit;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Tests\Core\Plugin\Fixtures\TestConfigurablePlugin;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\block\Entity\Block
* @group block
*/
class BlockConfigEntityUnitTest extends UnitTestCase {
/**
* The entity type used for testing.
*
* @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityType;
/**
* The entity manager used for testing.
*
* @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityManager;
/**
* The ID of the type of the entity under test.
*
* @var string
*/
protected $entityTypeId;
/**
* The UUID generator used for testing.
*
* @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $uuid;
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->entityTypeId = $this->randomMachineName();
$this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
$this->entityType->expects($this->any())
->method('getProvider')
->will($this->returnValue('block'));
$this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
$this->entityManager->expects($this->any())
->method('getDefinition')
->with($this->entityTypeId)
->will($this->returnValue($this->entityType));
$this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
$container = new ContainerBuilder();
$container->set('entity.manager', $this->entityManager);
$container->set('uuid', $this->uuid);
\Drupal::setContainer($container);
}
/**
* @covers ::calculateDependencies
*/
public function testCalculateDependencies() {
$values = array('theme' => 'stark');
// Mock the entity under test so that we can mock getPluginCollections().
$entity = $this->getMockBuilder('\Drupal\block\Entity\Block')
->setConstructorArgs(array($values, $this->entityTypeId))
->setMethods(array('getPluginCollections'))
->getMock();
// Create a configurable plugin that would add a dependency.
$instance_id = $this->randomMachineName();
$instance = new TestConfigurablePlugin(array(), $instance_id, array('provider' => 'test'));
// Create a plugin collection to contain the instance.
$plugin_collection = $this->getMockBuilder('\Drupal\Core\Plugin\DefaultLazyPluginCollection')
->disableOriginalConstructor()
->setMethods(array('get'))
->getMock();
$plugin_collection->expects($this->atLeastOnce())
->method('get')
->with($instance_id)
->will($this->returnValue($instance));
$plugin_collection->addInstanceId($instance_id);
// Return the mocked plugin collection.
$entity->expects($this->once())
->method('getPluginCollections')
->will($this->returnValue(array($plugin_collection)));
$dependencies = $entity->calculateDependencies()->getDependencies();
$this->assertContains('test', $dependencies['module']);
$this->assertContains('stark', $dependencies['theme']);
}
}

View file

@ -0,0 +1,129 @@
<?php
namespace Drupal\Tests\block\Unit;
use Drupal\block\BlockForm;
use Drupal\Core\Plugin\PluginFormFactoryInterface;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\block\BlockForm
* @group block
*/
class BlockFormTest extends UnitTestCase {
/**
* The condition plugin manager.
*
* @var \Drupal\Core\Executable\ExecutableManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $conditionManager;
/**
* The block storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $storage;
/**
* The language manager service.
*
* @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $language;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeHandler;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityManager;
/**
* The mocked context repository.
*
* @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $contextRepository;
/**
* The plugin form manager.
*
* @var \Drupal\Core\Plugin\PluginFormFactoryInterface|\Prophecy\Prophecy\ProphecyInterface
*/
protected $pluginFormFactory;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->conditionManager = $this->getMock('Drupal\Core\Executable\ExecutableManagerInterface');
$this->language = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
$this->contextRepository = $this->getMock('Drupal\Core\Plugin\Context\ContextRepositoryInterface');
$this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$this->storage = $this->getMock('Drupal\Core\Config\Entity\ConfigEntityStorageInterface');
$this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
$this->entityManager->expects($this->any())
->method('getStorage')
->will($this->returnValue($this->storage));
$this->pluginFormFactory = $this->prophesize(PluginFormFactoryInterface::class);
}
/**
* Tests the unique machine name generator.
*
* @see \Drupal\block\BlockForm::getUniqueMachineName()
*/
public function testGetUniqueMachineName() {
$blocks = array();
$blocks['test'] = $this->getBlockMockWithMachineName('test');
$blocks['other_test'] = $this->getBlockMockWithMachineName('other_test');
$blocks['other_test_1'] = $this->getBlockMockWithMachineName('other_test');
$blocks['other_test_2'] = $this->getBlockMockWithMachineName('other_test');
$query = $this->getMock('Drupal\Core\Entity\Query\QueryInterface');
$query->expects($this->exactly(5))
->method('condition')
->will($this->returnValue($query));
$query->expects($this->exactly(5))
->method('execute')
->will($this->returnValue(array('test', 'other_test', 'other_test_1', 'other_test_2')));
$this->storage->expects($this->exactly(5))
->method('getQuery')
->will($this->returnValue($query));
$block_form_controller = new BlockForm($this->entityManager, $this->conditionManager, $this->contextRepository, $this->language, $this->themeHandler, $this->pluginFormFactory->reveal());
// Ensure that the block with just one other instance gets the next available
// name suggestion.
$this->assertEquals('test_2', $block_form_controller->getUniqueMachineName($blocks['test']));
// Ensure that the block with already three instances (_0, _1, _2) gets the
// 4th available name.
$this->assertEquals('other_test_3', $block_form_controller->getUniqueMachineName($blocks['other_test']));
$this->assertEquals('other_test_3', $block_form_controller->getUniqueMachineName($blocks['other_test_1']));
$this->assertEquals('other_test_3', $block_form_controller->getUniqueMachineName($blocks['other_test_2']));
// Ensure that a block without an instance yet gets the suggestion as
// unique machine name.
$last_block = $this->getBlockMockWithMachineName('last_test');
$this->assertEquals('last_test', $block_form_controller->getUniqueMachineName($last_block));
}
}

View file

@ -0,0 +1,194 @@
<?php
/**
* @file
* Contains \Drupal\Tests\block\Unit\BlockRepositoryTest.
*/
namespace Drupal\Tests\block\Unit;
use Drupal\block\BlockRepository;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\block\BlockRepository
* @group block
*/
class BlockRepositoryTest extends UnitTestCase {
/**
* @var \Drupal\block\BlockRepository
*/
protected $blockRepository;
/**
* @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $blockStorage;
/**
* @var string
*/
protected $theme;
/**
* @var \Drupal\Core\Plugin\Context\ContextHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $contextHandler;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$active_theme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
$this->theme = $this->randomMachineName();
$active_theme->expects($this->atLeastOnce())
->method('getName')
->willReturn($this->theme);
$active_theme->expects($this->atLeastOnce())
->method('getRegions')
->willReturn([
'top',
'center',
'bottom',
]);
$theme_manager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
$theme_manager->expects($this->atLeastOnce())
->method('getActiveTheme')
->will($this->returnValue($active_theme));
$this->contextHandler = $this->getMock('Drupal\Core\Plugin\Context\ContextHandlerInterface');
$this->blockStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
$entity_manager->expects($this->any())
->method('getStorage')
->willReturn($this->blockStorage);
$this->blockRepository = new BlockRepository($entity_manager, $theme_manager, $this->contextHandler);
}
/**
* Tests the retrieval of block entities.
*
* @covers ::getVisibleBlocksPerRegion
*
* @dataProvider providerBlocksConfig
*/
public function testGetVisibleBlocksPerRegion(array $blocks_config, array $expected_blocks) {
$blocks = [];
foreach ($blocks_config as $block_id => $block_config) {
$block = $this->getMock('Drupal\block\BlockInterface');
$block->expects($this->once())
->method('access')
->will($this->returnValue($block_config[0]));
$block->expects($block_config[0] ? $this->atLeastOnce() : $this->never())
->method('getRegion')
->willReturn($block_config[1]);
$block->expects($this->any())
->method('label')
->willReturn($block_id);
$block->expects($this->any())
->method('getWeight')
->willReturn($block_config[2]);
$blocks[$block_id] = $block;
}
$this->blockStorage->expects($this->once())
->method('loadByProperties')
->with(['theme' => $this->theme])
->willReturn($blocks);
$result = [];
$cacheable_metadata = [];
foreach ($this->blockRepository->getVisibleBlocksPerRegion($cacheable_metadata) as $region => $resulting_blocks) {
$result[$region] = [];
foreach ($resulting_blocks as $plugin_id => $block) {
$result[$region][] = $plugin_id;
}
}
$this->assertEquals($expected_blocks, $result);
}
public function providerBlocksConfig() {
$blocks_config = array(
'block1' => array(
AccessResult::allowed(), 'top', 0
),
// Test a block without access.
'block2' => array(
AccessResult::forbidden(), 'bottom', 0
),
// Test some blocks in the same region with specific weight.
'block4' => array(
AccessResult::allowed(), 'bottom', 5
),
'block3' => array(
AccessResult::allowed(), 'bottom', 5
),
'block5' => array(
AccessResult::allowed(), 'bottom', -5
),
);
$test_cases = [];
$test_cases[] = [$blocks_config,
[
'top' => ['block1'],
'center' => [],
'bottom' => ['block5', 'block3', 'block4'],
]
];
return $test_cases;
}
/**
* Tests the retrieval of block entities that are context-aware.
*
* @covers ::getVisibleBlocksPerRegion
*/
public function testGetVisibleBlocksPerRegionWithContext() {
$block = $this->getMock('Drupal\block\BlockInterface');
$block->expects($this->once())
->method('access')
->willReturn(AccessResult::allowed()->addCacheTags(['config:block.block.block_id']));
$block->expects($this->once())
->method('getRegion')
->willReturn('top');
$blocks['block_id'] = $block;
$this->blockStorage->expects($this->once())
->method('loadByProperties')
->with(['theme' => $this->theme])
->willReturn($blocks);
$result = [];
$cacheable_metadata = [];
foreach ($this->blockRepository->getVisibleBlocksPerRegion($cacheable_metadata) as $region => $resulting_blocks) {
$result[$region] = [];
foreach ($resulting_blocks as $plugin_id => $block) {
$result[$region][] = $plugin_id;
}
}
$expected = [
'top' => [
'block_id',
],
'center' => [],
'bottom' => [],
];
$this->assertSame($expected, $result);
// Assert that the cacheable metadata from the block access results was
// collected.
$this->assertEquals(['config:block.block.block_id'], $cacheable_metadata['top']->getCacheTags());
}
}
interface TestContextAwareBlockInterface extends BlockPluginInterface, ContextAwarePluginInterface {
}

View file

@ -0,0 +1,85 @@
<?php
namespace Drupal\Tests\block\Unit;
use Drupal\Component\Utility\Html;
use Drupal\block\Controller\CategoryAutocompleteController;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
/**
* @coversDefaultClass \Drupal\block\Controller\CategoryAutocompleteController
* @group block
*/
class CategoryAutocompleteTest extends UnitTestCase {
/**
* The autocomplete controller.
*
* @var \Drupal\block\Controller\CategoryAutocompleteController
*/
protected $autocompleteController;
protected function setUp() {
$block_manager = $this->getMock('Drupal\Core\Block\BlockManagerInterface');
$block_manager->expects($this->any())
->method('getCategories')
->will($this->returnValue(array('Comment', 'Node', 'None & Such', 'User')));
$this->autocompleteController = new CategoryAutocompleteController($block_manager);
}
/**
* Tests the autocomplete method.
*
* @param string $string
* The string entered into the autocomplete.
* @param array $suggestions
* The array of expected suggestions.
*
* @see \Drupal\block\Controller\CategoryAutocompleteController::autocomplete()
*
* @dataProvider providerTestAutocompleteSuggestions
*/
public function testAutocompleteSuggestions($string, $suggestions) {
$suggestions = array_map(function ($suggestion) {
return array('value' => $suggestion, 'label' => Html::escape($suggestion));
}, $suggestions);
$result = $this->autocompleteController->autocomplete(new Request(array('q' => $string)));
$this->assertSame($suggestions, json_decode($result->getContent(), TRUE));
}
/**
* Data provider for testAutocompleteSuggestions().
*
* @return array
*/
public function providerTestAutocompleteSuggestions() {
$test_parameters = array();
$test_parameters[] = array(
'string' => 'Com',
'suggestions' => array(
'Comment',
),
);
$test_parameters[] = array(
'string' => 'No',
'suggestions' => array(
'Node',
'None & Such',
),
);
$test_parameters[] = array(
'string' => 'us',
'suggestions' => array(
'User',
),
);
$test_parameters[] = array(
'string' => 'Banana',
'suggestions' => array(),
);
return $test_parameters;
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace Drupal\Tests\block\Unit\Menu;
use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Tests block local tasks.
*
* @group block
*/
class BlockLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = array('block' => 'core/modules/block');
parent::setUp();
$config_factory = $this->getConfigFactoryStub(array('system.theme' => array(
'default' => 'test_c',
)));
$themes = array();
$themes['test_a'] = (object) array(
'status' => 1,
'info' => array(
'name' => 'test_a',
'hidden' => TRUE,
),
);
$themes['test_b'] = (object) array(
'status' => 1,
'info' => array(
'name' => 'test_b',
),
);
$themes['test_c'] = (object) array(
'status' => 1,
'info' => array(
'name' => 'test_c',
),
);
$theme_handler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
$theme_handler->expects($this->any())
->method('listInfo')
->will($this->returnValue($themes));
$theme_handler->expects($this->any())
->method('hasUi')
->willReturnMap([
['test_a', FALSE],
['test_b', TRUE],
['test_c', TRUE],
]);
$container = new ContainerBuilder();
$container->set('config.factory', $config_factory);
$container->set('theme_handler', $theme_handler);
$container->set('app.root', $this->root);
\Drupal::setContainer($container);
}
/**
* Tests the admin edit local task.
*/
public function testBlockAdminLocalTasks() {
$this->assertLocalTasks('entity.block.edit_form', array(array('entity.block.edit_form')));
}
/**
* Tests the block admin display local tasks.
*
* @dataProvider providerTestBlockAdminDisplay
*/
public function testBlockAdminDisplay($route, $expected) {
$this->assertLocalTasks($route, $expected);
}
/**
* Provides a list of routes to test.
*/
public function providerTestBlockAdminDisplay() {
return array(
array('block.admin_display', array(array('block.admin_display'), array('block.admin_display_theme:test_b', 'block.admin_display_theme:test_c'))),
array('block.admin_display_theme', array(array('block.admin_display'), array('block.admin_display_theme:test_b', 'block.admin_display_theme:test_c'))),
);
}
}

View file

@ -0,0 +1,264 @@
<?php
namespace Drupal\Tests\block\Unit\Plugin\DisplayVariant;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\Container;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\block\Plugin\DisplayVariant\BlockPageVariant
* @group block
*/
class BlockPageVariantTest extends UnitTestCase {
/**
* The block repository.
*
* @var \Drupal\block\BlockRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $blockRepository;
/**
* The block view builder.
*
* @var \Drupal\Core\Entity\EntityViewBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $blockViewBuilder;
/**
* The plugin context handler.
*
* @var \Drupal\Core\Plugin\Context\ContextHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $contextHandler;
/**
* Sets up a display variant plugin for testing.
*
* @param array $configuration
* An array of plugin configuration.
* @param array $definition
* The plugin definition array.
*
* @return \Drupal\block\Plugin\DisplayVariant\BlockPageVariant|\PHPUnit_Framework_MockObject_MockObject
* A mocked display variant plugin.
*/
public function setUpDisplayVariant($configuration = array(), $definition = array()) {
$container = new Container();
$cache_context_manager = $this->getMockBuilder('Drupal\Core\Cache\CacheContextsManager')
->disableOriginalConstructor()
->getMock();
$container->set('cache_contexts_manager', $cache_context_manager);
$cache_context_manager->expects($this->any())
->method('assertValidTokens')
->willReturn(TRUE);
\Drupal::setContainer($container);
$this->blockRepository = $this->getMock('Drupal\block\BlockRepositoryInterface');
$this->blockViewBuilder = $this->getMock('Drupal\Core\Entity\EntityViewBuilderInterface');
return $this->getMockBuilder('Drupal\block\Plugin\DisplayVariant\BlockPageVariant')
->setConstructorArgs(array($configuration, 'test', $definition, $this->blockRepository, $this->blockViewBuilder, ['config:block_list']))
->setMethods(array('getRegionNames'))
->getMock();
}
public function providerBuild() {
$blocks_config = array(
'block1' => array(
// region, is main content block, is messages block, is title block
'top', FALSE, FALSE, FALSE,
),
// Test multiple blocks in the same region.
'block2' => array(
'bottom', FALSE, FALSE, FALSE,
),
'block3' => array(
'bottom', FALSE, FALSE, FALSE,
),
// Test a block implementing MainContentBlockPluginInterface.
'block4' => array(
'center', TRUE, FALSE, FALSE,
),
// Test a block implementing MessagesBlockPluginInterface.
'block5' => array(
'center', FALSE, TRUE, FALSE,
),
// Test a block implementing TitleBlockPluginInterface.
'block6' => array(
'center', FALSE, FALSE, TRUE,
),
);
$test_cases = [];
$test_cases[] = [$blocks_config, 6,
[
'#cache' => [
'tags' => [
'config:block_list',
'route',
],
'contexts' => [],
'max-age' => -1,
],
'top' => [
'block1' => [],
'#sorted' => TRUE,
],
// The main content was rendered via a block.
'center' => [
'block4' => [],
'block5' => [],
'block6' => [],
'#sorted' => TRUE,
],
'bottom' => [
'block2' => [],
'block3' => [],
'#sorted' => TRUE,
],
],
];
unset($blocks_config['block5']);
$test_cases[] = [$blocks_config, 5,
[
'#cache' => [
'tags' => [
'config:block_list',
'route',
],
'contexts' => [],
'max-age' => -1,
],
'top' => [
'block1' => [],
'#sorted' => TRUE,
],
'center' => [
'block4' => [],
'block6' => [],
'#sorted' => TRUE,
],
'bottom' => [
'block2' => [],
'block3' => [],
'#sorted' => TRUE,
],
// The messages are rendered via the fallback in case there is no block
// rendering the main content.
'content' => [
'messages' => [
'#weight' => -1000,
'#type' => 'status_messages',
],
],
],
];
unset($blocks_config['block4']);
unset($blocks_config['block6']);
$test_cases[] = [$blocks_config, 3,
[
'#cache' => [
'tags' => [
'config:block_list',
'route',
],
'contexts' => [],
'max-age' => -1,
],
'top' => [
'block1' => [],
'#sorted' => TRUE,
],
'bottom' => [
'block2' => [],
'block3' => [],
'#sorted' => TRUE,
],
// The main content & messages are rendered via the fallback in case
// there are no blocks rendering them.
'content' => [
'system_main' => ['#markup' => 'Hello kittens!'],
'messages' => [
'#weight' => -1000,
'#type' => 'status_messages',
],
],
],
];
return $test_cases;
}
/**
* Tests the building of a full page variant.
*
* @covers ::build
*
* @dataProvider providerBuild
*/
public function testBuild(array $blocks_config, $visible_block_count, array $expected_render_array) {
$display_variant = $this->setUpDisplayVariant();
$display_variant->setMainContent(['#markup' => 'Hello kittens!']);
$blocks = ['top' => [], 'center' => [], 'bottom' => []];
$block_plugin = $this->getMock('Drupal\Core\Block\BlockPluginInterface');
$main_content_block_plugin = $this->getMock('Drupal\Core\Block\MainContentBlockPluginInterface');
$messages_block_plugin = $this->getMock('Drupal\Core\Block\MessagesBlockPluginInterface');
$title_block_plugin = $this->getMock('Drupal\Core\Block\TitleBlockPluginInterface');
foreach ($blocks_config as $block_id => $block_config) {
$block = $this->getMock('Drupal\block\BlockInterface');
$block->expects($this->any())
->method('getContexts')
->willReturn([]);
$block->expects($this->atLeastOnce())
->method('getPlugin')
->willReturn($block_config[1] ? $main_content_block_plugin : ($block_config[2] ? $messages_block_plugin : ($block_config[3] ? $title_block_plugin : $block_plugin)));
$blocks[$block_config[0]][$block_id] = $block;
}
$this->blockViewBuilder->expects($this->exactly($visible_block_count))
->method('view')
->will($this->returnValue(array()));
$this->blockRepository->expects($this->once())
->method('getVisibleBlocksPerRegion')
->willReturnCallback(function (&$cacheable_metadata) use ($blocks) {
$cacheable_metadata['top'] = (new CacheableMetadata())->addCacheTags(['route']);
return $blocks;
});
$value = $display_variant->build();
$this->assertSame($expected_render_array, $value);
}
/**
* Tests the building of a full page variant with no main content set.
*
* @covers ::build
*/
public function testBuildWithoutMainContent() {
$display_variant = $this->setUpDisplayVariant();
$this->blockRepository->expects($this->once())
->method('getVisibleBlocksPerRegion')
->willReturn([]);
$expected = [
'#cache' => [
'tags' => [
'config:block_list',
],
'contexts' => [],
'max-age' => -1,
],
'content' => [
'system_main' => [],
'messages' => [
'#weight' => -1000,
'#type' => 'status_messages',
],
],
];
$this->assertSame($expected, $display_variant->build());
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
use Drupal\block\Plugin\migrate\process\BlockRegion;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\block\Plugin\migrate\process\BlockRegion
* @group block
*/
class BlockRegionTest extends UnitTestCase {
/**
* Transforms a value through the block_region plugin.
*
* @param array $value
* The value to transform.
* @param \Drupal\migrate\Row|null $row
* (optional) The mocked row.
*
* @return array|string
* The transformed value.
*/
protected function transform(array $value, Row $row = NULL) {
$executable = $this->prophesize(MigrateExecutableInterface::class)->reveal();
if (empty($row)) {
$row = $this->prophesize(Row::class)->reveal();
}
$configuration = [
'map' => [
'bartik' => [
'bartik' => [
'triptych_first' => 'triptych_first',
'triptych_middle' => 'triptych_second',
'triptych_last' => 'triptych_third',
],
],
],
'default_value' => 'content',
];
$plugin = new BlockRegion($configuration, 'block_region', [], $configuration['map']['bartik']['bartik']);
return $plugin->transform($value, $executable, $row, 'foo');
}
/**
* If the source and destination themes are identical, the region should only
* be passed through if it actually exists in the destination theme.
*
* @covers ::transform
*/
public function testTransformSameThemeRegionExists() {
$this->assertSame('triptych_second', $this->transform(['bartik', 'bartik', 'triptych_middle']));
}
/**
* If the source and destination themes are identical, the region should be
* changed to 'content' if it doesn't exist in the destination theme.
*
* @covers ::transform
*/
public function testTransformSameThemeRegionNotExists() {
$this->assertSame('content', $this->transform(['bartik', 'bartik', 'footer']));
}
}

View file

@ -0,0 +1,83 @@
<?php
namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
use Drupal\block\Plugin\migrate\process\BlockVisibility;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
/**
* Tests the block_visibility process plugin.
*
* @coversDefaultClass \Drupal\block\Plugin\migrate\process\BlockVisibility
* @group block
*/
class BlockVisibilityTest extends MigrateProcessTestCase {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
$migration_plugin = $this->prophesize(MigrateProcessInterface::class);
$this->plugin = new BlockVisibility([], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
}
/**
* @covers ::transform
*/
public function testTransformNoData() {
$transformed_value = $this->plugin->transform([0, '', []], $this->migrateExecutable, $this->row, 'destinationproperty');
$this->assertEmpty($transformed_value);
}
/**
* @covers ::transform
*/
public function testTransformSinglePageWithFront() {
$visibility = $this->plugin->transform([0, '<front>', []], $this->migrateExecutable, $this->row, 'destinationproperty');
$this->assertSame('request_path', $visibility['request_path']['id']);
$this->assertTrue($visibility['request_path']['negate']);
$this->assertSame('<front>', $visibility['request_path']['pages']);
}
/**
* @covers ::transform
*/
public function testTransformMultiplePagesWithFront() {
$visibility = $this->plugin->transform([1, "foo\n/bar\rbaz\r\n<front>", []], $this->migrateExecutable, $this->row, 'destinationproperty');
$this->assertSame('request_path', $visibility['request_path']['id']);
$this->assertFalse($visibility['request_path']['negate']);
$this->assertSame("/foo\n/bar\n/baz\n<front>", $visibility['request_path']['pages']);
}
/**
* @covers ::transform
*/
public function testTransformPhpEnabled() {
$this->moduleHandler->moduleExists('php')->willReturn(TRUE);
$visibility = $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
$this->assertSame('php', $visibility['php']['id']);
$this->assertFalse($visibility['php']['negate']);
$this->assertSame('<?php', $visibility['php']['php']);
}
/**
* @covers ::transform
*/
public function testTransformPhpDisabled() {
$this->moduleHandler->moduleExists('php')->willReturn(FALSE);
$transformed_value = $this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
$this->assertEmpty($transformed_value);
}
}