Newer
Older
<?php
/**
* @file
Dries Buytaert
committed
* Contains \Drupal\block\Tests\BlockTest.
*/
namespace Drupal\block\Tests;
use Drupal\Component\Utility\Html;
use Drupal\block\Entity\Block;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
* Tests basic block functionality.
*
* @group block
*/
class BlockTest extends BlockTestBase {
* Tests block visibility.
*/
function testBlockVisibility() {
Dries Buytaert
committed
$block_name = 'system_powered_by_block';
// Create a random title for the block.
Alex Pott
committed
$title = $this->randomMachineName(8);
Dries Buytaert
committed
// Enable a standard block.
$default_theme = $this->config('system.theme')->get('default');
Dries Buytaert
committed
$edit = array(
Alex Pott
committed
'id' => strtolower($this->randomMachineName(8)),
Dries Buytaert
committed
'region' => 'sidebar_first',
'settings[label]' => $title,
Dries Buytaert
committed
);
// 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;
Alex Pott
committed
$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'));
Dries Buytaert
committed
$this->assertText('The block configuration has been saved.', 'Block was saved');
Alex Pott
committed
$this->clickLink('Configure');
$this->assertFieldChecked('edit-visibility-request-path-negate-1');
$this->drupalGet('');
Dries Buytaert
committed
$this->assertText($title, 'Block was displayed on the front page.');
$this->drupalGet('user');
Dries Buytaert
committed
$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('');
Dries Buytaert
committed
$this->assertNoText($title, 'Block was not displayed to anonymous users.');
// Confirm that an empty block is not displayed.
Dries Buytaert
committed
$this->assertNoText('Powered by Drupal', 'Empty block not displayed.');
Angie Byron
committed
$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 = array(
'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'));
}
Angie Byron
committed
* Test block visibility when leaving "pages" textarea empty.
*/
function testBlockVisibilityListedEmpty() {
Dries Buytaert
committed
$block_name = 'system_powered_by_block';
// Create a random title for the block.
Alex Pott
committed
$title = $this->randomMachineName(8);
Dries Buytaert
committed
// Enable a standard block.
$default_theme = $this->config('system.theme')->get('default');
Dries Buytaert
committed
$edit = array(
Alex Pott
committed
'id' => strtolower($this->randomMachineName(8)),
Dries Buytaert
committed
'region' => 'sidebar_first',
'settings[label]' => $title,
'visibility[request_path][negate]' => TRUE,
Dries Buytaert
committed
);
// 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'));
Dries Buytaert
committed
$this->assertText('The block configuration has been saved.', 'Block was saved');
$this->drupalGet('user');
Dries Buytaert
committed
$this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
$this->drupalGet('USER');
Dries Buytaert
committed
$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.');
}
/**
* Test configuring and moving a module-define block to specific regions.
*/
function testBlock() {
Dries Buytaert
committed
// Select the 'Powered by Drupal' block to be configured and moved.
$block = array();
Dries Buytaert
committed
$block['id'] = 'system_powered_by_block';
Alex Pott
committed
$block['settings[label]'] = $this->randomMachineName(8);
$block['theme'] = $this->config('system.theme')->get('default');
Dries Buytaert
committed
$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'], array('settings[label]' => $block['settings[label]'], 'id' => $block['id'], 'region' => $block['region']), t('Save block'));
Dries Buytaert
committed
$this->assertText(t('The block configuration has been saved.'), 'Block title set.');
Dries Buytaert
committed
// 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);
}
// Set the block to the disabled region.
$edit = array();
$edit['blocks[' . $block['id'] . '][region]'] = -1;
$this->drupalPostForm('admin/structure/block', $edit, t('Save blocks'));
Dries Buytaert
committed
// Confirm that the block is now listed as disabled.
Dries Buytaert
committed
$this->assertText(t('The block settings have been updated.'), 'Block successfully move to disabled region.');
Dries Buytaert
committed
// Confirm that the block instance title and markup are not displayed.
$this->drupalGet('node');
$this->assertNoText(t($block['settings[label]']));
Dries Buytaert
committed
// Check for <div id="block-my-block-instance-name"> if the machine name
// is my_block_instance_name.
$xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-' . str_replace('_', '-', strtolower($block['id']))));
Dries Buytaert
committed
$this->assertNoFieldByXPath($xpath, FALSE, 'Block found in no regions.');
Dries Buytaert
committed
// Test deleting the block from the edit form.
$this->drupalGet('admin/structure/block/manage/' . $block['id']);
$this->clickLink(t('Delete'));
Dries Buytaert
committed
$this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block['settings[label]'])));
$this->drupalPostForm(NULL, array(), t('Delete'));
Alex Pott
committed
$this->assertRaw(t('The block %name has been deleted.', array('%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(), array('query' => array('destination' => 'admin')));
$this->clickLink(t('Delete'));
$this->assertRaw(t('Are you sure you want to delete the block %name?', array('%name' => $block->label())));
$this->drupalPostForm(NULL, array(), t('Delete'));
Alex Pott
committed
$this->assertRaw(t('The block %name has been deleted.', array('%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() {
catch
committed
// Install all themes.
\Drupal::service('theme_handler')->install(array('bartik', 'seven'));
$theme_settings = $this->config('system.theme');
foreach (array('bartik', 'classy', 'seven') 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 = array();
Alex Pott
committed
$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]', array(':id' => Html::getUniqueId('block-' . $block['id'])));
$this->assertTrue(!empty($elements), 'The block was found.');
}
}
Angie Byron
committed
/**
* Test block display of theme titles.
*/
function testThemeName() {
// Enable the help block.
$this->drupalPlaceBlock('help_block', array('region' => 'help'));
$this->drupalPlaceBlock('local_tasks_block');
Angie Byron
committed
// Explicitly set the default and admin themes.
$theme = 'block_test_specialchars_theme';
catch
committed
\Drupal::service('theme_handler')->install(array($theme));
Angie Byron
committed
\Drupal::service('router.builder')->rebuild();
$this->drupalGet('admin/structure/block');
Alex Pott
committed
$this->assertEscaped('<"Cat" & \'Mouse\'>');
$this->drupalGet('admin/structure/block/list/block_test_specialchars_theme');
Alex Pott
committed
$this->assertEscaped('Demonstrate block regions (<"Cat" & \'Mouse\'>)');
Angie Byron
committed
}
Angie Byron
committed
/**
* Test block title display settings.
*/
function testHideBlockTitle() {
$block_name = 'system_powered_by_block';
// Create a random title for the block.
Alex Pott
committed
$title = $this->randomMachineName(8);
$id = strtolower($this->randomMachineName(8));
Angie Byron
committed
// Enable a standard block.
$default_theme = $this->config('system.theme')->get('default');
Angie Byron
committed
$edit = array(
'id' => $id,
Angie Byron
committed
'region' => 'sidebar_first',
'settings[label]' => $title,
Angie Byron
committed
);
$this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block'));
Angie Byron
committed
$this->assertText('The block configuration has been saved.', 'Block was saved');
$this->drupalGet('user');
$this->assertText($title, 'Block title was displayed by default.');
$edit = array(
'settings[label_display]' => FALSE,
Angie Byron
committed
);
$this->drupalPostForm('admin/structure/block/manage/' . $id, $edit, t('Save block'));
Angie Byron
committed
$this->assertText('The block configuration has been saved.', 'Block was saved');
$this->drupalGet('admin/structure/block/manage/' . $id);
$this->assertNoFieldChecked('edit-settings-label-display', 'The display_block option has the correct default value on the configuration form.');
Angie Byron
committed
$this->drupalGet('user');
$this->assertNoText($title, 'Block title was not displayed when hidden.');
}
/**
* 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'.
*/
function moveBlockToRegion(array $block, $region) {
// Set the created block to a specific region.
$block += array('theme' => $this->config('system.theme')->get('default'));
$edit = array();
$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.
Dries Buytaert
committed
$this->assertText(t('The block settings have been updated.'), format_string('Block successfully moved to %region_name region.', array( '%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]/*', array(
':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.', array('%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();
Dries Buytaert
committed
// Enable page caching.
$config = $this->config('system.performance');
$config->set('cache.page.max_age', 300);
$config->save();
// Place the "Powered by Drupal" block.
catch
committed
$block = $this->drupalPlaceBlock('system_powered_by_block', array('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');
Angie Byron
committed
$cid_parts = array(\Drupal::url('<front>', array(), array('absolute' => TRUE)), 'html');
catch
committed
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
$expected_cache_tags = array(
'config:block_list',
'block_view',
'config:block.block.powered',
'config:user.role.anonymous',
'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 = array(
'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');
Angie Byron
committed
$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.
catch
committed
$block_2 = $this->drupalPlaceBlock('system_powered_by_block', array('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');
Angie Byron
committed
$cid_parts = array(\Drupal::url('<front>', array(), array('absolute' => TRUE)), 'html');
catch
committed
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
$expected_cache_tags = array(
'config:block_list',
'block_view',
'config:block.block.powered',
'config:block.block.powered-2',
'config:user.role.anonymous',
'rendered',
);
sort($expected_cache_tags);
$this->assertEqual($cache_entry->tags, $expected_cache_tags);
$expected_cache_tags = array(
'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 = array(
'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', array('powered', 'powered-2'));
$this->drupalGet('<front>');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
Angie Byron
committed
/**
* 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');
}
Angie Byron
committed
catch
committed
/**
* 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']);
$theme_handler->setDefault('seven');
$block = $this->drupalPlaceBlock('system_powered_by_block', ['theme' => 'seven', 'region' => 'help']);
$this->drupalGet('<front>');
$this->assertText('Powered by Drupal');
$theme_handler->setDefault('classy');
catch
committed
$theme_handler->uninstall(['seven']);
// Ensure that the block configuration does not exist anymore.
$this->assertIdentical(NULL, Block::load($block->id()));
}
Alex Pott
committed
/**
* 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');
}
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
/**
* 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()
]);
}