updated contrib modules
This commit is contained in:
@@ -5,6 +5,9 @@ use Drupal\Component\Uuid\Php;
|
||||
use Drupal\Core\Utility\Token;
|
||||
use Drush\Commands\DrushCommands;
|
||||
use Drush\Exceptions\UserAbortException;
|
||||
use Drush\Utils\StringUtils;
|
||||
use Symfony\Component\Console\Input\Input;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
|
||||
/**
|
||||
* For commands that are parts of modules, Drush expects to find commandfiles in
|
||||
@@ -21,11 +24,21 @@ class DevelCommands extends DrushCommands {
|
||||
|
||||
protected $eventDispatcher;
|
||||
|
||||
public function __construct(Token $token, $container, $eventDispatcher) {
|
||||
protected $moduleHandler;
|
||||
|
||||
public function __construct(Token $token, $container, $eventDispatcher, $moduleHandler) {
|
||||
parent::__construct();
|
||||
$this->token = $token;
|
||||
$this->container = $container;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->moduleHandler = $moduleHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
public function getModuleHandler() {
|
||||
return $this->moduleHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,93 +63,110 @@ class DevelCommands extends DrushCommands {
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall, and Install a list of modules.
|
||||
* Uninstall, and Install modules.
|
||||
|
||||
* @command devel-reinstall
|
||||
* @command devel:reinstall
|
||||
* @param $modules A comma-separated list of module names.
|
||||
* @aliases dre
|
||||
* @aliases dre,devel-reinstall
|
||||
* @allow-additional-options pm-uninstall,pm-enable
|
||||
*/
|
||||
public function reinstall($projects) {
|
||||
$projects = _convert_csv_to_array($projects);
|
||||
public function reinstall($modules) {
|
||||
$modules = StringUtils::csvToArray($modules);
|
||||
|
||||
// This is faster than 3 separate bootstraps.
|
||||
$args = array_merge(array('pm-uninstall'), $projects);
|
||||
// @todo. Use $application dispatch instead of drush_invoke().
|
||||
call_user_func_array('drush_invoke', $args);
|
||||
|
||||
$args = array_merge(array('pm-enable'), $projects);
|
||||
call_user_func_array('drush_invoke', $args);
|
||||
$modules_str = implode(',', $modules);
|
||||
drush_invoke_process('@self', 'pm:uninstall', [$modules_str], []);
|
||||
drush_invoke_process('@self', 'pm:enable', [$modules_str], []);
|
||||
}
|
||||
|
||||
/**
|
||||
* List implementations of a given hook and optionally edit one.
|
||||
*
|
||||
* @command devel-hook
|
||||
* @command devel:hook
|
||||
* @param $hook The name of the hook to explore.
|
||||
* @param $implementation The name of the implementation to edit. Usually omitted.
|
||||
* @usage devel-hook cron
|
||||
* List implementations of hook_cron().
|
||||
* @aliases fnh,fn-hook,hook
|
||||
* @aliases fnh,fn-hook,hook,devel-hook
|
||||
* @optionset_get_editor
|
||||
*/
|
||||
function hook($hook) {
|
||||
function hook($hook, $implementation) {
|
||||
// Get implementations in the .install files as well.
|
||||
include_once './core/includes/install.inc';
|
||||
drupal_load_updates();
|
||||
$info = $this->codeLocate($implementation . "_$hook");
|
||||
$exec = drush_get_editor();
|
||||
drush_shell_exec_interactive($exec, $info['file']);
|
||||
}
|
||||
|
||||
if ($hook_implementations = \Drupal::moduleHandler()->getImplementations($hook)) {
|
||||
if ($choice = drush_choice(array_combine($hook_implementations, $hook_implementations), 'Enter the number of the hook implementation you wish to view.')) {
|
||||
$info= $this->codeLocate($choice . "_$hook");
|
||||
$exec = drush_get_editor();
|
||||
drush_shell_exec_interactive($exec, $info['file']);
|
||||
/**
|
||||
* @hook interact hook
|
||||
*/
|
||||
public function hookInteract(Input $input, Output $output) {
|
||||
if (!$input->getArgument('implementation')) {
|
||||
if ($hook_implementations = $this->getModuleHandler()->getImplementations($input->getArgument('hook'))) {
|
||||
if (!$choice = $this->io()->choice('Enter the number of the hook implementation you wish to view.', array_combine($hook_implementations, $hook_implementations))) {
|
||||
throw new UserAbortException();
|
||||
}
|
||||
$input->setArgument('implementation', $choice);
|
||||
}
|
||||
else {
|
||||
throw new \Exception(dt('No implementations'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->logger()->success(dt('No implementations.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List implementations of a given event and optionally edit one.
|
||||
*
|
||||
* @command devel-event
|
||||
* @command devel:event
|
||||
* @param $event The name of the event to explore. If omitted, a list of events is shown.
|
||||
* @param $implementation The name of the implementation to show. Usually omitted.
|
||||
* @usage devel-event
|
||||
* Pick a Kernel event, then pick an implementation, and then view its source code.
|
||||
* @usage devel-event kernel.terminate
|
||||
* Pick a terminate subscribers and view its source code.
|
||||
* Pick a terminate subscribers implementation and view its source code.
|
||||
* @aliases fne,fn-event,event
|
||||
*/
|
||||
function event($event) {
|
||||
function event($event, $implementation) {
|
||||
$info= $this->codeLocate($implementation);
|
||||
$exec = drush_get_editor();
|
||||
drush_shell_exec_interactive($exec, $info['file']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hook interact devel:event
|
||||
*/
|
||||
public function interactEvent(Input $input, Output $output) {
|
||||
$dispatcher = $this->getEventDispatcher();
|
||||
if (empty($event)) {
|
||||
// @todo Expand this list and move to interact().
|
||||
if (!$input->getArgument('event')) {
|
||||
// @todo Expand this list.
|
||||
$events = array('kernel.controller', 'kernel.exception', 'kernel.request', 'kernel.response', 'kernel.terminate', 'kernel.view');
|
||||
$events = array_combine($events, $events);
|
||||
if (!$event = drush_choice($events, 'Enter the event you wish to explore.')) {
|
||||
if (!$event = $this->io()->choice('Enter the event you wish to explore.', $events)) {
|
||||
throw new UserAbortException();
|
||||
}
|
||||
$input->setArgument('event', $event);
|
||||
}
|
||||
if ($implementations = $dispatcher->getListeners($event)) {
|
||||
foreach ($implementations as $implementation) {
|
||||
$callable = get_class($implementation[0]) . '::' . $implementation[1];
|
||||
$choices[$callable] = $callable;
|
||||
}
|
||||
if ($choice = drush_choice($choices, 'Enter the number of the implementation you wish to view.')) {
|
||||
$info= $this->codeLocate($choice);
|
||||
$exec = drush_get_editor();
|
||||
drush_shell_exec_interactive($exec, $info['file']);
|
||||
if (!$choice = $this->io()->choice('Enter the number of the implementation you wish to view.', $choices)) {
|
||||
throw new UserAbortException();
|
||||
}
|
||||
$input->setArgument('implementation', $choice);
|
||||
}
|
||||
else {
|
||||
$this->logger()->success(dt('No implementations.'));
|
||||
throw new \Exception(dt('No implementations.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List available tokens.
|
||||
*
|
||||
* @command devel-token
|
||||
* @aliases token
|
||||
* @command devel:token
|
||||
* @aliases token,devel-token
|
||||
* @field-labels
|
||||
* group: Group
|
||||
* token: Token
|
||||
@@ -162,8 +192,8 @@ class DevelCommands extends DrushCommands {
|
||||
/**
|
||||
* Generate a UUID.
|
||||
*
|
||||
* @command devel-uuid
|
||||
* @aliases uuid
|
||||
* @command devel:uuid
|
||||
* @aliases uuid,devel-uuid
|
||||
* @usage drush devel-uuid
|
||||
* Outputs a Universally Unique Identifier.
|
||||
*
|
||||
@@ -203,9 +233,9 @@ class DevelCommands extends DrushCommands {
|
||||
/**
|
||||
* Get a list of available container services.
|
||||
*
|
||||
* @command devel-services
|
||||
* @command devel:services
|
||||
* @param $prefix A prefix to filter the service list by.
|
||||
* @aliases devel-container-services,dcs
|
||||
* @aliases devel-container-services,dcs,devel-services
|
||||
* @usage drush devel-services
|
||||
* Gets a list of all available container services
|
||||
* @usage drush dcs plugin.manager
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\devel\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests Devel controller.
|
||||
*
|
||||
* @group devel
|
||||
*/
|
||||
class DevelControllerTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('devel', 'node', 'entity_test', 'devel_entity_test', 'block');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a test entity.
|
||||
$random_label = $this->randomMachineName();
|
||||
$data = array('type' => 'entity_test', 'name' => $random_label);
|
||||
$this->entity = entity_create('entity_test', $data);
|
||||
$this->entity->save();
|
||||
|
||||
// Create a test entity with only canonical route.
|
||||
$random_label = $this->randomMachineName();
|
||||
$data = array('type' => 'devel_entity_test_canonical', 'name' => $random_label);
|
||||
$this->entity_canonical = entity_create('devel_entity_test_canonical', $data);
|
||||
$this->entity_canonical->save();
|
||||
|
||||
// Create a test entity with only edit route.
|
||||
$random_label = $this->randomMachineName();
|
||||
$data = array('type' => 'devel_entity_test_edit', 'name' => $random_label);
|
||||
$this->entity_edit = entity_create('devel_entity_test_edit', $data);
|
||||
$this->entity_edit->save();
|
||||
|
||||
// Create a test entity with no routes.
|
||||
$random_label = $this->randomMachineName();
|
||||
$data = array('type' => 'devel_entity_test_no_links', 'name' => $random_label);
|
||||
$this->entity_no_links = entity_create('devel_entity_test_no_links', $data);
|
||||
$this->entity_no_links->save();
|
||||
|
||||
$this->drupalPlaceBlock('local_tasks_block');
|
||||
|
||||
$web_user = $this->drupalCreateUser(array(
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'access devel information',
|
||||
));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
function testRouteGeneration() {
|
||||
// Test Devel load and render routes for entities with both route
|
||||
// definitions.
|
||||
$this->drupalGet('entity_test/' . $this->entity->id());
|
||||
$this->assertText('Devel', 'Devel tab is present');
|
||||
$this->drupalGet('devel/entity_test/' . $this->entity->id());
|
||||
$this->assertResponse(200);
|
||||
$this->assertText('Definition', 'Devel definition tab is present');
|
||||
$this->assertText('Load', 'Devel load tab is present');
|
||||
$this->assertText('Render', 'Devel load tab is present');
|
||||
$this->assertLinkByHref('devel/entity_test/' . $this->entity->id() . '/render');
|
||||
$this->drupalGet('devel/entity_test/' . $this->entity->id() . '/render');
|
||||
$this->assertResponse(200);
|
||||
$this->assertLinkByHref('devel/entity_test/' . $this->entity->id() . '/definition');
|
||||
$this->drupalGet('devel/entity_test/' . $this->entity->id() . '/definition');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Test Devel load and render routes for entities with only canonical route
|
||||
// definitions.
|
||||
$this->drupalGet('devel_entity_test_canonical/' . $this->entity_canonical->id());
|
||||
$this->assertText('Devel', 'Devel tab is present');
|
||||
//TODO this fail since assertNoLinkByHref search by partial value.
|
||||
//$this->assertNoLinkByHref('devel/devel_entity_test_canonical/' . $this->entity_canonical->id());
|
||||
$this->assertLinkByHref('devel/devel_entity_test_canonical/' . $this->entity_canonical->id() . '/render');
|
||||
$this->drupalGet('devel/devel_entity_test_canonical/' . $this->entity_canonical->id());
|
||||
$this->assertResponse(404);
|
||||
$this->drupalGet('devel/devel_entity_test_canonical/' . $this->entity_canonical->id() . '/render');
|
||||
$this->assertResponse(200);
|
||||
$this->assertLinkByHref('devel/devel_entity_test_canonical/' . $this->entity_canonical->id() . '/definition');
|
||||
$this->drupalGet('devel/devel_entity_test_canonical/' . $this->entity_canonical->id() . '/definition');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Test Devel load and render routes for entities with only edit route
|
||||
// definitions.
|
||||
$this->drupalGet('devel_entity_test_edit/manage/' . $this->entity_edit->id());
|
||||
$this->assertText('Devel', 'Devel tab is present');
|
||||
$this->assertLinkByHref('devel/devel_entity_test_edit/' . $this->entity_edit->id());
|
||||
$this->assertNoLinkByHref('devel/devel_entity_test_edit/' . $this->entity_edit->id() . '/render');
|
||||
$this->assertNoLinkByHref('devel/devel_entity_test_edit/' . $this->entity_edit->id() . '/definition');
|
||||
$this->drupalGet('devel/devel_entity_test_edit/' . $this->entity_edit->id());
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet('devel/devel_entity_test_edit/' . $this->entity_edit->id() . '/render');
|
||||
$this->assertResponse(404);
|
||||
$this->drupalGet('devel/devel_entity_test_edit/' . $this->entity_edit->id() . '/definition');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Test Devel load and render routes for entities with no route
|
||||
// definitions.
|
||||
$this->drupalGet('devel_entity_test_no_links/' . $this->entity_edit->id());
|
||||
$this->assertNoText('Devel', 'Devel tab is not present');
|
||||
$this->assertNoLinkByHref('devel/devel_entity_test_no_links/' . $this->entity_no_links->id());
|
||||
$this->assertNoLinkByHref('devel/devel_entity_test_no_links/' . $this->entity_no_links->id() . '/render');
|
||||
$this->assertNoLinkByHref('devel/devel_entity_test_no_links/' . $this->entity_no_links->id() . '/definition');
|
||||
$this->drupalGet('devel/devel_entity_test_no_links/' . $this->entity_no_links->id());
|
||||
$this->assertResponse(404);
|
||||
$this->drupalGet('devel/devel_entity_test_no_links/' . $this->entity_no_links->id() . '/render');
|
||||
$this->assertResponse(404);
|
||||
$this->drupalGet('devel/devel_entity_test_no_links/' . $this->entity_no_links->id() . '/definition');
|
||||
$this->assertResponse(404);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\devel\Tests;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests pluggable dumper feature.
|
||||
*
|
||||
* @group devel
|
||||
*/
|
||||
class DevelDumperTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['devel', 'devel_dumper_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['administer site configuration', 'access devel information']);
|
||||
$this->drupalLogin($admin_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test dumpers configuration page.
|
||||
*/
|
||||
public function testDumpersConfiguration() {
|
||||
$this->drupalGet('admin/config/development/devel');
|
||||
|
||||
// Ensures that the dumper input is present on the config page.
|
||||
$this->assertFieldByName('dumper');
|
||||
|
||||
// Ensures that the 'default' dumper is enabled by default.
|
||||
$this->assertFieldChecked('edit-dumper-default');
|
||||
|
||||
// Ensures that all dumpers declared by devel are present on the config page
|
||||
// and that only the available dumpers are selectable.
|
||||
$dumpers = ['default', 'drupal_variable', 'firephp', 'chromephp', 'var_dumper'];
|
||||
$available_dumpers = ['default', 'drupal_variable'];
|
||||
|
||||
foreach ($dumpers as $dumper) {
|
||||
$this->assertFieldByXPath('//input[@type="radio" and @name="dumper"]', $dumper, new FormattableMarkup('Radio button for @dumper found.', ['@dumper' => $dumper]));
|
||||
if (in_array($dumper, $available_dumpers)) {
|
||||
$this->assertFieldByXPath('//input[@name="dumper" and not(@disabled="disabled")]', $dumper, new FormattableMarkup('Dumper @dumper is available.', ['@dumper' => $dumper]));
|
||||
}
|
||||
else {
|
||||
$this->assertFieldByXPath('//input[@name="dumper" and @disabled="disabled"]', $dumper, new FormattableMarkup('Dumper @dumper is disabled.', ['@dumper' => $dumper]));
|
||||
}
|
||||
}
|
||||
|
||||
// Ensures that dumper plugins declared by other modules are present on the
|
||||
// config page and that only the available dumpers are selectable.
|
||||
$this->assertFieldByName('dumper', 'available_test_dumper');
|
||||
$this->assertText('Available test dumper.', 'Available dumper label is present');
|
||||
$this->assertText('Drupal dumper for testing purposes (available).', 'Available dumper description is present');
|
||||
$this->assertFieldByXPath('//input[@name="dumper" and not(@disabled="disabled")]', 'available_test_dumper', 'Available dumper input not is disabled.');
|
||||
|
||||
$this->assertFieldByName('dumper', 'not_available_test_dumper');
|
||||
$this->assertText('Not available test dumper.', 'Non available dumper label is present');
|
||||
$this->assertText('Drupal dumper for testing purposes (not available).Not available. You may need to install external dependencies for use this plugin.', 'Non available dumper description is present');
|
||||
$this->assertFieldByXPath('//input[@name="dumper" and @disabled="disabled"]', 'not_available_test_dumper', 'Non available dumper input is disabled.');
|
||||
|
||||
// Ensures that saving of the dumpers configuration works as expected.
|
||||
$edit = [
|
||||
'dumper' => 'drupal_variable',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/development/devel', $edit, t('Save configuration'));
|
||||
$this->assertText(t('The configuration options have been saved.'));
|
||||
|
||||
$config = \Drupal::config('devel.settings')->get('devel_dumper');
|
||||
$this->assertEqual('drupal_variable', $config, 'The configuration options have been properly saved');
|
||||
|
||||
// Ensure that if the chosen dumper is not available (e.g. the module that
|
||||
// provide it is uninstalled) the 'default' dumper appears selected in the
|
||||
// config page.
|
||||
\Drupal::service('module_installer')->install(['kint']);
|
||||
|
||||
$this->drupalGet('admin/config/development/devel');
|
||||
$this->assertFieldByName('dumper', 'kint');
|
||||
|
||||
$edit = [
|
||||
'dumper' => 'kint',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/development/devel', $edit, t('Save configuration'));
|
||||
$this->assertText(t('The configuration options have been saved.'));
|
||||
|
||||
$config = \Drupal::config('devel.settings')->get('devel_dumper');
|
||||
$this->assertEqual('kint', $config, 'The configuration options have been properly saved');
|
||||
|
||||
\Drupal::service('module_installer')->uninstall(['kint']);
|
||||
|
||||
$this->drupalGet('admin/config/development/devel');
|
||||
$this->assertNoFieldByName('dumper', 'kint');
|
||||
$this->assertFieldChecked('edit-dumper-default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test variable is dumped in page.
|
||||
*/
|
||||
function testDumpersOutput() {
|
||||
$edit = [
|
||||
'dumper' => 'available_test_dumper',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/development/devel', $edit, t('Save configuration'));
|
||||
$this->assertText(t('The configuration options have been saved.'));
|
||||
|
||||
$this->drupalGet('devel_dumper_test/dump');
|
||||
$elements = $this->xpath('//body/pre[contains(text(), :message)]', [':message' => 'AvailableTestDumper::dump() Test output']);
|
||||
$this->assertTrue(!empty($elements), 'Dumped message is present.');
|
||||
|
||||
$this->drupalGet('devel_dumper_test/message');
|
||||
$elements = $this->xpath('//div[contains(@class, "messages")]/pre[contains(text(), :message)]', [':message' => 'AvailableTestDumper::export() Test output']);
|
||||
$this->assertTrue(!empty($elements), 'Dumped message is present.');
|
||||
|
||||
$this->drupalGet('devel_dumper_test/export');
|
||||
$elements = $this->xpath('//div[@class="layout-content"]//pre[contains(text(), :message)]', [':message' => 'AvailableTestDumper::export() Test output']);
|
||||
$this->assertTrue(!empty($elements), 'Dumped message is present.');
|
||||
|
||||
$this->drupalGet('devel_dumper_test/export_renderable');
|
||||
$elements = $this->xpath('//div[@class="layout-content"]//pre[contains(text(), :message)]', [':message' => 'AvailableTestDumper::exportAsRenderable() Test output']);
|
||||
$this->assertTrue(!empty($elements), 'Dumped message is present.');
|
||||
// Ensures that plugins can add libraries to the page when the
|
||||
// ::exportAsRenderable() method is used.
|
||||
$this->assertRaw('devel_dumper_test/css/devel_dumper_test.css');
|
||||
$this->assertRaw('devel_dumper_test/js/devel_dumper_test.js');
|
||||
|
||||
$debug_filename = file_directory_temp() . '/drupal_debug.txt';
|
||||
|
||||
$this->drupalGet('devel_dumper_test/debug');
|
||||
$file_content = file_get_contents($debug_filename);
|
||||
$expected = <<<EOF
|
||||
<pre>AvailableTestDumper::export() Test output</pre>
|
||||
|
||||
EOF;
|
||||
$this->assertEqual($file_content, $expected, 'Dumped message is present.');
|
||||
|
||||
// Ensures that the DevelDumperManager::debug() is not access checked and
|
||||
// that the dump is written in the debug file even if the user has not the
|
||||
// 'access devel information' permission.
|
||||
file_put_contents($debug_filename, '');
|
||||
$this->drupalLogout();
|
||||
$this->drupalGet('devel_dumper_test/debug');
|
||||
$file_content = file_get_contents($debug_filename);
|
||||
$expected = <<<EOF
|
||||
<pre>AvailableTestDumper::export() Test output</pre>
|
||||
|
||||
EOF;
|
||||
$this->assertEqual($file_content, $expected, 'Dumped message is present.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\devel\Tests;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests devel menu links.
|
||||
*
|
||||
* @group devel
|
||||
*/
|
||||
class DevelMenuLinksTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['devel', 'block', 'devel_test'];
|
||||
|
||||
/**
|
||||
* The user for tests.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $develUser;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
// Devel links currently appears only in the devel menu.
|
||||
// Place the devel menu block so we can ensure that these link works
|
||||
// properly.
|
||||
$this->drupalPlaceBlock('system_menu_block:devel');
|
||||
$this->drupalPlaceBlock('page_title_block');
|
||||
|
||||
$this->develUser = $this->drupalCreateUser(['access devel information', 'administer site configuration']);
|
||||
$this->drupalLogin($this->develUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests CSFR protected links.
|
||||
*/
|
||||
public function testCsrfProtectedLinks() {
|
||||
// Ensure CSRF link are not accessible directly.
|
||||
$this->drupalGet('devel/run-cron');
|
||||
$this->assertResponse(403);
|
||||
$this->drupalGet('devel/cache/clear');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Ensure clear cache link works properly.
|
||||
$this->assertLink('Cache clear');
|
||||
$this->clickLink('Cache clear');
|
||||
$this->assertText('Cache cleared.');
|
||||
|
||||
// Ensure run cron link works properly.
|
||||
$this->assertLink('Run cron');
|
||||
$this->clickLink('Run cron');
|
||||
$this->assertText('Cron ran successfully.');
|
||||
|
||||
// Ensure CSRF protected links work properly after change session.
|
||||
$this->drupalLogout();
|
||||
$this->drupalLogin($this->develUser);
|
||||
|
||||
$this->assertLink('Cache clear');
|
||||
$this->clickLink('Cache clear');
|
||||
$this->assertText('Cache cleared.');
|
||||
|
||||
$this->assertLink('Run cron');
|
||||
$this->clickLink('Run cron');
|
||||
$this->assertText('Cron ran successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests redirect destination links.
|
||||
*/
|
||||
public function testRedirectDestinationLinks() {
|
||||
// By default, in the testing profile, front page is the user canonical URI.
|
||||
// For better testing do not use the default frontpage.
|
||||
$url = Url::fromRoute('devel.simple_page');
|
||||
$destination = Url::fromRoute('devel.simple_page', [], ['absolute' => FALSE]);
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertLink(t('Reinstall Modules'));
|
||||
$this->clickLink(t('Reinstall Modules'));
|
||||
$this->assertUrl('devel/reinstall', ['query' => ['destination' => $destination->toString()]]);
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertLink(t('Rebuild Menu'));
|
||||
$this->clickLink(t('Rebuild Menu'));
|
||||
$this->assertUrl('devel/menu/reset', ['query' => ['destination' => $destination->toString()]]);
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertLink(t('Cache clear'));
|
||||
$this->clickLink(t('Cache clear'));
|
||||
$this->assertText('Cache cleared.');
|
||||
$this->assertUrl($url);
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertLink(t('Run cron'));
|
||||
$this->clickLink(t('Run cron'));
|
||||
$this->assertText(t('Cron ran successfully.'));
|
||||
$this->assertUrl($url);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\devel\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests reinstall modules.
|
||||
*
|
||||
* @group devel
|
||||
*/
|
||||
class DevelReinstallTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('devel');
|
||||
|
||||
/**
|
||||
* The profile to install as a basis for testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'minimal';
|
||||
|
||||
/**
|
||||
* Set up test.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(array('administer site configuration'));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinstall modules.
|
||||
*/
|
||||
public function testDevelReinstallModules() {
|
||||
// Minimal profile enables only dblog, block and node.
|
||||
$modules = array('dblog', 'block');
|
||||
|
||||
// Needed for compare correctly the message.
|
||||
sort($modules);
|
||||
|
||||
$this->drupalGet('devel/reinstall');
|
||||
|
||||
// Prepare field data in an associative array
|
||||
$edit = array();
|
||||
foreach ($modules as $module) {
|
||||
$edit["reinstall[$module]"] = TRUE;
|
||||
}
|
||||
|
||||
$this->drupalPostForm('devel/reinstall', $edit, t('Reinstall'));
|
||||
$this->assertText(t('Uninstalled and installed: @names.', array('@names' => implode(', ', $modules))));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,313 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\devel\Tests;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests switch user.
|
||||
*
|
||||
* @group devel
|
||||
*/
|
||||
class DevelSwitchUserTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['devel', 'block'];
|
||||
|
||||
/**
|
||||
* The block used by this test.
|
||||
*
|
||||
* @var \Drupal\block\BlockInterface
|
||||
*/
|
||||
protected $block;
|
||||
|
||||
/**
|
||||
* The devel user.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $develUser;
|
||||
|
||||
/**
|
||||
* The switch user.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $switchUser;
|
||||
|
||||
/**
|
||||
* The web user.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* Set up test.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->block = $this->drupalPlaceBlock('devel_switch_user', ['id' => 'switch-user']);
|
||||
|
||||
$this->develUser = $this->drupalCreateUser(['access devel information', 'switch users']);
|
||||
$this->switchUser = $this->drupalCreateUser(['switch users']);
|
||||
$this->webUser = $this->drupalCreateUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests switch user.
|
||||
*/
|
||||
public function testSwitchUser() {
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertNoText($this->block->label(), 'Block title was not found.');
|
||||
|
||||
// Ensure that a token is required to switch user.
|
||||
$this->drupalGet('/devel/switch/' . $this->webUser->getDisplayName());
|
||||
$this->assertResponse(403);
|
||||
|
||||
$this->drupalLogin($this->develUser);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertText($this->block->label(), 'Block title was found.');
|
||||
|
||||
// Ensure that if name in not passed the controller returns access denied.
|
||||
$this->drupalGet('/devel/switch');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Ensure that a token is required to switch user.
|
||||
$this->drupalGet('/devel/switch/' . $this->switchUser->getDisplayName());
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Switch to another user account.
|
||||
$this->drupalGet('/user/' . $this->switchUser->id());
|
||||
$this->clickLink($this->switchUser->getDisplayName());
|
||||
$this->assertSessionByUid($this->switchUser->id());
|
||||
$this->assertNoSessionByUid($this->develUser->id());
|
||||
|
||||
// Switch back to initial account.
|
||||
$this->clickLink($this->develUser->getDisplayName());
|
||||
$this->assertNoSessionByUid($this->switchUser->id());
|
||||
$this->assertSessionByUid($this->develUser->id());
|
||||
|
||||
// Use the search form to switch to another account.
|
||||
$edit = ['userid' => $this->switchUser->getDisplayName()];
|
||||
$this->drupalPostForm(NULL, $edit, t('Switch'));
|
||||
$this->assertSessionByUid($this->switchUser->id());
|
||||
$this->assertNoSessionByUid($this->develUser->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the switch user block configuration.
|
||||
*/
|
||||
public function testSwitchUserBlockConfiguration() {
|
||||
$anonymous = \Drupal::config('user.settings')->get('anonymous');
|
||||
|
||||
// Create some users for the test.
|
||||
for ($i = 0; $i < 12; $i++) {
|
||||
$this->drupalCreateUser();
|
||||
}
|
||||
|
||||
$this->drupalLogin($this->develUser);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertText($this->block->label(), 'Block title was found.');
|
||||
|
||||
// Ensure that block default configuration is effectively used. The block
|
||||
// default configuration is the following:
|
||||
// - list_size : 12
|
||||
// - include_anon : FALSE
|
||||
// - show_form : TRUE
|
||||
$this->assertSwitchUserSearchForm();
|
||||
$this->assertSwitchUserListCount(12);
|
||||
$this->assertSwitchUserListNoContainsUser($anonymous);
|
||||
|
||||
// Ensure that changing the list_size configuration property the number of
|
||||
// user displayed in the list change.
|
||||
$this->setBlockConfiguration('list_size', 4);
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListCount(4);
|
||||
|
||||
// Ensure that changing the include_anon configuration property the
|
||||
// anonymous user is displayed in the list.
|
||||
$this->setBlockConfiguration('include_anon', TRUE);
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListContainsUser($anonymous);
|
||||
|
||||
// Ensure that changing the show_form configuration property the
|
||||
// form is not displayed.
|
||||
$this->setBlockConfiguration('show_form', FALSE);
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserNoSearchForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user list items.
|
||||
*/
|
||||
public function testSwitchUserListItems() {
|
||||
$anonymous = \Drupal::config('user.settings')->get('anonymous');
|
||||
|
||||
$this->setBlockConfiguration('list_size', 2);
|
||||
|
||||
// Login as web user so we are sure that this account is prioritized
|
||||
// in the list if not enougth user with 'switch users' permission are
|
||||
// present.
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
$this->drupalLogin($this->develUser);
|
||||
$this->drupalGet('');
|
||||
|
||||
// Ensure that user with 'switch users' permission are prioritized.
|
||||
$this->assertSwitchUserListCount(2);
|
||||
$this->assertSwitchUserListContainsUser($this->develUser->getDisplayName());
|
||||
$this->assertSwitchUserListContainsUser($this->switchUser->getDisplayName());
|
||||
|
||||
// Ensure that blocked users are not shown in the list.
|
||||
$this->switchUser->set('status', 0)->save();
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListCount(2);
|
||||
$this->assertSwitchUserListContainsUser($this->develUser->getDisplayName());
|
||||
$this->assertSwitchUserListContainsUser($this->webUser->getDisplayName());
|
||||
$this->assertSwitchUserListNoContainsUser($this->switchUser->getDisplayName());
|
||||
|
||||
// Ensure that anonymous user are prioritized if include_anon is set to true.
|
||||
$this->setBlockConfiguration('include_anon', TRUE);
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListCount(2);
|
||||
$this->assertSwitchUserListContainsUser($this->develUser->getDisplayName());
|
||||
$this->assertSwitchUserListContainsUser($anonymous);
|
||||
|
||||
// Ensure that the switch user block works properly even if no prioritized
|
||||
// users are found (special handling for user 1).
|
||||
$this->drupalLogout();
|
||||
$this->develUser->delete();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListCount(2);
|
||||
$this->assertSwitchUserListContainsUser($this->rootUser->getDisplayName());
|
||||
$this->assertSwitchUserListContainsUser($anonymous);
|
||||
|
||||
// Ensure that the switch user block works properly even if no roles have
|
||||
// the 'switch users' permission associated (special handling for user 1).
|
||||
$roles = user_roles(TRUE, 'switch users');
|
||||
\Drupal::entityTypeManager()->getStorage('user_role')->delete($roles);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertSwitchUserListCount(2);
|
||||
$this->assertSwitchUserListContainsUser($this->rootUser->getDisplayName());
|
||||
$this->assertSwitchUserListContainsUser($anonymous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for verify the number of items shown in the user list.
|
||||
*
|
||||
* @param int $number
|
||||
* The expected numer of items.
|
||||
*/
|
||||
public function assertSwitchUserListCount($number) {
|
||||
$result = $this->xpath('//div[@id=:block]//ul/li/a', [':block' => 'block-switch-user']);
|
||||
$this->assert(count($result) == $number, 'The number of users shown in switch user is correct.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for verify if the user list contains a username.
|
||||
*
|
||||
* @param string $username
|
||||
* The username to check.
|
||||
*/
|
||||
public function assertSwitchUserListContainsUser($username) {
|
||||
$result = $this->xpath('//div[@id=:block]//ul/li/a[normalize-space()=:user]', [':block' => 'block-switch-user', ':user' => $username]);
|
||||
$this->assert(count($result) > 0, new FormattableMarkup('User "%user" is included in the switch user list.', ['%user' => $username]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for verify if the user list not contains a username.
|
||||
*
|
||||
* @param string $username
|
||||
* The username to check.
|
||||
*/
|
||||
public function assertSwitchUserListNoContainsUser($username) {
|
||||
$result = $this->xpath('//div[@id=:block]//ul/li/a[normalize-space()=:user]', [':block' => 'block-switch-user', ':user' => $username]);
|
||||
$this->assert(count($result) == 0, new FormattableMarkup('User "%user" is not included in the switch user list.', ['%user' => $username]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for verify if the search form is shown.
|
||||
*/
|
||||
public function assertSwitchUserSearchForm() {
|
||||
$result = $this->xpath('//div[@id=:block]//form[contains(@class, :form)]', [':block' => 'block-switch-user', ':form' => 'devel-switchuser-form']);
|
||||
$this->assert(count($result) > 0, 'The search form is shown.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for verify if the search form is not shown.
|
||||
*/
|
||||
public function assertSwitchUserNoSearchForm() {
|
||||
$result = $this->xpath('//div[@id=:block]//form[contains(@class, :form)]', [':block' => 'block-switch-user', ':form' => 'devel-switchuser-form']);
|
||||
$this->assert(count($result) == 0, 'The search form is not shown.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected helper method to set the test block's configuration.
|
||||
*/
|
||||
protected function setBlockConfiguration($key, $value) {
|
||||
$block = $this->block->getPlugin();
|
||||
$block->setConfigurationValue($key, $value);
|
||||
$this->block->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that there is a session for a given user ID.
|
||||
*
|
||||
* Based off masquarade module.
|
||||
*
|
||||
* @param int $uid
|
||||
* The user ID for which to find a session record.
|
||||
*
|
||||
* TODO find a cleaner way to do this check.
|
||||
*/
|
||||
protected function assertSessionByUid($uid) {
|
||||
$query = \Drupal::database()->select('sessions');
|
||||
$query->fields('sessions', array('uid'));
|
||||
$query->condition('uid', $uid);
|
||||
$result = $query->execute()->fetchAll();
|
||||
|
||||
if (empty($result)) {
|
||||
$this->fail(new FormattableMarkup('No session found for uid @uid', array('@uid' => $uid)));
|
||||
}
|
||||
elseif (count($result) > 1) {
|
||||
// If there is more than one session, then that must be unexpected.
|
||||
$this->fail("Found more than 1 session for uid $uid.");
|
||||
}
|
||||
else {
|
||||
$this->pass("Found session for uid $uid.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that no session exists for a given uid.
|
||||
*
|
||||
* Based off masquarade module.
|
||||
*
|
||||
* @param int $uid
|
||||
* The user ID to assert.
|
||||
*
|
||||
* TODO find a cleaner way to do this check.
|
||||
*/
|
||||
protected function assertNoSessionByUid($uid) {
|
||||
$query = \Drupal::database()->select('sessions');
|
||||
$query->fields('sessions', array('uid'));
|
||||
$query->condition('uid', $uid);
|
||||
$result = $query->execute()->fetchAll();
|
||||
$this->assert(empty($result), "No session for uid $uid found.");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user