Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
|
@ -5,4 +5,4 @@ package: Testing
|
|||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- block
|
||||
- drupal:block
|
||||
|
|
|
@ -4,9 +4,8 @@ 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\Plugin\Context\EntityContext;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
|
@ -47,9 +46,8 @@ class MultipleStaticContext implements ContextProviderInterface {
|
|||
public function getRuntimeContexts(array $unqualified_context_ids) {
|
||||
$current_user = $this->userStorage->load($this->account->id());
|
||||
|
||||
$context1 = new Context(new ContextDefinition('entity:user', 'User A'), $current_user);
|
||||
|
||||
$context2 = new Context(new ContextDefinition('entity:user', 'User B'), $current_user);
|
||||
$context1 = EntityContext::fromEntity($current_user, 'User A');
|
||||
$context2 = EntityContext::fromEntity($current_user, 'User B');
|
||||
|
||||
$cacheability = new CacheableMetadata();
|
||||
$cacheability->setCacheContexts(['user']);
|
||||
|
|
|
@ -17,7 +17,8 @@ class TestMultipleFormController extends ControllerBase {
|
|||
'form2' => $this->formBuilder()->buildForm('\Drupal\block_test\Form\FavoriteAnimalTestForm', $form_state),
|
||||
];
|
||||
|
||||
// Output all attached placeholders trough drupal_set_message(), so we can
|
||||
// Output all attached placeholders trough
|
||||
// \Drupal\Core\Messenger\MessengerInterface::addMessage(), so we can
|
||||
// see if there's only one in the tests.
|
||||
$post_render_callable = function ($elements) {
|
||||
$matches = [];
|
||||
|
@ -26,7 +27,7 @@ class TestMultipleFormController extends ControllerBase {
|
|||
$action_values = $matches[2];
|
||||
|
||||
foreach ($action_values as $action_value) {
|
||||
drupal_set_message('Form action: ' . $action_value);
|
||||
$this->messenger()->addStatus('Form action: ' . $action_value);
|
||||
}
|
||||
return $elements;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,11 @@ namespace Drupal\block_test\Form;
|
|||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form that performs favorite animal test.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FavoriteAnimalTestForm extends FormBase {
|
||||
|
||||
/**
|
||||
|
@ -20,7 +25,7 @@ class FavoriteAnimalTestForm extends FormBase {
|
|||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['favorite_animal'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Your favorite animal.')
|
||||
'#title' => $this->t('Your favorite animal.'),
|
||||
];
|
||||
|
||||
$form['submit_animal'] = [
|
||||
|
@ -35,7 +40,7 @@ class FavoriteAnimalTestForm extends FormBase {
|
|||
* {@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']]));
|
||||
$this->messenger()->addStatus($this->t('Your favorite animal is: @favorite_animal', ['@favorite_animal' => $form['favorite_animal']['#value']]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@ namespace Drupal\block_test\Form;
|
|||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form that performs base block form test.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TestForm extends FormBase {
|
||||
|
||||
/**
|
||||
|
@ -20,7 +25,7 @@ class TestForm extends FormBase {
|
|||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['email'] = [
|
||||
'#type' => 'email',
|
||||
'#title' => $this->t('Your .com email address.')
|
||||
'#title' => $this->t('Your .com email address.'),
|
||||
];
|
||||
|
||||
$form['show'] = [
|
||||
|
@ -44,7 +49,7 @@ class TestForm extends FormBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
drupal_set_message($this->t('Your email address is @email', ['@email' => $form['email']['#value']]));
|
||||
$this->messenger()->addStatus($this->t('Your email address is @email', ['@email' => $form['email']['#value']]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class TestContextAwareBlock extends BlockBase {
|
|||
*/
|
||||
protected function blockAccess(AccountInterface $account) {
|
||||
if ($this->getContextValue('user') instanceof UserInterface) {
|
||||
drupal_set_message('User context found.');
|
||||
$this->messenger()->addStatus('User context found.');
|
||||
}
|
||||
|
||||
return parent::blockAccess($account);
|
||||
|
|
|
@ -5,5 +5,5 @@ package: Testing
|
|||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- block
|
||||
- views
|
||||
- drupal:block
|
||||
- drupal:views
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
||||
/**
|
||||
* Provides test assertions for testing block appearance.
|
||||
*
|
||||
* Can be used by test classes that extend \Drupal\Tests\BrowserTestBase.
|
||||
*/
|
||||
trait AssertBlockAppearsTrait {
|
||||
|
||||
/**
|
||||
* Checks to see whether a block appears on the page.
|
||||
*
|
||||
* @param \Drupal\block\Entity\Block $block
|
||||
* The block entity to find on the page.
|
||||
*/
|
||||
protected function assertBlockAppears(Block $block) {
|
||||
$result = $this->findBlockInstance($block);
|
||||
$this->assertTrue(!empty($result), new FormattableMarkup('The block @id appears on the page', ['@id' => $block->id()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see whether a block does not appears on the page.
|
||||
*
|
||||
* @param \Drupal\block\Entity\Block $block
|
||||
* The block entity to find on the page.
|
||||
*/
|
||||
protected function assertNoBlockAppears(Block $block) {
|
||||
$result = $this->findBlockInstance($block);
|
||||
$this->assertFalse(!empty($result), new FormattableMarkup('The block @id does not appear on the page', ['@id' => $block->id()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a block instance on the page.
|
||||
*
|
||||
* @param \Drupal\block\Entity\Block $block
|
||||
* The block entity to find on the page.
|
||||
*
|
||||
* @return array
|
||||
* The result from the xpath query.
|
||||
*/
|
||||
protected function findBlockInstance(Block $block) {
|
||||
return $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the block system with admin themes.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockAdminThemeTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'contextual'];
|
||||
|
||||
/**
|
||||
* Check for the accessibility of the admin theme on the block admin page.
|
||||
*/
|
||||
public function testAdminTheme() {
|
||||
// Create administrative user.
|
||||
$admin_user = $this->drupalCreateUser(['administer blocks', 'administer themes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Ensure that access to block admin page is denied when theme is not
|
||||
// installed.
|
||||
$this->drupalGet('admin/structure/block/list/bartik');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Install admin theme and confirm that tab is accessible.
|
||||
\Drupal::service('theme_handler')->install(['bartik']);
|
||||
$edit['admin_theme'] = 'bartik';
|
||||
$this->drupalPostForm('admin/appearance', $edit, t('Save configuration'));
|
||||
$this->drupalGet('admin/structure/block/list/bartik');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure contextual links are disabled in Seven theme.
|
||||
*/
|
||||
public function testSevenAdminTheme() {
|
||||
// Create administrative user.
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'access administration pages',
|
||||
'administer themes',
|
||||
'access contextual links',
|
||||
'view the administration theme',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Install admin theme and confirm that tab is accessible.
|
||||
\Drupal::service('theme_handler')->install(['seven']);
|
||||
$edit['admin_theme'] = 'seven';
|
||||
$this->drupalPostForm('admin/appearance', $edit, t('Save configuration'));
|
||||
|
||||
// Define our block settings.
|
||||
$settings = [
|
||||
'theme' => 'seven',
|
||||
'region' => 'header',
|
||||
];
|
||||
|
||||
// Place a block.
|
||||
$block = $this->drupalPlaceBlock('local_tasks_block', $settings);
|
||||
|
||||
// Open admin page.
|
||||
$this->drupalGet('admin');
|
||||
|
||||
// Check if contextual link classes are unavailable.
|
||||
$this->assertNoRaw('<div data-contextual-id="block:block=' . $block->id() . ':langcode=en"></div>');
|
||||
$this->assertNoRaw('contextual-region');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the block demo page with admin themes.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockDemoTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* Check for the accessibility of the admin block demo page.
|
||||
*/
|
||||
public function testBlockDemo() {
|
||||
// Create administrative user.
|
||||
$admin_user = $this->drupalCreateUser(['administer blocks', 'administer themes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Confirm we have access to the block demo page for the default theme.
|
||||
$config = $this->container->get('config.factory')->get('system.theme');
|
||||
$default_theme = $config->get('default');
|
||||
$this->drupalGet('admin/structure/block/demo/' . $default_theme);
|
||||
$this->assertResponse(200);
|
||||
$this->assertLinkByHref('admin/structure/block');
|
||||
$this->assertNoLinkByHref('admin/structure/block/list/' . $default_theme);
|
||||
|
||||
// All available themes in core.
|
||||
$available_themes = [
|
||||
'bartik',
|
||||
'classy',
|
||||
'seven',
|
||||
'stark',
|
||||
];
|
||||
|
||||
// All available themes minute minus the default theme.
|
||||
$themes = array_diff($available_themes, [$default_theme]);
|
||||
|
||||
foreach ($themes as $theme) {
|
||||
// Install theme.
|
||||
$this->container->get('theme_handler')->install([$theme]);
|
||||
// Confirm access to the block demo page for the theme.
|
||||
$this->drupalGet('admin/structure/block/demo/' . $theme);
|
||||
$this->assertResponse(200);
|
||||
// Confirm existence of link for "Exit block region demonstration".
|
||||
$this->assertLinkByHref('admin/structure/block/list/' . $theme);
|
||||
}
|
||||
|
||||
// Confirm access to the block demo page is denied for an invalid theme.
|
||||
$this->drupalGet('admin/structure/block/demo/invalid_theme');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests form in block caching.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockFormInBlockTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'block_test', 'test_page_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Enable our test block.
|
||||
$this->drupalPlaceBlock('test_form_in_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if form in block's redirect isn't cached.
|
||||
*/
|
||||
public function testCachePerPage() {
|
||||
$form_values = ['email' => 'test@example.com'];
|
||||
|
||||
// Go to "test-page" and test if the block is enabled.
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertResponse(200);
|
||||
$this->assertText('Your .com email address.', 'form found');
|
||||
|
||||
// Make sure that we're currently still on /test-page after submitting the
|
||||
// form.
|
||||
$this->drupalPostForm(NULL, $form_values, t('Submit'));
|
||||
$this->assertUrl('test-page');
|
||||
$this->assertText(t('Your email address is @email', ['@email' => 'test@example.com']));
|
||||
|
||||
// Go to a different page and see if the block is enabled there as well.
|
||||
$this->drupalGet('test-render-title');
|
||||
$this->assertResponse(200);
|
||||
$this->assertText('Your .com email address.', 'form found');
|
||||
|
||||
// Make sure that submitting the form didn't redirect us to the first page
|
||||
// we submitted the form from after submitting the form from
|
||||
// /test-render-title.
|
||||
$this->drupalPostForm(NULL, $form_values, t('Submit'));
|
||||
$this->assertUrl('test-render-title');
|
||||
$this->assertText(t('Your email address is @email', ['@email' => 'test@example.com']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the actual placeholders
|
||||
*/
|
||||
public function testPlaceholders() {
|
||||
$this->drupalGet('test-multiple-forms');
|
||||
|
||||
$placeholder = 'form_action_' . Crypt::hashBase64('Drupal\Core\Form\FormBuilder::prepareForm');
|
||||
$this->assertText('Form action: ' . $placeholder, 'placeholder found.');
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +36,7 @@ class BlockHookOperationTest extends BrowserTestBase {
|
|||
public function testBlockOperationAlter() {
|
||||
// Add a test block, any block will do.
|
||||
// Set the machine name so the test_operation link can be built later.
|
||||
$block_id = Unicode::strtolower($this->randomMachineName(16));
|
||||
$block_id = mb_strtolower($this->randomMachineName(16));
|
||||
$this->drupalPlaceBlock('system_powered_by_block', ['id' => $block_id]);
|
||||
|
||||
// Get the Block listing.
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests block module's installation.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockInstallTest extends BrowserTestBase {
|
||||
|
||||
public function testCacheTagInvalidationUponInstallation() {
|
||||
// Warm the page cache.
|
||||
$this->drupalGet('');
|
||||
$this->assertNoText('Powered by Drupal');
|
||||
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:block_list');
|
||||
|
||||
// Install the block module, and place the "Powered by Drupal" block.
|
||||
$this->container->get('module_installer')->install(['block', 'shortcut']);
|
||||
$this->rebuildContainer();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
$this->drupalPlaceBlock('system_powered_by_block');
|
||||
|
||||
// Check the same page, block.module's hook_install() should have
|
||||
// invalidated the 'rendered' cache tag to make blocks show up.
|
||||
$this->drupalGet('');
|
||||
$this->assertCacheTag('config:block_list');
|
||||
$this->assertText('Powered by Drupal');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests display of menu blocks with multiple languages.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockLanguageCacheTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'language', 'menu_ui'];
|
||||
|
||||
/**
|
||||
* List of langcodes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $langcodes = [];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create test languages.
|
||||
$this->langcodes = [ConfigurableLanguage::load('en')];
|
||||
for ($i = 1; $i < 3; ++$i) {
|
||||
$language = ConfigurableLanguage::create([
|
||||
'id' => 'l' . $i,
|
||||
'label' => $this->randomString(),
|
||||
]);
|
||||
$language->save();
|
||||
$this->langcodes[$i] = $language;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a block in a language, check blocks page in all languages.
|
||||
*/
|
||||
public function testBlockLinks() {
|
||||
// Create admin user to be able to access block admin.
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
'access administration pages',
|
||||
'administer menu',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
// Create the block cache for all languages.
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$this->drupalGet('admin/structure/block', ['language' => $langcode]);
|
||||
$this->clickLink('Place block');
|
||||
}
|
||||
|
||||
// Create a menu in the default language.
|
||||
$edit['label'] = $this->randomMachineName();
|
||||
$edit['id'] = mb_strtolower($edit['label']);
|
||||
$this->drupalPostForm('admin/structure/menu/add', $edit, t('Save'));
|
||||
$this->assertText(t('Menu @label has been added.', ['@label' => $edit['label']]));
|
||||
|
||||
// Check that the block is listed for all languages.
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
$this->drupalGet('admin/structure/block', ['language' => $langcode]);
|
||||
$this->clickLink('Place block');
|
||||
$this->assertText($edit['label']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -164,7 +164,7 @@ class BlockLanguageTest extends BrowserTestBase {
|
|||
|
||||
// Change visibility to now depend on content language for this block.
|
||||
$edit = [
|
||||
'visibility[language][context_mapping][language]' => '@language.current_language_context:language_content'
|
||||
'visibility[language][context_mapping][language]' => '@language.current_language_context:language_content',
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/block/manage/' . $block_id, $edit, t('Save block'));
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests blocks are being rendered in order by weight.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockRenderOrderTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'block'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create a test user.
|
||||
$end_user = $this->drupalCreateUser([
|
||||
'access content',
|
||||
]);
|
||||
$this->drupalLogin($end_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the render order of the blocks.
|
||||
*/
|
||||
public function testBlockRenderOrder() {
|
||||
// Enable test blocks and place them in the same region.
|
||||
$region = 'header';
|
||||
$test_blocks = [
|
||||
'stark_powered' => [
|
||||
'weight' => '-3',
|
||||
'id' => 'stark_powered',
|
||||
'label' => 'Test block A',
|
||||
],
|
||||
'stark_by' => [
|
||||
'weight' => '3',
|
||||
'id' => 'stark_by',
|
||||
'label' => 'Test block C',
|
||||
],
|
||||
'stark_drupal' => [
|
||||
'weight' => '3',
|
||||
'id' => 'stark_drupal',
|
||||
'label' => 'Test block B',
|
||||
],
|
||||
];
|
||||
|
||||
// Place the test blocks.
|
||||
foreach ($test_blocks as $test_block) {
|
||||
$this->drupalPlaceBlock('system_powered_by_block', [
|
||||
'label' => $test_block['label'],
|
||||
'region' => $region,
|
||||
'weight' => $test_block['weight'],
|
||||
'id' => $test_block['id'],
|
||||
]);
|
||||
}
|
||||
|
||||
$this->drupalGet('');
|
||||
$test_content = $this->getSession()->getPage()->getContent();
|
||||
|
||||
$controller = $this->container->get('entity_type.manager')->getStorage('block');
|
||||
foreach ($controller->loadMultiple() as $return_block) {
|
||||
$id = $return_block->id();
|
||||
if ($return_block_weight = $return_block->getWeight()) {
|
||||
$this->assertTrue($test_blocks[$id]['weight'] == $return_block_weight, 'Block weight is set as "' . $return_block_weight . '" for ' . $id . ' block.');
|
||||
$position[$id] = strpos($test_content, Html::getClass('block-' . $test_blocks[$id]['id']));
|
||||
}
|
||||
}
|
||||
$this->assertTrue($position['stark_powered'] < $position['stark_by'], 'Blocks with different weight are rendered in the correct order.');
|
||||
$this->assertTrue($position['stark_drupal'] < $position['stark_by'], 'Blocks with identical weight are rendered in alphabetical order.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
/**
|
||||
* Tests branding block display.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockSystemBrandingTest extends BlockTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Set a site slogan.
|
||||
$this->config('system.site')
|
||||
->set('slogan', 'Community plumbing')
|
||||
->save();
|
||||
// Add the system branding block to the page.
|
||||
$this->drupalPlaceBlock('system_branding_block', ['region' => 'header', 'id' => 'site-branding']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests system branding block configuration.
|
||||
*/
|
||||
public function testSystemBrandingSettings() {
|
||||
$site_logo_xpath = '//div[@id="block-site-branding"]//a[@class="site-logo"]';
|
||||
$site_name_xpath = '//div[@id="block-site-branding"]//div[@class="site-name"]';
|
||||
$site_slogan_xpath = '//div[@id="block-site-branding"]//div[@class="site-slogan"]';
|
||||
|
||||
// Set default block settings.
|
||||
$this->drupalGet('');
|
||||
$site_logo_element = $this->xpath($site_logo_xpath);
|
||||
$site_name_element = $this->xpath($site_name_xpath);
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
// Test that all branding elements are displayed.
|
||||
$this->assertTrue(!empty($site_logo_element), 'The branding block logo was found.');
|
||||
$this->assertTrue(!empty($site_name_element), 'The branding block site name was found.');
|
||||
$this->assertTrue(!empty($site_slogan_element), 'The branding block slogan was found.');
|
||||
$this->assertCacheTag('config:system.site');
|
||||
|
||||
// Be sure the slogan is XSS-filtered.
|
||||
$this->config('system.site')
|
||||
->set('slogan', '<script>alert("Community carpentry");</script>')
|
||||
->save();
|
||||
$this->drupalGet('');
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
$this->assertEqual($site_slogan_element[0]->getText(), 'alert("Community carpentry");', 'The site slogan was XSS-filtered.');
|
||||
|
||||
// Turn just the logo off.
|
||||
$this->config('block.block.site-branding')
|
||||
->set('settings.use_site_logo', 0)
|
||||
->save();
|
||||
$this->drupalGet('');
|
||||
$site_logo_element = $this->xpath($site_logo_xpath);
|
||||
$site_name_element = $this->xpath($site_name_xpath);
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
// Re-test all branding elements.
|
||||
$this->assertTrue(empty($site_logo_element), 'The branding block logo was disabled.');
|
||||
$this->assertTrue(!empty($site_name_element), 'The branding block site name was found.');
|
||||
$this->assertTrue(!empty($site_slogan_element), 'The branding block slogan was found.');
|
||||
$this->assertCacheTag('config:system.site');
|
||||
|
||||
// Turn just the site name off.
|
||||
$this->config('block.block.site-branding')
|
||||
->set('settings.use_site_logo', 1)
|
||||
->set('settings.use_site_name', 0)
|
||||
->save();
|
||||
$this->drupalGet('');
|
||||
$site_logo_element = $this->xpath($site_logo_xpath);
|
||||
$site_name_element = $this->xpath($site_name_xpath);
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
// Re-test all branding elements.
|
||||
$this->assertTrue(!empty($site_logo_element), 'The branding block logo was found.');
|
||||
$this->assertTrue(empty($site_name_element), 'The branding block site name was disabled.');
|
||||
$this->assertTrue(!empty($site_slogan_element), 'The branding block slogan was found.');
|
||||
$this->assertCacheTag('config:system.site');
|
||||
|
||||
// Turn just the site slogan off.
|
||||
$this->config('block.block.site-branding')
|
||||
->set('settings.use_site_name', 1)
|
||||
->set('settings.use_site_slogan', 0)
|
||||
->save();
|
||||
$this->drupalGet('');
|
||||
$site_logo_element = $this->xpath($site_logo_xpath);
|
||||
$site_name_element = $this->xpath($site_name_xpath);
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
// Re-test all branding elements.
|
||||
$this->assertTrue(!empty($site_logo_element), 'The branding block logo was found.');
|
||||
$this->assertTrue(!empty($site_name_element), 'The branding block site name was found.');
|
||||
$this->assertTrue(empty($site_slogan_element), 'The branding block slogan was disabled.');
|
||||
$this->assertCacheTag('config:system.site');
|
||||
|
||||
// Turn the site name and the site slogan off.
|
||||
$this->config('block.block.site-branding')
|
||||
->set('settings.use_site_name', 0)
|
||||
->set('settings.use_site_slogan', 0)
|
||||
->save();
|
||||
$this->drupalGet('');
|
||||
$site_logo_element = $this->xpath($site_logo_xpath);
|
||||
$site_name_element = $this->xpath($site_name_xpath);
|
||||
$site_slogan_element = $this->xpath($site_slogan_xpath);
|
||||
// Re-test all branding elements.
|
||||
$this->assertTrue(!empty($site_logo_element), 'The branding block logo was found.');
|
||||
$this->assertTrue(empty($site_name_element), 'The branding block site name was disabled.');
|
||||
$this->assertTrue(empty($site_slogan_element), 'The branding block slogan was disabled.');
|
||||
$this->assertCacheTag('config:system.site');
|
||||
}
|
||||
|
||||
}
|
551
web/core/modules/block/tests/src/Functional/BlockTest.php
Normal file
551
web/core/modules/block/tests/src/Functional/BlockTest.php
Normal file
|
@ -0,0 +1,551 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests basic block functionality.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockTest extends BlockTestBase {
|
||||
|
||||
/**
|
||||
* Tests block visibility.
|
||||
*/
|
||||
public function testBlockVisibility() {
|
||||
$block_name = 'system_powered_by_block';
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
// Enable a standard block.
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$edit = [
|
||||
'id' => strtolower($this->randomMachineName(8)),
|
||||
'region' => 'sidebar_first',
|
||||
'settings[label]' => $title,
|
||||
'settings[label_display]' => TRUE,
|
||||
];
|
||||
// Set the block to be hidden on any user path, and to be shown only to
|
||||
// authenticated users.
|
||||
$edit['visibility[request_path][pages]'] = '/user*';
|
||||
$edit['visibility[request_path][negate]'] = TRUE;
|
||||
$edit['visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']'] = TRUE;
|
||||
$this->drupalGet('admin/structure/block/add/' . $block_name . '/' . $default_theme);
|
||||
$this->assertFieldChecked('edit-visibility-request-path-negate-0');
|
||||
|
||||
$this->drupalPostForm(NULL, $edit, t('Save block'));
|
||||
$this->assertText('The block configuration has been saved.', 'Block was saved');
|
||||
|
||||
$this->clickLink('Configure');
|
||||
$this->assertFieldChecked('edit-visibility-request-path-negate-1');
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertText($title, 'Block was displayed on the front page.');
|
||||
|
||||
$this->drupalGet('user');
|
||||
$this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
|
||||
|
||||
// Confirm that the block is not displayed to anonymous users.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('');
|
||||
$this->assertNoText($title, 'Block was not displayed to anonymous users.');
|
||||
|
||||
// Confirm that an empty block is not displayed.
|
||||
$this->assertNoText('Powered by Drupal', 'Empty block not displayed.');
|
||||
$this->assertNoRaw('sidebar-first', 'Empty sidebar-first region is not displayed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that visibility can be properly toggled.
|
||||
*/
|
||||
public function testBlockToggleVisibility() {
|
||||
$block_name = 'system_powered_by_block';
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
// Enable a standard block.
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$edit = [
|
||||
'id' => strtolower($this->randomMachineName(8)),
|
||||
'region' => 'sidebar_first',
|
||||
'settings[label]' => $title,
|
||||
];
|
||||
$block_id = $edit['id'];
|
||||
// Set the block to be shown only to authenticated users.
|
||||
$edit['visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']'] = TRUE;
|
||||
$this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block'));
|
||||
$this->clickLink('Configure');
|
||||
$this->assertFieldChecked('edit-visibility-user-role-roles-authenticated');
|
||||
|
||||
$edit = [
|
||||
'visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']' => FALSE,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save block');
|
||||
$this->clickLink('Configure');
|
||||
$this->assertNoFieldChecked('edit-visibility-user-role-roles-authenticated');
|
||||
|
||||
// Ensure that no visibility is configured.
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$block = Block::load($block_id);
|
||||
$visibility_config = $block->getVisibilityConditions()->getConfiguration();
|
||||
$this->assertIdentical([], $visibility_config);
|
||||
$this->assertIdentical([], $block->get('visibility'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test block visibility when leaving "pages" textarea empty.
|
||||
*/
|
||||
public function testBlockVisibilityListedEmpty() {
|
||||
$block_name = 'system_powered_by_block';
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
// Enable a standard block.
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$edit = [
|
||||
'id' => strtolower($this->randomMachineName(8)),
|
||||
'region' => 'sidebar_first',
|
||||
'settings[label]' => $title,
|
||||
'visibility[request_path][negate]' => TRUE,
|
||||
];
|
||||
// Set the block to be hidden on any user path, and to be shown only to
|
||||
// authenticated users.
|
||||
$this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block'));
|
||||
$this->assertText('The block configuration has been saved.', 'Block was saved');
|
||||
|
||||
$this->drupalGet('user');
|
||||
$this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
|
||||
|
||||
$this->drupalGet('USER');
|
||||
$this->assertNoText($title, 'Block was not displayed according to block visibility rules regardless of path case.');
|
||||
|
||||
// Confirm that the block is not displayed to anonymous users.
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('');
|
||||
$this->assertNoText($title, 'Block was not displayed to anonymous users on the front page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a block from the library page with a weight query string.
|
||||
*/
|
||||
public function testAddBlockFromLibraryWithWeight() {
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
// Test one positive, zero, and one negative weight.
|
||||
foreach (['7', '0', '-9'] as $weight) {
|
||||
$options = [
|
||||
'query' => [
|
||||
'region' => 'sidebar_first',
|
||||
'weight' => $weight,
|
||||
],
|
||||
];
|
||||
$this->drupalGet(Url::fromRoute('block.admin_library', ['theme' => $default_theme], $options));
|
||||
|
||||
$block_name = 'system_powered_by_block';
|
||||
$add_url = Url::fromRoute('block.admin_add', [
|
||||
'plugin_id' => $block_name,
|
||||
'theme' => $default_theme,
|
||||
]);
|
||||
$links = $this->xpath('//a[contains(@href, :href)]', [':href' => $add_url->toString()]);
|
||||
$this->assertEqual(1, count($links), 'Found one matching link.');
|
||||
$this->assertEqual(t('Place block'), $links[0]->getText(), 'Found the expected link text.');
|
||||
|
||||
list($path, $query_string) = explode('?', $links[0]->getAttribute('href'), 2);
|
||||
parse_str($query_string, $query_parts);
|
||||
$this->assertEqual($weight, $query_parts['weight'], 'Found the expected weight query string.');
|
||||
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
$block_id = strtolower($this->randomMachineName(8));
|
||||
$edit = [
|
||||
'id' => $block_id,
|
||||
'settings[label]' => $title,
|
||||
];
|
||||
// Create the block using the link parsed from the library page.
|
||||
$this->drupalPostForm($this->getAbsoluteUrl($links[0]->getAttribute('href')), $edit, t('Save block'));
|
||||
|
||||
// Ensure that the block was created with the expected weight.
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$block = Block::load($block_id);
|
||||
$this->assertEqual($weight, $block->getWeight(), 'Found the block with expected weight.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test configuring and moving a module-define block to specific regions.
|
||||
*/
|
||||
public function testBlock() {
|
||||
// Place page title block to test error messages.
|
||||
$this->drupalPlaceBlock('page_title_block');
|
||||
|
||||
// Disable the block.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Disable');
|
||||
|
||||
// Select the 'Powered by Drupal' block to be configured and moved.
|
||||
$block = [];
|
||||
$block['id'] = 'system_powered_by_block';
|
||||
$block['settings[label]'] = $this->randomMachineName(8);
|
||||
$block['settings[label_display]'] = TRUE;
|
||||
$block['theme'] = $this->config('system.theme')->get('default');
|
||||
$block['region'] = 'header';
|
||||
|
||||
// Set block title to confirm that interface works and override any custom titles.
|
||||
$this->drupalPostForm('admin/structure/block/add/' . $block['id'] . '/' . $block['theme'], ['settings[label]' => $block['settings[label]'], 'settings[label_display]' => $block['settings[label_display]'], 'id' => $block['id'], 'region' => $block['region']], t('Save block'));
|
||||
$this->assertText(t('The block configuration has been saved.'), 'Block title set.');
|
||||
// Check to see if the block was created by checking its configuration.
|
||||
$instance = Block::load($block['id']);
|
||||
|
||||
$this->assertEqual($instance->label(), $block['settings[label]'], 'Stored block title found.');
|
||||
|
||||
// Check whether the block can be moved to all available regions.
|
||||
foreach ($this->regions as $region) {
|
||||
$this->moveBlockToRegion($block, $region);
|
||||
}
|
||||
|
||||
// Disable the block.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Disable');
|
||||
|
||||
// Confirm that the block is now listed as disabled.
|
||||
$this->assertText(t('The block settings have been updated.'), 'Block successfully moved to disabled region.');
|
||||
|
||||
// Confirm that the block instance title and markup are not displayed.
|
||||
$this->drupalGet('node');
|
||||
$this->assertNoText(t($block['settings[label]']));
|
||||
// Check for <div id="block-my-block-instance-name"> if the machine name
|
||||
// is my_block_instance_name.
|
||||
$xpath = $this->buildXPathQuery('//div[@id=:id]/*', [':id' => 'block-' . str_replace('_', '-', strtolower($block['id']))]);
|
||||
$this->assertNoFieldByXPath($xpath, FALSE, 'Block found in no regions.');
|
||||
|
||||
// Test deleting the block from the edit form.
|
||||
$this->drupalGet('admin/structure/block/manage/' . $block['id']);
|
||||
$this->clickLink(t('Remove block'));
|
||||
$this->assertRaw(t('Are you sure you want to remove the block @name?', ['@name' => $block['settings[label]']]));
|
||||
$this->drupalPostForm(NULL, [], t('Remove'));
|
||||
$this->assertRaw(t('The block %name has been removed.', ['%name' => $block['settings[label]']]));
|
||||
|
||||
// Test deleting a block via "Configure block" link.
|
||||
$block = $this->drupalPlaceBlock('system_powered_by_block');
|
||||
$this->drupalGet('admin/structure/block/manage/' . $block->id(), ['query' => ['destination' => 'admin']]);
|
||||
$this->clickLink(t('Remove block'));
|
||||
$this->assertRaw(t('Are you sure you want to remove the block @name?', ['@name' => $block->label()]));
|
||||
$this->drupalPostForm(NULL, [], t('Remove'));
|
||||
$this->assertRaw(t('The block %name has been removed.', ['%name' => $block->label()]));
|
||||
$this->assertUrl('admin');
|
||||
$this->assertNoRaw($block->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the block form has a theme selector when not passed via the URL.
|
||||
*/
|
||||
public function testBlockThemeSelector() {
|
||||
// Install all themes.
|
||||
\Drupal::service('theme_handler')->install(['bartik', 'seven', 'stark']);
|
||||
$theme_settings = $this->config('system.theme');
|
||||
foreach (['bartik', 'seven', 'stark'] as $theme) {
|
||||
$this->drupalGet('admin/structure/block/list/' . $theme);
|
||||
$this->assertTitle(t('Block layout') . ' | Drupal');
|
||||
// Select the 'Powered by Drupal' block to be placed.
|
||||
$block = [];
|
||||
$block['id'] = strtolower($this->randomMachineName());
|
||||
$block['theme'] = $theme;
|
||||
$block['region'] = 'content';
|
||||
$this->drupalPostForm('admin/structure/block/add/system_powered_by_block', $block, t('Save block'));
|
||||
$this->assertText(t('The block configuration has been saved.'));
|
||||
$this->assertUrl('admin/structure/block/list/' . $theme . '?block-placement=' . Html::getClass($block['id']));
|
||||
|
||||
// Set the default theme and ensure the block is placed.
|
||||
$theme_settings->set('default', $theme)->save();
|
||||
$this->drupalGet('');
|
||||
$elements = $this->xpath('//div[@id = :id]', [':id' => Html::getUniqueId('block-' . $block['id'])]);
|
||||
$this->assertTrue(!empty($elements), 'The block was found.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test block display of theme titles.
|
||||
*/
|
||||
public function testThemeName() {
|
||||
// Enable the help block.
|
||||
$this->drupalPlaceBlock('help_block', ['region' => 'help']);
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
// Explicitly set the default and admin themes.
|
||||
$theme = 'block_test_specialchars_theme';
|
||||
\Drupal::service('theme_handler')->install([$theme]);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->assertEscaped('<"Cat" & \'Mouse\'>');
|
||||
$this->drupalGet('admin/structure/block/list/block_test_specialchars_theme');
|
||||
$this->assertEscaped('Demonstrate block regions (<"Cat" & \'Mouse\'>)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test block title display settings.
|
||||
*/
|
||||
public function testHideBlockTitle() {
|
||||
$block_name = 'system_powered_by_block';
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
$id = strtolower($this->randomMachineName(8));
|
||||
// Enable a standard block.
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$edit = [
|
||||
'id' => $id,
|
||||
'region' => 'sidebar_first',
|
||||
'settings[label]' => $title,
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block'));
|
||||
$this->assertText('The block configuration has been saved.', 'Block was saved');
|
||||
|
||||
$this->drupalGet('user');
|
||||
$this->assertNoText($title, 'Block title was not displayed by default.');
|
||||
|
||||
$edit = [
|
||||
'settings[label_display]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/block/manage/' . $id, $edit, t('Save block'));
|
||||
$this->assertText('The block configuration has been saved.', 'Block was saved');
|
||||
|
||||
$this->drupalGet('admin/structure/block/manage/' . $id);
|
||||
$this->assertFieldChecked('edit-settings-label-display', 'The display_block option has the correct default value on the configuration form.');
|
||||
|
||||
$this->drupalGet('user');
|
||||
$this->assertText($title, 'Block title was displayed when enabled.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a block to a given region via the UI and confirms the result.
|
||||
*
|
||||
* @param array $block
|
||||
* An array of information about the block, including the following keys:
|
||||
* - module: The module providing the block.
|
||||
* - title: The title of the block.
|
||||
* - delta: The block's delta key.
|
||||
* @param string $region
|
||||
* The machine name of the theme region to move the block to, for example
|
||||
* 'header' or 'sidebar_first'.
|
||||
*/
|
||||
public function moveBlockToRegion(array $block, $region) {
|
||||
// Set the created block to a specific region.
|
||||
$block += ['theme' => $this->config('system.theme')->get('default')];
|
||||
$edit = [];
|
||||
$edit['blocks[' . $block['id'] . '][region]'] = $region;
|
||||
$this->drupalPostForm('admin/structure/block', $edit, t('Save blocks'));
|
||||
|
||||
// Confirm that the block was moved to the proper region.
|
||||
$this->assertText(t('The block settings have been updated.'), format_string('Block successfully moved to %region_name region.', ['%region_name' => $region]));
|
||||
|
||||
// Confirm that the block is being displayed.
|
||||
$this->drupalGet('');
|
||||
$this->assertText(t($block['settings[label]']), 'Block successfully being displayed on the page.');
|
||||
|
||||
// Confirm that the custom block was found at the proper region.
|
||||
$xpath = $this->buildXPathQuery('//div[@class=:region-class]//div[@id=:block-id]/*', [
|
||||
':region-class' => 'region region-' . Html::getClass($region),
|
||||
':block-id' => 'block-' . str_replace('_', '-', strtolower($block['id'])),
|
||||
]);
|
||||
$this->assertFieldByXPath($xpath, NULL, t('Block found in %region_name region.', ['%region_name' => Html::getClass($region)]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cache tags are properly set and bubbled up to the page cache.
|
||||
*
|
||||
* Verify that invalidation of these cache tags works:
|
||||
* - "block:<block ID>"
|
||||
* - "block_plugin:<block plugin ID>"
|
||||
*/
|
||||
public function testBlockCacheTags() {
|
||||
// The page cache only works for anonymous users.
|
||||
$this->drupalLogout();
|
||||
|
||||
// Enable page caching.
|
||||
$config = $this->config('system.performance');
|
||||
$config->set('cache.page.max_age', 300);
|
||||
$config->save();
|
||||
|
||||
// Place the "Powered by Drupal" block.
|
||||
$block = $this->drupalPlaceBlock('system_powered_by_block', ['id' => 'powered']);
|
||||
|
||||
// Prime the page cache.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
|
||||
|
||||
// Verify a cache hit, but also the presence of the correct cache tags in
|
||||
// both the page and block caches.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
|
||||
$cid_parts = [\Drupal::url('<front>', [], ['absolute' => TRUE]), 'html'];
|
||||
$cid = implode(':', $cid_parts);
|
||||
$cache_entry = \Drupal::cache('page')->get($cid);
|
||||
$expected_cache_tags = [
|
||||
'config:block_list',
|
||||
'block_view',
|
||||
'config:block.block.powered',
|
||||
'config:user.role.anonymous',
|
||||
'http_response',
|
||||
'rendered',
|
||||
];
|
||||
sort($expected_cache_tags);
|
||||
$keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
|
||||
$this->assertIdentical($cache_entry->tags, $expected_cache_tags);
|
||||
$cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:' . implode(':', $keys));
|
||||
$expected_cache_tags = [
|
||||
'block_view',
|
||||
'config:block.block.powered',
|
||||
'rendered',
|
||||
];
|
||||
sort($expected_cache_tags);
|
||||
$this->assertIdentical($cache_entry->tags, $expected_cache_tags);
|
||||
|
||||
// The "Powered by Drupal" block is modified; verify a cache miss.
|
||||
$block->setRegion('content');
|
||||
$block->save();
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
|
||||
|
||||
// Now we should have a cache hit again.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
|
||||
|
||||
// Place the "Powered by Drupal" block another time; verify a cache miss.
|
||||
$block_2 = $this->drupalPlaceBlock('system_powered_by_block', ['id' => 'powered-2']);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
|
||||
|
||||
// Verify a cache hit, but also the presence of the correct cache tags.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
|
||||
$cid_parts = [\Drupal::url('<front>', [], ['absolute' => TRUE]), 'html'];
|
||||
$cid = implode(':', $cid_parts);
|
||||
$cache_entry = \Drupal::cache('page')->get($cid);
|
||||
$expected_cache_tags = [
|
||||
'config:block_list',
|
||||
'block_view',
|
||||
'config:block.block.powered',
|
||||
'config:block.block.powered-2',
|
||||
'config:user.role.anonymous',
|
||||
'http_response',
|
||||
'rendered',
|
||||
];
|
||||
sort($expected_cache_tags);
|
||||
$this->assertEqual($cache_entry->tags, $expected_cache_tags);
|
||||
$expected_cache_tags = [
|
||||
'block_view',
|
||||
'config:block.block.powered',
|
||||
'rendered',
|
||||
];
|
||||
sort($expected_cache_tags);
|
||||
$keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
|
||||
$cache_entry = \Drupal::cache('render')->get('entity_view:block:powered:' . implode(':', $keys));
|
||||
$this->assertIdentical($cache_entry->tags, $expected_cache_tags);
|
||||
$expected_cache_tags = [
|
||||
'block_view',
|
||||
'config:block.block.powered-2',
|
||||
'rendered',
|
||||
];
|
||||
sort($expected_cache_tags);
|
||||
$keys = \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:language_interface', 'theme', 'user.permissions'])->getKeys();
|
||||
$cache_entry = \Drupal::cache('render')->get('entity_view:block:powered-2:' . implode(':', $keys));
|
||||
$this->assertIdentical($cache_entry->tags, $expected_cache_tags);
|
||||
|
||||
// Now we should have a cache hit again.
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
|
||||
|
||||
// Delete the "Powered by Drupal" blocks; verify a cache miss.
|
||||
entity_delete_multiple('block', ['powered', 'powered-2']);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a link exists to block layout from the appearance form.
|
||||
*/
|
||||
public function testThemeAdminLink() {
|
||||
$this->drupalPlaceBlock('help_block', ['region' => 'help']);
|
||||
$theme_admin = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
'administer themes',
|
||||
'access administration pages',
|
||||
]);
|
||||
$this->drupalLogin($theme_admin);
|
||||
$this->drupalGet('admin/appearance');
|
||||
$this->assertText('You can place blocks for each theme on the block layout page');
|
||||
$this->assertLinkByHref('admin/structure/block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that uninstalling a theme removes its block configuration.
|
||||
*/
|
||||
public function testUninstallTheme() {
|
||||
/** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
|
||||
$theme_handler = \Drupal::service('theme_handler');
|
||||
|
||||
$theme_handler->install(['seven']);
|
||||
$this->config('system.theme')->set('default', 'seven')->save();
|
||||
$block = $this->drupalPlaceBlock('system_powered_by_block', ['theme' => 'seven', 'region' => 'help']);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertText('Powered by Drupal');
|
||||
|
||||
$this->config('system.theme')->set('default', 'classy')->save();
|
||||
$theme_handler->uninstall(['seven']);
|
||||
|
||||
// Ensure that the block configuration does not exist anymore.
|
||||
$this->assertIdentical(NULL, Block::load($block->id()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the block access.
|
||||
*/
|
||||
public function testBlockAccess() {
|
||||
$this->drupalPlaceBlock('test_access', ['region' => 'help']);
|
||||
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertNoText('Hello test world');
|
||||
|
||||
\Drupal::state()->set('test_block_access', TRUE);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertText('Hello test world');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests block_user_role_delete.
|
||||
*/
|
||||
public function testBlockUserRoleDelete() {
|
||||
$role1 = Role::create(['id' => 'test_role1', 'name' => $this->randomString()]);
|
||||
$role1->save();
|
||||
|
||||
$role2 = Role::create(['id' => 'test_role2', 'name' => $this->randomString()]);
|
||||
$role2->save();
|
||||
|
||||
$block = Block::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'plugin' => 'system_powered_by_block',
|
||||
]);
|
||||
|
||||
$block->setVisibilityConfig('user_role', [
|
||||
'roles' => [
|
||||
$role1->id() => $role1->id(),
|
||||
$role2->id() => $role2->id(),
|
||||
],
|
||||
]);
|
||||
|
||||
$block->save();
|
||||
|
||||
$this->assertEqual($block->getVisibility()['user_role']['roles'], [
|
||||
$role1->id() => $role1->id(),
|
||||
$role2->id() => $role2->id(),
|
||||
]);
|
||||
|
||||
$role1->delete();
|
||||
|
||||
$block = Block::load($block->id());
|
||||
$this->assertEqual($block->getVisibility()['user_role']['roles'], [
|
||||
$role2->id() => $role2->id(),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Provides setup and helper methods for block module tests.
|
||||
*/
|
||||
abstract class BlockTestBase extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'filter', 'test_page_test', 'help', 'block_test'];
|
||||
|
||||
/**
|
||||
* A list of theme regions to test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $regions;
|
||||
|
||||
/**
|
||||
* A test user with administrative privileges.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Use the test page as the front page.
|
||||
$this->config('system.site')->set('page.front', '/test-page')->save();
|
||||
|
||||
// Create Full HTML text format.
|
||||
$full_html_format = FilterFormat::create([
|
||||
'format' => 'full_html',
|
||||
'name' => 'Full HTML',
|
||||
]);
|
||||
$full_html_format->save();
|
||||
|
||||
// Create and log in an administrative user having access to the Full HTML
|
||||
// text format.
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
$full_html_format->getPermissionName(),
|
||||
'access administration pages',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Define the existing regions.
|
||||
$this->regions = [
|
||||
'header',
|
||||
'sidebar_first',
|
||||
'content',
|
||||
'sidebar_second',
|
||||
'footer',
|
||||
];
|
||||
$block_storage = $this->container->get('entity_type.manager')->getStorage('block');
|
||||
$blocks = $block_storage->loadByProperties(['theme' => $this->config('system.theme')->get('default')]);
|
||||
foreach ($blocks as $block) {
|
||||
$block->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
329
web/core/modules/block/tests/src/Functional/BlockUiTest.php
Normal file
329
web/core/modules/block/tests/src/Functional/BlockUiTest.php
Normal file
|
@ -0,0 +1,329 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the block configuration UI exists and stores data correctly.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockUiTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'block_test', 'help', 'condition_test'];
|
||||
|
||||
protected $regions;
|
||||
|
||||
/**
|
||||
* The submitted block values used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $blockValues;
|
||||
|
||||
/**
|
||||
* The block entities used by this test.
|
||||
*
|
||||
* @var \Drupal\block\BlockInterface[]
|
||||
*/
|
||||
protected $blocks;
|
||||
|
||||
/**
|
||||
* An administrative user to configure the test environment.
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Create and log in an administrative user.
|
||||
$this->adminUser = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
'access administration pages',
|
||||
]);
|
||||
$this->drupalLogin($this->adminUser);
|
||||
|
||||
// Enable some test blocks.
|
||||
$this->blockValues = [
|
||||
[
|
||||
'label' => 'Tools',
|
||||
'tr' => '5',
|
||||
'plugin_id' => 'system_menu_block:tools',
|
||||
'settings' => ['region' => 'sidebar_second', 'id' => 'tools'],
|
||||
'test_weight' => '-1',
|
||||
],
|
||||
[
|
||||
'label' => 'Powered by Drupal',
|
||||
'tr' => '16',
|
||||
'plugin_id' => 'system_powered_by_block',
|
||||
'settings' => ['region' => 'footer', 'id' => 'powered'],
|
||||
'test_weight' => '0',
|
||||
],
|
||||
];
|
||||
$this->blocks = [];
|
||||
foreach ($this->blockValues as $values) {
|
||||
$this->blocks[] = $this->drupalPlaceBlock($values['plugin_id'], $values['settings']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test block demo page exists and functions correctly.
|
||||
*/
|
||||
public function testBlockDemoUiPage() {
|
||||
$this->drupalPlaceBlock('help_block', ['region' => 'help']);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink(t('Demonstrate block regions (@theme)', ['@theme' => 'Classy']));
|
||||
$elements = $this->xpath('//div[contains(@class, "region-highlighted")]/div[contains(@class, "block-region") and contains(text(), :title)]', [':title' => 'Highlighted']);
|
||||
$this->assertTrue(!empty($elements), 'Block demo regions are shown.');
|
||||
|
||||
\Drupal::service('theme_handler')->install(['test_theme']);
|
||||
$this->drupalGet('admin/structure/block/demo/test_theme');
|
||||
$this->assertEscaped('<strong>Test theme</strong>');
|
||||
|
||||
\Drupal::service('theme_handler')->install(['stable']);
|
||||
$this->drupalGet('admin/structure/block/demo/stable');
|
||||
$this->assertResponse(404, 'Hidden themes that are not the default theme are not supported by the block demo screen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test block admin page exists and functions correctly.
|
||||
*/
|
||||
public function testBlockAdminUiPage() {
|
||||
// Visit the blocks admin ui.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
// Look for the blocks table.
|
||||
$blocks_table = $this->xpath("//table[@id='blocks']");
|
||||
$this->assertTrue(!empty($blocks_table), 'The blocks table is being rendered.');
|
||||
// Look for test blocks in the table.
|
||||
foreach ($this->blockValues as $delta => $values) {
|
||||
$block = $this->blocks[$delta];
|
||||
$label = $block->label();
|
||||
$element = $this->xpath('//*[@id="blocks"]/tbody/tr[' . $values['tr'] . ']/td[1]/text()');
|
||||
$this->assertEquals($element[0]->getText(), $label, 'The "' . $label . '" block title is set inside the ' . $values['settings']['region'] . ' region.');
|
||||
// Look for a test block region select form element.
|
||||
$this->assertField('blocks[' . $values['settings']['id'] . '][region]', 'The block "' . $values['label'] . '" has a region assignment field.');
|
||||
// Move the test block to the header region.
|
||||
$edit['blocks[' . $values['settings']['id'] . '][region]'] = 'header';
|
||||
// Look for a test block weight select form element.
|
||||
$this->assertField('blocks[' . $values['settings']['id'] . '][weight]', 'The block "' . $values['label'] . '" has a weight assignment field.');
|
||||
// Change the test block's weight.
|
||||
$edit['blocks[' . $values['settings']['id'] . '][weight]'] = $values['test_weight'];
|
||||
}
|
||||
$this->drupalPostForm('admin/structure/block', $edit, t('Save blocks'));
|
||||
foreach ($this->blockValues as $values) {
|
||||
// Check if the region and weight settings changes have persisted.
|
||||
$this->assertOptionSelected(
|
||||
'edit-blocks-' . $values['settings']['id'] . '-region',
|
||||
'header',
|
||||
'The block "' . $label . '" has the correct region assignment (header).'
|
||||
);
|
||||
$this->assertOptionSelected(
|
||||
'edit-blocks-' . $values['settings']['id'] . '-weight',
|
||||
$values['test_weight'],
|
||||
'The block "' . $label . '" has the correct weight assignment (' . $values['test_weight'] . ').'
|
||||
);
|
||||
}
|
||||
|
||||
// Add a block with a machine name the same as a region name.
|
||||
$this->drupalPlaceBlock('system_powered_by_block', ['region' => 'header', 'id' => 'header']);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$element = $this->xpath('//tr[contains(@class, :class)]', [':class' => 'region-title-header']);
|
||||
$this->assertTrue(!empty($element));
|
||||
|
||||
// Ensure hidden themes do not appear in the UI. Enable another non base
|
||||
// theme and place the local tasks block.
|
||||
$this->assertTrue(\Drupal::service('theme_handler')->themeExists('classy'), 'The classy base theme is enabled');
|
||||
$this->drupalPlaceBlock('local_tasks_block', ['region' => 'header']);
|
||||
\Drupal::service('theme_installer')->install(['stable', 'stark']);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$theme_handler = \Drupal::service('theme_handler');
|
||||
$this->assertLink($theme_handler->getName('classy'));
|
||||
$this->assertLink($theme_handler->getName('stark'));
|
||||
$this->assertNoLink($theme_handler->getName('stable'));
|
||||
|
||||
$this->drupalGet('admin/structure/block/list/stable');
|
||||
$this->assertResponse(404, 'Placing blocks through UI is not possible for a hidden base theme.');
|
||||
|
||||
\Drupal::configFactory()->getEditable('system.theme')->set('admin', 'stable')->save();
|
||||
\Drupal::service('router.builder')->rebuildIfNeeded();
|
||||
$this->drupalPlaceBlock('local_tasks_block', ['region' => 'header', 'theme' => 'stable']);
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->assertLink($theme_handler->getName('stable'));
|
||||
$this->drupalGet('admin/structure/block/list/stable');
|
||||
$this->assertResponse(200, 'Placing blocks through UI is possible for a hidden base theme that is the admin theme.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the block categories on the listing page.
|
||||
*/
|
||||
public function testCandidateBlockList() {
|
||||
$arguments = [
|
||||
':title' => 'Display message',
|
||||
':category' => 'Block test',
|
||||
':href' => 'admin/structure/block/add/test_block_instantiation/classy',
|
||||
];
|
||||
$pattern = '//tr[.//td/div[text()=:title] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]';
|
||||
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The test block appears in the category for its module.');
|
||||
|
||||
// Trigger the custom category addition in block_test_block_alter().
|
||||
$this->container->get('state')->set('block_test_info_alter', TRUE);
|
||||
$this->container->get('plugin.manager.block')->clearCachedDefinitions();
|
||||
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$arguments[':category'] = 'Custom category';
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The test block appears in a custom category controlled by block_test_block_alter().');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the behavior of unsatisfied context-aware blocks.
|
||||
*/
|
||||
public function testContextAwareUnsatisfiedBlocks() {
|
||||
$arguments = [
|
||||
':category' => 'Block test',
|
||||
':href' => 'admin/structure/block/add/test_context_aware_unsatisfied/classy',
|
||||
':text' => 'Test context-aware unsatisfied block',
|
||||
];
|
||||
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$elements = $this->xpath('//tr[.//td/div[text()=:text] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]', $arguments);
|
||||
$this->assertTrue(empty($elements), 'The context-aware test block does not appear.');
|
||||
|
||||
$definition = \Drupal::service('plugin.manager.block')->getDefinition('test_context_aware_unsatisfied');
|
||||
$this->assertTrue(!empty($definition), 'The context-aware test block does not exist.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the behavior of context-aware blocks.
|
||||
*/
|
||||
public function testContextAwareBlocks() {
|
||||
$expected_text = '<div id="test_context_aware--username">' . \Drupal::currentUser()->getUsername() . '</div>';
|
||||
$this->drupalGet('');
|
||||
$this->assertNoText('Test context-aware block');
|
||||
$this->assertNoRaw($expected_text);
|
||||
|
||||
$block_url = 'admin/structure/block/add/test_context_aware/classy';
|
||||
$arguments = [
|
||||
':title' => 'Test context-aware block',
|
||||
':category' => 'Block test',
|
||||
':href' => $block_url,
|
||||
];
|
||||
$pattern = '//tr[.//td/div[text()=:title] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]';
|
||||
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The context-aware test block appears.');
|
||||
$definition = \Drupal::service('plugin.manager.block')->getDefinition('test_context_aware');
|
||||
$this->assertTrue(!empty($definition), 'The context-aware test block exists.');
|
||||
$edit = [
|
||||
'region' => 'content',
|
||||
'settings[context_mapping][user]' => '@block_test.multiple_static_context:userB',
|
||||
];
|
||||
$this->drupalPostForm($block_url, $edit, 'Save block');
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertText('Test context-aware block');
|
||||
$this->assertText('User context found.');
|
||||
$this->assertRaw($expected_text);
|
||||
|
||||
// Test context mapping allows empty selection for optional contexts.
|
||||
$this->drupalGet('admin/structure/block/manage/testcontextawareblock');
|
||||
$edit = [
|
||||
'settings[context_mapping][user]' => '',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save block');
|
||||
$this->drupalGet('');
|
||||
$this->assertText('No context mapping selected.');
|
||||
$this->assertNoText('User context found.');
|
||||
|
||||
// Tests that conditions with missing context are not displayed.
|
||||
$this->drupalGet('admin/structure/block/manage/testcontextawareblock');
|
||||
$this->assertNoRaw('No existing type');
|
||||
$this->assertNoFieldByXPath('//*[@name="visibility[condition_test_no_existing_type][negate]"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the BlockForm populates machine name correctly.
|
||||
*/
|
||||
public function testMachineNameSuggestion() {
|
||||
$url = 'admin/structure/block/add/test_block_instantiation/classy';
|
||||
$this->drupalGet($url);
|
||||
$this->assertFieldByName('id', 'displaymessage', 'Block form uses raw machine name suggestion when no instance already exists.');
|
||||
$edit = ['region' => 'content'];
|
||||
$this->drupalPostForm($url, $edit, 'Save block');
|
||||
$this->assertText('The block configuration has been saved.');
|
||||
|
||||
// Now, check to make sure the form starts by autoincrementing correctly.
|
||||
$this->drupalGet($url);
|
||||
$this->assertFieldByName('id', 'displaymessage_2', 'Block form appends _2 to plugin-suggested machine name when an instance already exists.');
|
||||
$this->drupalPostForm($url, $edit, 'Save block');
|
||||
$this->assertText('The block configuration has been saved.');
|
||||
|
||||
// And verify that it continues working beyond just the first two.
|
||||
$this->drupalGet($url);
|
||||
$this->assertFieldByName('id', 'displaymessage_3', 'Block form appends _3 to plugin-suggested machine name when two instances already exist.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the block placement indicator.
|
||||
*/
|
||||
public function testBlockPlacementIndicator() {
|
||||
// Select the 'Powered by Drupal' block to be placed.
|
||||
$block = [];
|
||||
$block['id'] = strtolower($this->randomMachineName());
|
||||
$block['theme'] = 'classy';
|
||||
$block['region'] = 'content';
|
||||
|
||||
// After adding a block, it will indicate which block was just added.
|
||||
$this->drupalPostForm('admin/structure/block/add/system_powered_by_block', $block, t('Save block'));
|
||||
$this->assertUrl('admin/structure/block/list/classy?block-placement=' . Html::getClass($block['id']));
|
||||
|
||||
// Resaving the block page will remove the block indicator.
|
||||
$this->drupalPostForm(NULL, [], t('Save blocks'));
|
||||
$this->assertUrl('admin/structure/block/list/classy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if validation errors are passed plugin form to the parent form.
|
||||
*/
|
||||
public function testBlockValidateErrors() {
|
||||
$this->drupalPostForm('admin/structure/block/add/test_settings_validation/classy', ['region' => 'content', 'settings[digits]' => 'abc'], t('Save block'));
|
||||
|
||||
$arguments = [':message' => 'Only digits are allowed'];
|
||||
$pattern = '//div[contains(@class,"messages messages--error")]/div[contains(text()[2],:message)]';
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue($elements, 'Plugin error message found in parent form.');
|
||||
|
||||
$error_class_pattern = '//div[contains(@class,"form-item-settings-digits")]/input[contains(@class,"error")]';
|
||||
$error_class = $this->xpath($error_class_pattern);
|
||||
$this->assertTrue($error_class, 'Plugin error class found in parent form.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the enable/disable routes are protected from CSRF.
|
||||
*/
|
||||
public function testRouteProtection() {
|
||||
// Get the first block generated in our setUp method.
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$block = reset($this->blocks);
|
||||
// Ensure that the enable and disable routes are protected.
|
||||
$this->drupalGet('admin/structure/block/manage/' . $block->id() . '/disable');
|
||||
$this->assertResponse(403);
|
||||
$this->drupalGet('admin/structure/block/manage/' . $block->id() . '/enable');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
}
|
167
web/core/modules/block/tests/src/Functional/BlockXssTest.php
Normal file
167
web/core/modules/block/tests/src/Functional/BlockXssTest.php
Normal file
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\block_content\Entity\BlockContent;
|
||||
use Drupal\block_content\Entity\BlockContentType;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\system\Entity\Menu;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\views\Entity\View;
|
||||
|
||||
/**
|
||||
* Tests that the block module properly escapes block descriptions.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockXssTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block', 'block_content', 'menu_ui', 'views'];
|
||||
|
||||
/**
|
||||
* Tests that nothing is escaped other than the blocks explicitly tested.
|
||||
*/
|
||||
public function testNoUnexpectedEscaping() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
$this->assertNoEscaped('<');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests XSS in title.
|
||||
*/
|
||||
public function testXssInTitle() {
|
||||
$this->container->get('module_installer')->install(['block_test']);
|
||||
$this->drupalPlaceBlock('test_xss_title', ['label' => '<script>alert("XSS label");</script>']);
|
||||
|
||||
\Drupal::state()->set('block_test.content', $this->randomMachineName());
|
||||
$this->drupalGet('');
|
||||
$this->assertNoRaw('<script>alert("XSS label");</script>', 'The block title was properly sanitized when rendered.');
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$this->drupalGet('admin/structure/block/list/' . $default_theme);
|
||||
$this->assertNoRaw("<script>alert('XSS subject');</script>", 'The block title was properly sanitized in Block Plugin UI Admin page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests XSS in category.
|
||||
*/
|
||||
public function testXssInCategory() {
|
||||
$this->container->get('module_installer')->install(['block_test']);
|
||||
$this->drupalPlaceBlock('test_xss_title');
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer blocks', 'access administration pages']));
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
$this->assertNoRaw("<script>alert('XSS category');</script>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests various modules that provide blocks for XSS.
|
||||
*/
|
||||
public function testBlockXss() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
$this->doViewTest();
|
||||
$this->doMenuTest();
|
||||
$this->doBlockContentTest();
|
||||
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
$this->assertNoRaw('&lt;', 'The page does not have double escaped HTML tags.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests XSS coming from View block labels.
|
||||
*/
|
||||
protected function doViewTest() {
|
||||
// Create a View without a custom label for its block Display. The
|
||||
// admin_label of the block then becomes just the View's label.
|
||||
$view = View::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => '<script>alert("view1");</script>',
|
||||
]);
|
||||
$view->addDisplay('block');
|
||||
$view->save();
|
||||
|
||||
// Create a View with a custom label for its block Display. The
|
||||
// admin_label of the block then becomes the View's label combined with
|
||||
// the Display's label.
|
||||
$view = View::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => '<script>alert("view2");</script>',
|
||||
]);
|
||||
$view->addDisplay('block', 'Fish & chips');
|
||||
$view->save();
|
||||
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
|
||||
// \Drupal\views\Plugin\Derivative\ViewsBlock::getDerivativeDefinitions()
|
||||
// has a different code path for an admin label based only on the View
|
||||
// label versus one based on both the View label and the Display label.
|
||||
// Ensure that this test is covering both code paths by asserting the
|
||||
// absence of a ":" for the first View and the presence of a ":" for the
|
||||
// second one. Note that the second assertion is redundant with the one
|
||||
// further down which also checks for the Display label, but is included
|
||||
// here for clarity.
|
||||
$this->assertNoEscaped('<script>alert("view1");</script>:');
|
||||
$this->assertEscaped('<script>alert("view2");</script>:');
|
||||
|
||||
// Assert that the blocks have their admin labels escaped and
|
||||
// don't appear anywhere unescaped.
|
||||
$this->assertEscaped('<script>alert("view1");</script>');
|
||||
$this->assertNoRaw('<script>alert("view1");</script>');
|
||||
$this->assertEscaped('<script>alert("view2");</script>: Fish & chips');
|
||||
$this->assertNoRaw('<script>alert("view2");</script>');
|
||||
$this->assertNoRaw('Fish & chips');
|
||||
|
||||
// Assert the Display label doesn't appear anywhere double escaped.
|
||||
$this->assertNoRaw('Fish & chips');
|
||||
$this->assertNoRaw('Fish &amp; chips');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests XSS coming from Menu block labels.
|
||||
*/
|
||||
protected function doMenuTest() {
|
||||
Menu::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'label' => '<script>alert("menu");</script>',
|
||||
])->save();
|
||||
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
|
||||
$this->assertEscaped('<script>alert("menu");</script>');
|
||||
$this->assertNoRaw('<script>alert("menu");</script>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests XSS coming from Block Content block info.
|
||||
*/
|
||||
protected function doBlockContentTest() {
|
||||
BlockContentType::create([
|
||||
'id' => 'basic',
|
||||
'label' => 'basic',
|
||||
'revision' => TRUE,
|
||||
])->save();
|
||||
BlockContent::create([
|
||||
'type' => 'basic',
|
||||
'info' => '<script>alert("block_content");</script>',
|
||||
])->save();
|
||||
|
||||
$this->drupalGet(Url::fromRoute('block.admin_display'));
|
||||
$this->clickLink('Place block');
|
||||
|
||||
$this->assertEscaped('<script>alert("block_content");</script>');
|
||||
$this->assertNoRaw('<script>alert("block_content");</script>');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BlockHalJsonAnonTest extends BlockResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BlockHalJsonBasicAuthTest extends BlockResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class BlockHalJsonCookieTest extends BlockResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the block administration page for a non-default theme.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class NonDefaultBlockAdminTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test non-default theme admin.
|
||||
*/
|
||||
public function testNonDefaultBlockAdmin() {
|
||||
$admin_user = $this->drupalCreateUser(['administer blocks', 'administer themes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$new_theme = 'bartik';
|
||||
\Drupal::service('theme_handler')->install([$new_theme]);
|
||||
$this->drupalGet('admin/structure/block/list/' . $new_theme);
|
||||
$this->assertText('Bartik(' . t('active tab') . ')', 'Tab for non-default theme found.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockJsonAnonTest extends BlockResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockJsonBasicAuthTest extends BlockResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockJsonCookieTest extends BlockResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
abstract class BlockResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'block';
|
||||
|
||||
/**
|
||||
* @var \Drupal\block\BlockInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$this->entity->setVisibilityConfig('user_role', [])->save();
|
||||
break;
|
||||
case 'POST':
|
||||
$this->grantPermissionsToTestedRole(['administer blocks']);
|
||||
break;
|
||||
case 'PATCH':
|
||||
$this->grantPermissionsToTestedRole(['administer blocks']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$block = Block::create([
|
||||
'plugin' => 'llama_block',
|
||||
'region' => 'header',
|
||||
'id' => 'llama',
|
||||
'theme' => 'classy',
|
||||
]);
|
||||
// All blocks can be viewed by the anonymous user by default. An interesting
|
||||
// side effect of this is that any anonymous user is also able to read the
|
||||
// corresponding block config entity via REST, even if an authentication
|
||||
// provider is configured for the block config entity REST resource! In
|
||||
// other words: Block entities do not distinguish between 'view' as in
|
||||
// "render on a page" and 'view' as in "read the configuration".
|
||||
// This prevents that.
|
||||
// @todo Fix this in https://www.drupal.org/node/2820315.
|
||||
$block->setVisibilityConfig('user_role', [
|
||||
'id' => 'user_role',
|
||||
'roles' => ['non-existing-role' => 'non-existing-role'],
|
||||
'negate' => FALSE,
|
||||
'context_mapping' => [
|
||||
'user' => '@user.current_user_context:current_user',
|
||||
],
|
||||
]);
|
||||
$block->save();
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$normalization = [
|
||||
'uuid' => $this->entity->uuid(),
|
||||
'id' => 'llama',
|
||||
'weight' => NULL,
|
||||
'langcode' => 'en',
|
||||
'status' => TRUE,
|
||||
'dependencies' => [
|
||||
'theme' => [
|
||||
'classy',
|
||||
],
|
||||
],
|
||||
'theme' => 'classy',
|
||||
'region' => 'header',
|
||||
'provider' => NULL,
|
||||
'plugin' => 'llama_block',
|
||||
'settings' => [
|
||||
'id' => 'broken',
|
||||
'label' => '',
|
||||
'provider' => 'core',
|
||||
'label_display' => 'visible',
|
||||
],
|
||||
'visibility' => [],
|
||||
];
|
||||
|
||||
return $normalization;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
// @see ::createEntity()
|
||||
return ['url.site'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheTags() {
|
||||
// Because the 'user.permissions' cache context is missing, the cache tag
|
||||
// for the anonymous user role is never added automatically.
|
||||
return array_values(array_diff(parent::getExpectedCacheTags(), ['config:user.role.anonymous']));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return "You are not authorized to view this block entity.";
|
||||
default:
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessCacheability() {
|
||||
// @see \Drupal\block\BlockAccessControlHandler::checkAccess()
|
||||
return parent::getExpectedUnauthorizedAccessCacheability()
|
||||
->setCacheTags([
|
||||
'4xx-response',
|
||||
'config:block.block.llama',
|
||||
'http_response',
|
||||
static::$auth ? 'user:2' : 'user:0',
|
||||
])
|
||||
->setCacheContexts(['user.roles']);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockXmlAnonTest extends BlockResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockXmlBasicAuthTest extends BlockResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class BlockXmlCookieTest extends BlockResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for block with conditions missing context.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2811519
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class BlockConditionMissingSchemaUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* This test does not have a failed update but the configuration has missing
|
||||
* schema so can not do the full post update testing offered by
|
||||
* UpdatePathTestBase.
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @see \Drupal\system\Tests\Update\UpdatePathTestBase::runUpdates()
|
||||
*/
|
||||
protected $checkFailedUpdates = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['block_test', 'language'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.block-test-enabled-missing-schema.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that block context mapping is updated properly.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
$this->runUpdates();
|
||||
$this->drupalGet('<front>');
|
||||
// If the block is fixed by block_post_update_fix_negate_in_conditions()
|
||||
// then it will be visible.
|
||||
$this->assertText('Test missing schema on conditions');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Update;
|
||||
|
||||
/**
|
||||
* Runs BlockContextMappingUpdateTest with a dump filled with content.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class BlockContextMappingUpdateFilledTest extends BlockContextMappingUpdateTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
parent::setDatabaseDumpFiles();
|
||||
$this->databaseDumpFiles[0] = __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Update;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for block context mapping renames.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2354889
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class BlockContextMappingUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['block_test', 'language'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php',
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.language-enabled.php',
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.block-test-enabled.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that block context mapping is updated properly.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
$this->runUpdates();
|
||||
$this->assertRaw('Encountered an unknown context mapping key coming probably from a contributed or custom module: One or more mappings could not be updated. Please manually review your visibility settings for the following blocks, which are disabled now:<ul><li>User login (Visibility: Baloney spam)</li></ul>');
|
||||
|
||||
// Disable maintenance mode.
|
||||
\Drupal::state()->set('system.maintenance_mode', FALSE);
|
||||
|
||||
// We finished updating so we can log in the user now.
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// The block that we are testing has the following visibility rules:
|
||||
// - only visible on node pages
|
||||
// - only visible to authenticated users.
|
||||
$block_title = 'Test for 2354889';
|
||||
|
||||
// Create two nodes, a page and an article.
|
||||
$page = Node::create([
|
||||
'type' => 'page',
|
||||
'title' => 'Page node',
|
||||
]);
|
||||
$page->save();
|
||||
|
||||
$article = Node::create([
|
||||
'type' => 'article',
|
||||
'title' => 'Article node',
|
||||
]);
|
||||
$article->save();
|
||||
|
||||
// Check that the block appears only on Page nodes for authenticated users.
|
||||
$this->drupalGet('node/' . $page->id());
|
||||
$this->assertRaw($block_title, 'Test block is visible on a Page node as an authenticated user.');
|
||||
|
||||
$this->drupalGet('node/' . $article->id());
|
||||
$this->assertNoRaw($block_title, 'Test block is not visible on a Article node as an authenticated user.');
|
||||
|
||||
$this->drupalLogout();
|
||||
|
||||
// Check that the block does not appear on any page for anonymous users.
|
||||
$this->drupalGet('node/' . $page->id());
|
||||
$this->assertNoRaw($block_title, 'Test block is not visible on a Page node as an anonymous user.');
|
||||
|
||||
$this->drupalGet('node/' . $article->id());
|
||||
$this->assertNoRaw($block_title, 'Test block is not visible on a Article node as an anonymous user.');
|
||||
|
||||
// Ensure that all the context mappings got updated properly.
|
||||
$block = Block::load('testfor2354889');
|
||||
$visibility = $block->get('visibility');
|
||||
$this->assertEqual('@node.node_route_context:node', $visibility['node_type']['context_mapping']['node']);
|
||||
$this->assertEqual('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
|
||||
$this->assertEqual('@language.current_language_context:language_interface', $visibility['language']['context_mapping']['language']);
|
||||
|
||||
// Check that a block with invalid context is being disabled and that it can
|
||||
// still be edited afterward.
|
||||
$disabled_block = Block::load('thirdtestfor2354889');
|
||||
$this->assertFalse($disabled_block->status(), 'Block with invalid context is disabled');
|
||||
|
||||
$this->assertEqual(['thirdtestfor2354889' => ['missing_context_ids' => ['baloney_spam' => ['node_type']], 'status' => TRUE]], \Drupal::keyValue('update_backup')->get('block_update_8001'));
|
||||
|
||||
$disabled_block_visibility = $disabled_block->get('visibility');
|
||||
$this->assertTrue(!isset($disabled_block_visibility['node_type']), 'The problematic visibility condition has been removed.');
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['administer blocks']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->drupalGet('admin/structure/block/manage/thirdtestfor2354889');
|
||||
$this->assertResponse('200');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for removal of disabled region.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2513534
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class BlockRemoveDisabledRegionUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['block_test', 'language'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.update-test-block-disabled-2513534.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that block context mapping is updated properly.
|
||||
*/
|
||||
public function testUpdateHookN() {
|
||||
$this->runUpdates();
|
||||
|
||||
// Disable maintenance mode.
|
||||
\Drupal::state()->set('system.maintenance_mode', FALSE);
|
||||
|
||||
// We finished updating so we can login the user now.
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Verify that a disabled block is in the default region.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$element = $this->xpath("//tr[contains(@data-drupal-selector, :block) and contains(@class, :status)]//select/option[@selected and @value=:region]",
|
||||
[':block' => 'edit-blocks-pagetitle-1', ':status' => 'block-disabled', ':region' => 'header']);
|
||||
$this->assertTrue(!empty($element));
|
||||
|
||||
// Verify that an enabled block is now disabled and in the default region.
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$element = $this->xpath("//tr[contains(@data-drupal-selector, :block) and contains(@class, :status)]//select/option[@selected and @value=:region]",
|
||||
[':block' => 'edit-blocks-pagetitle-2', ':status' => 'block-disabled', ':region' => 'header']);
|
||||
$this->assertTrue(!empty($element));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,383 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Functional\Views;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\block\Functional\AssertBlockAppearsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\Core\Template\Attribute;
|
||||
|
||||
/**
|
||||
* Tests the block display plugin.
|
||||
*
|
||||
* @group block
|
||||
* @see \Drupal\views\Plugin\views\display\Block
|
||||
*/
|
||||
class DisplayBlockTest extends ViewTestBase {
|
||||
|
||||
use AssertPageCacheContextsAndTagsTrait;
|
||||
use AssertBlockAppearsTrait;
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'block_test_views', 'test_page_test', 'contextual', 'views_ui'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_view_block', 'test_view_block2'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['block_test_views']);
|
||||
$this->enableViewsTestModule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests default and custom block categories.
|
||||
*/
|
||||
public function testBlockCategory() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer views', 'administer blocks']));
|
||||
|
||||
// Create a new view in the UI.
|
||||
$edit = [];
|
||||
$edit['label'] = $this->randomString();
|
||||
$edit['id'] = strtolower($this->randomMachineName());
|
||||
$edit['show[wizard_key]'] = 'standard:views_test_data';
|
||||
$edit['description'] = $this->randomString();
|
||||
$edit['block[create]'] = TRUE;
|
||||
$edit['block[style][row_plugin]'] = 'fields';
|
||||
$this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit'));
|
||||
|
||||
$pattern = '//tr[.//td[text()=:category] and .//td//a[contains(@href, :href)]]';
|
||||
|
||||
// Test that the block was given a default category corresponding to its
|
||||
// base table.
|
||||
$arguments = [
|
||||
':href' => \Drupal::Url('block.admin_add', [
|
||||
'plugin_id' => 'views_block:' . $edit['id'] . '-block_1',
|
||||
'theme' => 'classy',
|
||||
]),
|
||||
':category' => 'Lists (Views)',
|
||||
];
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The test block appears in the category for its base table.');
|
||||
|
||||
// Duplicate the block before changing the category.
|
||||
$this->drupalPostForm('admin/structure/views/view/' . $edit['id'] . '/edit/block_1', [], t('Duplicate @display_title', ['@display_title' => 'Block']));
|
||||
$this->assertUrl('admin/structure/views/view/' . $edit['id'] . '/edit/block_2');
|
||||
|
||||
// Change the block category to a random string.
|
||||
$this->drupalGet('admin/structure/views/view/' . $edit['id'] . '/edit/block_1');
|
||||
$link = $this->xpath('//a[@id="views-block-1-block-category" and normalize-space(text())=:category]', $arguments);
|
||||
$this->assertTrue(!empty($link));
|
||||
$this->clickLink(t('Lists (Views)'));
|
||||
$category = $this->randomString();
|
||||
$this->drupalPostForm(NULL, ['block_category' => $category], t('Apply'));
|
||||
|
||||
// Duplicate the block after changing the category.
|
||||
$this->drupalPostForm(NULL, [], t('Duplicate @display_title', ['@display_title' => 'Block']));
|
||||
$this->assertUrl('admin/structure/views/view/' . $edit['id'] . '/edit/block_3');
|
||||
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
// Test that the blocks are listed under the correct categories.
|
||||
$arguments[':category'] = $category;
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$this->clickLink('Place block');
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The test block appears in the custom category.');
|
||||
|
||||
$arguments = [
|
||||
':href' => \Drupal::Url('block.admin_add', [
|
||||
'plugin_id' => 'views_block:' . $edit['id'] . '-block_2',
|
||||
'theme' => 'classy',
|
||||
]),
|
||||
':category' => 'Lists (Views)',
|
||||
];
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The first duplicated test block remains in the original category.');
|
||||
|
||||
$arguments = [
|
||||
':href' => \Drupal::Url('block.admin_add', [
|
||||
'plugin_id' => 'views_block:' . $edit['id'] . '-block_3',
|
||||
'theme' => 'classy',
|
||||
]),
|
||||
':category' => $category,
|
||||
];
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue(!empty($elements), 'The second duplicated test block appears in the custom category.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests removing a block display.
|
||||
*/
|
||||
public function testDeleteBlockDisplay() {
|
||||
// To test all combinations possible we first place create two instances
|
||||
// of the block display of the first view.
|
||||
$block_1 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', ['label' => 'test_view_block-block_1:1']);
|
||||
$block_2 = $this->drupalPlaceBlock('views_block:test_view_block-block_1', ['label' => 'test_view_block-block_1:2']);
|
||||
|
||||
// Then we add one instance of blocks for each of the two displays of the
|
||||
// second view.
|
||||
$block_3 = $this->drupalPlaceBlock('views_block:test_view_block2-block_1', ['label' => 'test_view_block2-block_1']);
|
||||
$block_4 = $this->drupalPlaceBlock('views_block:test_view_block2-block_2', ['label' => 'test_view_block2-block_2']);
|
||||
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertBlockAppears($block_1);
|
||||
$this->assertBlockAppears($block_2);
|
||||
$this->assertBlockAppears($block_3);
|
||||
$this->assertBlockAppears($block_4);
|
||||
|
||||
$block_storage = $this->container->get('entity_type.manager')->getStorage('block');
|
||||
|
||||
// Remove the block display, so both block entities from the first view
|
||||
// should both disappear.
|
||||
$view = Views::getView('test_view_block');
|
||||
$view->initDisplay();
|
||||
$view->displayHandlers->remove('block_1');
|
||||
$view->storage->save();
|
||||
|
||||
$this->assertFalse($block_storage->load($block_1->id()), 'The block for this display was removed.');
|
||||
$this->assertFalse($block_storage->load($block_2->id()), 'The block for this display was removed.');
|
||||
$this->assertTrue($block_storage->load($block_3->id()), 'A block from another view was unaffected.');
|
||||
$this->assertTrue($block_storage->load($block_4->id()), 'A block from another view was unaffected.');
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertNoBlockAppears($block_1);
|
||||
$this->assertNoBlockAppears($block_2);
|
||||
$this->assertBlockAppears($block_3);
|
||||
$this->assertBlockAppears($block_4);
|
||||
|
||||
// Remove the first block display of the second view and ensure the block
|
||||
// instance of the second block display still exists.
|
||||
$view = Views::getView('test_view_block2');
|
||||
$view->initDisplay();
|
||||
$view->displayHandlers->remove('block_1');
|
||||
$view->storage->save();
|
||||
|
||||
$this->assertFalse($block_storage->load($block_3->id()), 'The block for this display was removed.');
|
||||
$this->assertTrue($block_storage->load($block_4->id()), 'A block from another display on the same view was unaffected.');
|
||||
$this->drupalGet('test-page');
|
||||
$this->assertNoBlockAppears($block_3);
|
||||
$this->assertBlockAppears($block_4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the block form for a Views block.
|
||||
*/
|
||||
public function testViewsBlockForm() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer blocks']));
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$this->drupalGet('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme);
|
||||
$elements = $this->xpath('//input[@name="label"]');
|
||||
$this->assertTrue(empty($elements), 'The label field is not found for Views blocks.');
|
||||
// Test that that machine name field is hidden from display and has been
|
||||
// saved as expected from the default value.
|
||||
$this->assertNoFieldById('edit-machine-name', 'views_block__test_view_block_1', 'The machine name is hidden on the views block form.');
|
||||
|
||||
// Save the block.
|
||||
$edit = ['region' => 'content'];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save block'));
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage('block');
|
||||
$block = $storage->load('views_block__test_view_block_block_1');
|
||||
// This will only return a result if our new block has been created with the
|
||||
// expected machine name.
|
||||
$this->assertTrue(!empty($block), 'The expected block was loaded.');
|
||||
|
||||
for ($i = 2; $i <= 3; $i++) {
|
||||
// Place the same block again and make sure we have a new ID.
|
||||
$this->drupalPostForm('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme, $edit, t('Save block'));
|
||||
$block = $storage->load('views_block__test_view_block_block_1_' . $i);
|
||||
// This will only return a result if our new block has been created with the
|
||||
// expected machine name.
|
||||
$this->assertTrue(!empty($block), 'The expected block was loaded.');
|
||||
}
|
||||
|
||||
// Tests the override capability of items per page.
|
||||
$this->drupalGet('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme);
|
||||
$edit = ['region' => 'content'];
|
||||
$edit['settings[override][items_per_page]'] = 10;
|
||||
|
||||
$this->drupalPostForm('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme, $edit, t('Save block'));
|
||||
|
||||
$block = $storage->load('views_block__test_view_block_block_1_4');
|
||||
$config = $block->getPlugin()->getConfiguration();
|
||||
$this->assertEqual(10, $config['items_per_page'], "'Items per page' is properly saved.");
|
||||
|
||||
$edit['settings[override][items_per_page]'] = 5;
|
||||
$this->drupalPostForm('admin/structure/block/manage/views_block__test_view_block_block_1_4', $edit, t('Save block'));
|
||||
|
||||
$block = $storage->load('views_block__test_view_block_block_1_4');
|
||||
|
||||
$config = $block->getPlugin()->getConfiguration();
|
||||
$this->assertEqual(5, $config['items_per_page'], "'Items per page' is properly saved.");
|
||||
|
||||
// Tests the override of the label capability.
|
||||
$edit = ['region' => 'content'];
|
||||
$edit['settings[views_label_checkbox]'] = 1;
|
||||
$edit['settings[views_label]'] = 'Custom title';
|
||||
$this->drupalPostForm('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme, $edit, t('Save block'));
|
||||
|
||||
$block = $storage->load('views_block__test_view_block_block_1_5');
|
||||
$config = $block->getPlugin()->getConfiguration();
|
||||
$this->assertEqual('Custom title', $config['views_label'], "'Label' is properly saved.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the actual rendering of the views block.
|
||||
*/
|
||||
public function testBlockRendering() {
|
||||
// Create a block and set a custom title.
|
||||
$block = $this->drupalPlaceBlock('views_block:test_view_block-block_1', ['label' => 'test_view_block-block_1:1', 'views_label' => 'Custom title']);
|
||||
$this->drupalGet('');
|
||||
|
||||
$result = $this->xpath('//div[contains(@class, "region-sidebar-first")]/div[contains(@class, "block-views")]/h2');
|
||||
$this->assertEqual($result[0]->getText(), 'Custom title');
|
||||
|
||||
// Don't override the title anymore.
|
||||
$plugin = $block->getPlugin();
|
||||
$plugin->setConfigurationValue('views_label', '');
|
||||
$block->save();
|
||||
|
||||
$this->drupalGet('');
|
||||
$result = $this->xpath('//div[contains(@class, "region-sidebar-first")]/div[contains(@class, "block-views")]/h2');
|
||||
$this->assertEqual($result[0]->getText(), 'test_view_block');
|
||||
|
||||
// Hide the title.
|
||||
$block->getPlugin()->setConfigurationValue('label_display', FALSE);
|
||||
$block->save();
|
||||
|
||||
$this->drupalGet('');
|
||||
$result = $this->xpath('//div[contains(@class, "region-sidebar-first")]/div[contains(@class, "block-views")]/h2');
|
||||
$this->assertTrue(empty($result), 'The title is not visible.');
|
||||
|
||||
$this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:system.site', 'config:views.view.test_view_block', 'http_response', 'rendered']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the various testcases of empty block rendering.
|
||||
*/
|
||||
public function testBlockEmptyRendering() {
|
||||
$url = new Url('test_page_test.test_page');
|
||||
// Remove all views_test_data entries.
|
||||
\Drupal::database()->truncate('views_test_data')->execute();
|
||||
/** @var \Drupal\views\ViewEntityInterface $view */
|
||||
$view = View::load('test_view_block');
|
||||
$view->invalidateCaches();
|
||||
|
||||
$block = $this->drupalPlaceBlock('views_block:test_view_block-block_1', ['label' => 'test_view_block-block_1:1', 'views_label' => 'Custom title']);
|
||||
$this->drupalGet('');
|
||||
$this->assertEqual(1, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
|
||||
|
||||
$display = &$view->getDisplay('block_1');
|
||||
$display['display_options']['block_hide_empty'] = TRUE;
|
||||
$view->save();
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertEqual(0, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
|
||||
// Ensure that the view cacheability metadata is propagated even, for an
|
||||
// empty block.
|
||||
$this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
|
||||
$this->assertCacheContexts(['url.query_args:_wrapper_format']);
|
||||
|
||||
// Add a header displayed on empty result.
|
||||
$display = &$view->getDisplay('block_1');
|
||||
$display['display_options']['defaults']['header'] = FALSE;
|
||||
$display['display_options']['header']['example'] = [
|
||||
'field' => 'area_text_custom',
|
||||
'id' => 'area_text_custom',
|
||||
'table' => 'views',
|
||||
'plugin_id' => 'text_custom',
|
||||
'content' => 'test header',
|
||||
'empty' => TRUE,
|
||||
];
|
||||
$view->save();
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertEqual(1, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
|
||||
$this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
|
||||
$this->assertCacheContexts(['url.query_args:_wrapper_format']);
|
||||
|
||||
// Hide the header on empty results.
|
||||
$display = &$view->getDisplay('block_1');
|
||||
$display['display_options']['defaults']['header'] = FALSE;
|
||||
$display['display_options']['header']['example'] = [
|
||||
'field' => 'area_text_custom',
|
||||
'id' => 'area_text_custom',
|
||||
'table' => 'views',
|
||||
'plugin_id' => 'text_custom',
|
||||
'content' => 'test header',
|
||||
'empty' => FALSE,
|
||||
];
|
||||
$view->save();
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertEqual(0, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
|
||||
$this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
|
||||
$this->assertCacheContexts(['url.query_args:_wrapper_format']);
|
||||
|
||||
// Add an empty text.
|
||||
$display = &$view->getDisplay('block_1');
|
||||
$display['display_options']['defaults']['empty'] = FALSE;
|
||||
$display['display_options']['empty']['example'] = [
|
||||
'field' => 'area_text_custom',
|
||||
'id' => 'area_text_custom',
|
||||
'table' => 'views',
|
||||
'plugin_id' => 'text_custom',
|
||||
'content' => 'test empty',
|
||||
];
|
||||
$view->save();
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertEqual(1, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
|
||||
$this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block', 'http_response', 'rendered']));
|
||||
$this->assertCacheContexts(['url.query_args:_wrapper_format']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the contextual links on a Views block.
|
||||
*/
|
||||
public function testBlockContextualLinks() {
|
||||
$this->drupalLogin($this->drupalCreateUser(['administer views', 'access contextual links', 'administer blocks']));
|
||||
$block = $this->drupalPlaceBlock('views_block:test_view_block-block_1');
|
||||
$cached_block = $this->drupalPlaceBlock('views_block:test_view_block-block_1');
|
||||
$this->drupalGet('test-page');
|
||||
|
||||
$id = 'block:block=' . $block->id() . ':langcode=en|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1&langcode=en';
|
||||
$id_token = Crypt::hmacBase64($id, Settings::getHashSalt() . $this->container->get('private_key')->get());
|
||||
$cached_id = 'block:block=' . $cached_block->id() . ':langcode=en|entity.view.edit_form:view=test_view_block:location=block&name=test_view_block&display_id=block_1&langcode=en';
|
||||
$cached_id_token = Crypt::hmacBase64($cached_id, Settings::getHashSalt() . $this->container->get('private_key')->get());
|
||||
// @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder()
|
||||
$this->assertRaw('<div' . new Attribute(['data-contextual-id' => $id, 'data-contextual-token' => $id_token]) . '></div>', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id]));
|
||||
$this->assertRaw('<div' . new Attribute(['data-contextual-id' => $cached_id, 'data-contextual-token' => $cached_id_token]) . '></div>', format_string('Contextual link placeholder with id @id exists.', ['@id' => $cached_id]));
|
||||
|
||||
// Get server-rendered contextual links.
|
||||
// @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks()
|
||||
$post = ['ids[0]' => $id, 'ids[1]' => $cached_id, 'tokens[0]' => $id_token, 'tokens[1]' => $cached_id_token];
|
||||
$url = 'contextual/render?_format=json,destination=test-page';
|
||||
$this->getSession()->getDriver()->getClient()->request('POST', $url, $post);
|
||||
$this->assertResponse(200);
|
||||
$json = Json::decode($this->getSession()->getPage()->getContent());
|
||||
$this->assertIdentical($json[$id], '<ul class="contextual-links"><li class="block-configure"><a href="' . base_path() . 'admin/structure/block/manage/' . $block->id() . '">Configure block</a></li><li class="entityviewedit-form"><a href="' . base_path() . 'admin/structure/views/view/test_view_block/edit/block_1">Edit view</a></li></ul>');
|
||||
$this->assertIdentical($json[$cached_id], '<ul class="contextual-links"><li class="block-configure"><a href="' . base_path() . 'admin/structure/block/manage/' . $cached_block->id() . '">Configure block</a></li><li class="entityviewedit-form"><a href="' . base_path() . 'admin/structure/views/view/test_view_block/edit/block_1">Edit view</a></li></ul>');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\FunctionalJavascript;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests the JavaScript functionality of the block add filter.
|
||||
*
|
||||
* @group block
|
||||
*/
|
||||
class BlockFilterTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['user', 'block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
]);
|
||||
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests block filter.
|
||||
*/
|
||||
public function testBlockFilter() {
|
||||
$this->drupalGet('admin/structure/block');
|
||||
$assertSession = $this->assertSession();
|
||||
$session = $this->getSession();
|
||||
$page = $session->getPage();
|
||||
|
||||
// Find the block filter field on the add-block dialog.
|
||||
$page->find('css', '#edit-blocks-region-header-title')->click();
|
||||
$filter = $assertSession->waitForElement('css', '.block-filter-text');
|
||||
|
||||
// Get all block rows, for assertions later.
|
||||
$block_rows = $page->findAll('css', '.block-add-table tbody tr');
|
||||
|
||||
// Test block filter reduces the number of visible rows.
|
||||
$filter->setValue('ad');
|
||||
$session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("blocks are available") > -1');
|
||||
$visible_rows = $this->filterVisibleElements($block_rows);
|
||||
if (count($block_rows) > 0) {
|
||||
$this->assertNotEquals(count($block_rows), count($visible_rows));
|
||||
}
|
||||
|
||||
// Test Drupal.announce() message when multiple matches are expected.
|
||||
$expected_message = count($visible_rows) . ' blocks are available in the modified list.';
|
||||
$assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message);
|
||||
|
||||
// Test Drupal.announce() message when only one match is expected.
|
||||
$filter->setValue('Powered by');
|
||||
$session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("block is available") > -1');
|
||||
$visible_rows = $this->filterVisibleElements($block_rows);
|
||||
$this->assertEquals(1, count($visible_rows));
|
||||
$expected_message = '1 block is available in the modified list.';
|
||||
$assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message);
|
||||
|
||||
// Test Drupal.announce() message when no matches are expected.
|
||||
$filter->setValue('Pan-Galactic Gargle Blaster');
|
||||
$session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("0 blocks are available") > -1');
|
||||
$visible_rows = $this->filterVisibleElements($block_rows);
|
||||
$this->assertEquals(0, count($visible_rows));
|
||||
$expected_message = '0 blocks are available in the modified list.';
|
||||
$assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any non-visible elements from the passed array.
|
||||
*
|
||||
* @param \Behat\Mink\Element\NodeElement[] $elements
|
||||
* An array of node elements.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement[]
|
||||
*/
|
||||
protected function filterVisibleElements(array $elements) {
|
||||
$elements = array_filter($elements, function (NodeElement $element) {
|
||||
return $element->isVisible();
|
||||
});
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,7 +47,8 @@ class BlockRebuildTest extends KernelTestBase {
|
|||
*/
|
||||
public function testRebuildNoBlocks() {
|
||||
block_rebuild();
|
||||
$messages = drupal_get_messages();
|
||||
$messages = \Drupal::messenger()->all();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
$this->assertEquals([], $messages);
|
||||
}
|
||||
|
||||
|
@ -58,7 +59,8 @@ class BlockRebuildTest extends KernelTestBase {
|
|||
$this->placeBlock('system_powered_by_block', ['region' => 'content']);
|
||||
|
||||
block_rebuild();
|
||||
$messages = drupal_get_messages();
|
||||
$messages = \Drupal::messenger()->all();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
$this->assertEquals([], $messages);
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,8 @@ class BlockRebuildTest extends KernelTestBase {
|
|||
$block1 = Block::load($block1->id());
|
||||
$block2 = Block::load($block2->id());
|
||||
|
||||
$messages = drupal_get_messages();
|
||||
$messages = \Drupal::messenger()->all();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
$expected = ['warning' => [new TranslatableMarkup('The block %info was assigned to the invalid region %region and has been disabled.', ['%info' => $block1->id(), '%region' => 'INVALID'])]];
|
||||
$this->assertEquals($expected, $messages);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class BlockStorageUnitTest extends KernelTestBase {
|
|||
/**
|
||||
* The block storage.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface.
|
||||
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration of i18n block translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateBlockContentTranslationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'aggregator',
|
||||
'book',
|
||||
'block',
|
||||
'comment',
|
||||
'forum',
|
||||
'views',
|
||||
'block_content',
|
||||
'content_translation',
|
||||
'language',
|
||||
'statistics',
|
||||
'taxonomy',
|
||||
// Required for translation migrations.
|
||||
'migrate_drupal_multilingual',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['block']);
|
||||
$this->installConfig(['block_content']);
|
||||
$this->installEntitySchema('block_content');
|
||||
|
||||
$this->executeMigrations([
|
||||
'd6_filter_format',
|
||||
'block_content_type',
|
||||
'block_content_body_field',
|
||||
'd6_custom_block',
|
||||
'd6_user_role',
|
||||
'd6_block',
|
||||
'd6_block_translation',
|
||||
]);
|
||||
block_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the migration of block title translation.
|
||||
*/
|
||||
public function testBlockContentTranslation() {
|
||||
/** @var \Drupal\language\ConfigurableLanguageManagerInterface $language_manager */
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
$config = $language_manager->getLanguageConfigOverride('zu', 'block.block.user_1');
|
||||
$this->assertSame('zu - Navigation', $config->get('settings.label'));
|
||||
}
|
||||
|
||||
}
|
|
@ -116,9 +116,9 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
|||
$visibility = [];
|
||||
$settings = [
|
||||
'id' => 'system_menu_block',
|
||||
'label' => '',
|
||||
'label' => 'zu - Navigation',
|
||||
'provider' => 'system',
|
||||
'label_display' => '0',
|
||||
'label_display' => 'visible',
|
||||
'level' => 1,
|
||||
'depth' => 0,
|
||||
];
|
||||
|
|
|
@ -87,7 +87,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
|
|||
'schema_version' => '6055',
|
||||
'weight' => '0',
|
||||
'info' => 'a:0:{}',
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
// The expected results.
|
||||
|
@ -104,7 +104,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
|
|||
'pages' => '',
|
||||
'title' => 'Test Title 01',
|
||||
'cache' => -1,
|
||||
'roles' => [2]
|
||||
'roles' => [2],
|
||||
],
|
||||
[
|
||||
'bid' => 2,
|
||||
|
@ -118,7 +118,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
|
|||
'pages' => '<front>',
|
||||
'title' => 'Test Title 02',
|
||||
'cache' => -1,
|
||||
'roles' => [2]
|
||||
'roles' => [2],
|
||||
],
|
||||
];
|
||||
return $tests;
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\block\Kernel\Plugin\migrate\source\BlockTest;
|
||||
|
||||
/**
|
||||
* Tests i18n block source plugin.
|
||||
*
|
||||
* @covers \Drupal\block\Plugin\migrate\source\d6\BlockTranslation
|
||||
*
|
||||
* @group content_translation
|
||||
*/
|
||||
class BlockTranslationTest extends BlockTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
// Test data is the same as BlockTest, but with the addition of i18n_blocks.
|
||||
$tests = parent::providerSource();
|
||||
|
||||
// The source data.
|
||||
$tests[0]['source_data']['i18n_blocks'] = [
|
||||
[
|
||||
'ibid' => 1,
|
||||
'module' => 'block',
|
||||
'delta' => '1',
|
||||
'type' => 0,
|
||||
'language' => 'fr',
|
||||
],
|
||||
[
|
||||
'ibid' => 2,
|
||||
'module' => 'block',
|
||||
'delta' => '2',
|
||||
'type' => 0,
|
||||
'language' => 'zu',
|
||||
],
|
||||
];
|
||||
$tests[0]['source_data']['variables'] = [
|
||||
[
|
||||
'name' => 'default_theme',
|
||||
'value' => 's:7:"garland";',
|
||||
],
|
||||
];
|
||||
// The expected results.
|
||||
$tests[0]['expected_data'] = [
|
||||
[
|
||||
'bid' => 1,
|
||||
'module' => 'block',
|
||||
'delta' => '1',
|
||||
'title' => 'Test Title 01',
|
||||
'ibid' => 1,
|
||||
'type' => '0',
|
||||
'language' => 'fr',
|
||||
'default_theme' => 'Garland',
|
||||
],
|
||||
[
|
||||
'bid' => 2,
|
||||
'module' => 'block',
|
||||
'delta' => '2',
|
||||
'theme' => 'garland',
|
||||
'title' => 'Test Title 02',
|
||||
'ibid' => 2,
|
||||
'type' => '0',
|
||||
'language' => 'zu',
|
||||
'default_theme' => 'Garland',
|
||||
],
|
||||
];
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\block\Traits;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
|
||||
/**
|
||||
* Provides methods to create and place block with default settings.
|
||||
*
|
||||
* This trait is meant to be used only by test classes.
|
||||
*/
|
||||
trait BlockCreationTrait {
|
||||
|
||||
/**
|
||||
* Creates a block instance based on default settings.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The plugin ID of the block type for this block instance.
|
||||
* @param array $settings
|
||||
* (optional) An associative array of settings for the block entity.
|
||||
* Override the defaults by specifying the key and value in the array, for
|
||||
* example:
|
||||
* @code
|
||||
* $this->drupalPlaceBlock('system_powered_by_block', array(
|
||||
* 'label' => t('Hello, world!'),
|
||||
* ));
|
||||
* @endcode
|
||||
* The following defaults are provided:
|
||||
* - label: Random string.
|
||||
* - ID: Random string.
|
||||
* - region: 'sidebar_first'.
|
||||
* - theme: The default theme.
|
||||
* - visibility: Empty array.
|
||||
*
|
||||
* @return \Drupal\block\Entity\Block
|
||||
* The block entity.
|
||||
*
|
||||
* @todo
|
||||
* Add support for creating custom block instances.
|
||||
*/
|
||||
protected function placeBlock($plugin_id, array $settings = []) {
|
||||
$config = \Drupal::configFactory();
|
||||
$settings += [
|
||||
'plugin' => $plugin_id,
|
||||
'region' => 'sidebar_first',
|
||||
'id' => strtolower($this->randomMachineName(8)),
|
||||
'theme' => $config->get('system.theme')->get('default'),
|
||||
'label' => $this->randomMachineName(8),
|
||||
'visibility' => [],
|
||||
'weight' => 0,
|
||||
];
|
||||
$values = [];
|
||||
foreach (['region', 'id', 'theme', 'plugin', 'weight', 'visibility'] as $key) {
|
||||
$values[$key] = $settings[$key];
|
||||
// Remove extra values that do not belong in the settings array.
|
||||
unset($settings[$key]);
|
||||
}
|
||||
foreach ($values['visibility'] as $id => $visibility) {
|
||||
$values['visibility'][$id]['id'] = $id;
|
||||
}
|
||||
$values['settings'] = $settings;
|
||||
$block = Block::create($values);
|
||||
$block->save();
|
||||
return $block;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\block\Unit;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Tests\Core\Plugin\Fixtures\TestConfigurablePlugin;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -20,11 +21,11 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
|||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The entity manager used for testing.
|
||||
* The entity type manager used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityManager;
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* The ID of the type of the entity under test.
|
||||
|
@ -51,8 +52,8 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
|||
->method('getProvider')
|
||||
->will($this->returnValue('block'));
|
||||
|
||||
$this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
|
||||
$this->entityManager->expects($this->any())
|
||||
$this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
|
||||
$this->entityTypeManager->expects($this->any())
|
||||
->method('getDefinition')
|
||||
->with($this->entityTypeId)
|
||||
->will($this->returnValue($this->entityType));
|
||||
|
@ -60,7 +61,7 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
|||
$this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container->set('entity.manager', $this->entityManager);
|
||||
$container->set('entity_type.manager', $this->entityTypeManager);
|
||||
$container->set('uuid', $this->uuid);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
namespace Drupal\Tests\block\Unit;
|
||||
|
||||
use Drupal\block\BlockForm;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
use Drupal\Core\Plugin\PluginFormFactoryInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
|
@ -82,6 +84,32 @@ class BlockFormTest extends UnitTestCase {
|
|||
$this->pluginFormFactory = $this->prophesize(PluginFormFactoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks a block with a block plugin.
|
||||
*
|
||||
* @param string $machine_name
|
||||
* The machine name of the block plugin.
|
||||
*
|
||||
* @return \Drupal\block\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* The mocked block.
|
||||
*/
|
||||
protected function getBlockMockWithMachineName($machine_name) {
|
||||
$plugin = $this->getMockBuilder(BlockBase::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$plugin->expects($this->any())
|
||||
->method('getMachineNameSuggestion')
|
||||
->will($this->returnValue($machine_name));
|
||||
|
||||
$block = $this->getMockBuilder(Block::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$block->expects($this->any())
|
||||
->method('getPlugin')
|
||||
->will($this->returnValue($plugin));
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the unique machine name generator.
|
||||
*
|
||||
|
|
|
@ -118,21 +118,21 @@ class BlockRepositoryTest extends UnitTestCase {
|
|||
public function providerBlocksConfig() {
|
||||
$blocks_config = [
|
||||
'block1' => [
|
||||
AccessResult::allowed(), 'top', 0
|
||||
AccessResult::allowed(), 'top', 0,
|
||||
],
|
||||
// Test a block without access.
|
||||
'block2' => [
|
||||
AccessResult::forbidden(), 'bottom', 0
|
||||
AccessResult::forbidden(), 'bottom', 0,
|
||||
],
|
||||
// Test some blocks in the same region with specific weight.
|
||||
'block4' => [
|
||||
AccessResult::allowed(), 'bottom', 5
|
||||
AccessResult::allowed(), 'bottom', 5,
|
||||
],
|
||||
'block3' => [
|
||||
AccessResult::allowed(), 'bottom', 5
|
||||
AccessResult::allowed(), 'bottom', 5,
|
||||
],
|
||||
'block5' => [
|
||||
AccessResult::allowed(), 'bottom', -5
|
||||
AccessResult::allowed(), 'bottom', -5,
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -142,7 +142,7 @@ class BlockRepositoryTest extends UnitTestCase {
|
|||
'top' => ['block1'],
|
||||
'center' => [],
|
||||
'bottom' => ['block5', 'block3', 'block4'],
|
||||
]
|
||||
],
|
||||
];
|
||||
return $test_cases;
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ class BlockLocalTasksTest extends LocalTaskIntegrationTestBase {
|
|||
$this->directoryList = ['block' => 'core/modules/block'];
|
||||
parent::setUp();
|
||||
|
||||
$config_factory = $this->getConfigFactoryStub(['system.theme' => [
|
||||
'default' => 'test_c',
|
||||
]]);
|
||||
$config_factory = $this->getConfigFactoryStub([
|
||||
'system.theme' => ['default' => 'test_c'],
|
||||
]);
|
||||
|
||||
$themes = [];
|
||||
$themes['test_a'] = (object) [
|
||||
|
|
|
@ -49,6 +49,7 @@ class BlockPageVariantTest extends UnitTestCase {
|
|||
$container = new Container();
|
||||
$cache_context_manager = $this->getMockBuilder('Drupal\Core\Cache\CacheContextsManager')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['assertValidTokens'])
|
||||
->getMock();
|
||||
$container->set('cache_contexts_manager', $cache_context_manager);
|
||||
$cache_context_manager->expects($this->any())
|
||||
|
@ -209,9 +210,6 @@ class BlockPageVariantTest extends UnitTestCase {
|
|||
$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)));
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
|
|||
|
||||
use Drupal\block\Plugin\migrate\process\BlockVisibility;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\migrate\MigrateSkipRowException;
|
||||
use Drupal\migrate\Plugin\MigrateProcessInterface;
|
||||
use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
|
||||
|
||||
|
@ -80,4 +81,22 @@ class BlockVisibilityTest extends MigrateProcessTestCase {
|
|||
$this->assertEmpty($transformed_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::transform
|
||||
*/
|
||||
public function testTransformException() {
|
||||
$this->moduleHandler->moduleExists('php')->willReturn(FALSE);
|
||||
$migration_plugin = $this->prophesize(MigrateProcessInterface::class);
|
||||
$this->row = $this->getMockBuilder('Drupal\migrate\Row')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['getSourceProperty'])
|
||||
->getMock();
|
||||
$this->row->expects($this->exactly(2))
|
||||
->method('getSourceProperty')
|
||||
->willReturnMap([['bid', 99], ['module', 'foobar']]);
|
||||
$this->plugin = new BlockVisibility(['skip_php' => TRUE], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
|
||||
$this->setExpectedException(MigrateSkipRowException::class, "The block with bid '99' from module 'foobar' will have no PHP or request_path visibility configuration.");
|
||||
$this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue