first commit

This commit is contained in:
2020-06-08 23:57:36 +02:00
commit 6277454f7a
16057 changed files with 1715382 additions and 0 deletions
@@ -0,0 +1,7 @@
name: action_form_ajax_test
type: module
description: 'module used for testing ajax in action config entity forms.'
package: Core
version: VERSION
core: 8.x
hidden: true
@@ -0,0 +1,7 @@
action.configuration.action_form_ajax_test:
type: action_configuration_default
label: 'action_form_ajax_test action'
mapping:
party_time:
type: string
label: 'The time of the party.'
@@ -0,0 +1,89 @@
<?php
namespace Drupal\action_form_ajax_test\Plugin\Action;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Plugin used for testing AJAX in action config entity forms.
*
* @Action(
* id = "action_form_ajax_test",
* label = @Translation("action_form_ajax_test"),
* type = "system"
* )
*/
class ActionAjaxTest extends ConfigurableActionBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'party_time' => '',
];
}
/**
* {@inheritdoc}
*/
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
$result = AccessResult::allowed();
return $return_as_object ? $result : $result->isAllowed();
}
/**
* {@inheritdoc}
*/
public function execute() {
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$having_a_party = $form_state->getValue('having_a_party', !empty($this->configuration['party_time']));
$form['having_a_party'] = [
'#type' => 'checkbox',
'#title' => $this->t('Are we having a party?'),
'#ajax' => [
'wrapper' => 'party-container',
'callback' => [$this, 'partyCallback'],
],
'#default_value' => $having_a_party,
];
$form['container'] = [
'#type' => 'container',
'#prefix' => '<div id="party-container">',
'#suffix' => '</div>',
];
if ($having_a_party) {
$form['container']['party_time'] = [
'#type' => 'textfield',
'#title' => $this->t('Party time'),
'#default_value' => $this->configuration['party_time'],
];
}
return $form;
}
/**
* Callback for party checkbox.
*/
public function partyCallback(array $form, FormStateInterface $form_state) {
return $form['container'];
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['party_time'] = $form_state->getValue('party_time');
}
}
@@ -0,0 +1 @@
recursion_limit: 35
@@ -0,0 +1,41 @@
<?php
/**
* @file
* Contains database additions to for testing upgrade path for action settings.
*
* @see https://www.drupal.org/node/3022401
*/
use Drupal\Core\Database\Database;
use Drupal\Core\Serialization\Yaml;
$connection = Database::getConnection();
$action_settings = Yaml::decode(file_get_contents(__DIR__ . '/action.settings_3022401.yml'));
$connection->insert('config')
->fields([
'collection',
'name',
'data',
])
->values([
'collection' => '',
'name' => 'action.settings',
'data' => serialize($action_settings),
])
->execute();
// Enable action module.
$extensions = $connection->select('config')
->fields('config', ['data'])
->condition('name', 'core.extension')
->execute()
->fetchField();
$extensions = unserialize($extensions);
$connection->update('config')
->fields([
'data' => serialize(array_merge_recursive($extensions, ['module' => ['action' => 0]])),
])
->condition('name', 'core.extension')
->execute();
@@ -0,0 +1,42 @@
<?php
namespace Drupal\Tests\action\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Test behaviors when visiting the action listing page.
*
* @group action
*/
class ActionListTest extends BrowserTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = ['action'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests the behavior when there are no actions to list in the admin page.
*/
public function testEmptyActionList() {
// Create a user with permission to view the actions administration pages.
$this->drupalLogin($this->drupalCreateUser(['administer actions']));
// Ensure the empty text appears on the action list page.
/** @var $storage \Drupal\Core\Entity\EntityStorageInterface */
$storage = $this->container->get('entity_type.manager')->getStorage('action');
$actions = $storage->loadMultiple();
$storage->delete($actions);
$this->drupalGet('/admin/config/system/actions');
$this->assertRaw('There are no actions yet.');
}
}
@@ -0,0 +1,47 @@
<?php
namespace Drupal\Tests\action\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests that uninstalling actions does not remove other module's actions.
*
* @group action
* @see \Drupal\views\Plugin\views\field\BulkForm
* @see \Drupal\user\Plugin\Action\BlockUser
*/
class ActionUninstallTest extends BrowserTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = ['views', 'action'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests Action uninstall.
*/
public function testActionUninstall() {
\Drupal::service('module_installer')->uninstall(['action']);
$storage = $this->container->get('entity_type.manager')->getStorage('action');
$storage->resetCache(['user_block_user_action']);
$this->assertNotEmpty($storage->load('user_block_user_action'), 'Configuration entity \'user_block_user_action\' still exists after uninstalling action module.');
$admin_user = $this->drupalCreateUser(['administer users']);
$this->drupalLogin($admin_user);
$this->drupalGet('admin/people');
// Ensure we have the user_block_user_action listed.
$this->assertRaw('<option value="user_block_user_action">Block the selected user(s)</option>');
}
}
@@ -0,0 +1,95 @@
<?php
namespace Drupal\Tests\action\Functional;
use Drupal\system\Entity\Action;
use Drupal\Tests\BrowserTestBase;
/**
* Tests complex actions configuration by adding, editing, and deleting a
* complex action.
*
* @group action
*/
class ConfigurationTest extends BrowserTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = ['action'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests configuration of advanced actions through administration interface.
*/
public function testActionConfiguration() {
// Create a user with permission to view the actions administration pages.
$user = $this->drupalCreateUser(['administer actions']);
$this->drupalLogin($user);
// Make a POST request to admin/config/system/actions.
$edit = [];
$edit['action'] = 'action_goto_action';
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
$this->assertSession()->statusCodeEquals(200);
// Make a POST request to the individual action configuration page.
$edit = [];
$action_label = $this->randomMachineName();
$edit['label'] = $action_label;
$edit['id'] = strtolower($action_label);
$edit['url'] = 'admin';
$this->drupalPostForm('admin/config/system/actions/add/action_goto_action', $edit, t('Save'));
$this->assertSession()->statusCodeEquals(200);
$action_id = $edit['id'];
// Make sure that the new complex action was saved properly.
$this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully saved the complex action.");
$this->assertText($action_label, "Make sure the action label appears on the configuration page after we've saved the complex action.");
// Make another POST request to the action edit page.
$this->clickLink(t('Configure'));
$edit = [];
$new_action_label = $this->randomMachineName();
$edit['label'] = $new_action_label;
$edit['url'] = 'admin';
$this->drupalPostForm(NULL, $edit, t('Save'));
$this->assertSession()->statusCodeEquals(200);
// Make sure that the action updated properly.
$this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully updated the complex action.");
$this->assertNoText($action_label, "Make sure the old action label does NOT appear on the configuration page after we've updated the complex action.");
$this->assertText($new_action_label, "Make sure the action label appears on the configuration page after we've updated the complex action.");
$this->clickLink(t('Configure'));
$element = $this->xpath('//input[@type="text" and @value="admin"]');
$this->assertTrue(!empty($element), 'Make sure the URL appears when re-editing the action.');
// Make sure that deletions work properly.
$this->drupalGet('admin/config/system/actions');
$this->clickLink(t('Delete'));
$this->assertSession()->statusCodeEquals(200);
$edit = [];
$this->drupalPostForm(NULL, $edit, t('Delete'));
$this->assertSession()->statusCodeEquals(200);
// Make sure that the action was actually deleted.
$this->assertRaw(t('The action %action has been deleted.', ['%action' => $new_action_label]), 'Make sure that we get a delete confirmation message.');
$this->drupalGet('admin/config/system/actions');
$this->assertSession()->statusCodeEquals(200);
$this->assertNoText($new_action_label, "Make sure the action label does not appear on the overview page after we've deleted the action.");
$action = Action::load($action_id);
$this->assertNull($action, 'Make sure the action is gone after being deleted.');
}
}
@@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\action\Functional\Update;
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
/**
* Tests removing action module's configuration.
*
* @group Update
* @group legacy
*/
class ActionConfigTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.8.0.bare.standard.php.gz',
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.action-3022401.php',
];
}
/**
* Tests upgrading action settings.
*
* @see \action_post_update_remove_settings()
*/
public function testUpdateActionPlugins() {
$config = $this->config('action.settings');
$this->assertSame(35, $config->get('recursion_limit'));
// Run updates.
$this->runUpdates();
$config = $this->config('action.settings');
$this->assertTrue($config->isNew());
}
}
@@ -0,0 +1,73 @@
<?php
namespace Drupal\Tests\action\FunctionalJavascript;
use Drupal\Core\Url;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\system\Entity\Action;
/**
* Tests action plugins using Javascript.
*
* @group action
*/
class ActionFormAjaxTest extends WebDriverTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['action', 'action_form_ajax_test'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$user = $this->drupalCreateUser(['administer actions']);
$this->drupalLogin($user);
}
/**
* Tests action plugins with AJAX save their configuration.
*/
public function testActionConfigurationWithAjax() {
$url = Url::fromRoute('action.admin_add', ['action_id' => 'action_form_ajax_test']);
$this->drupalGet($url);
$page = $this->getSession()->getPage();
$id = 'test_plugin';
$this->assertSession()->waitForElementVisible('named', ['button', 'Edit'])->press();
$this->assertSession()->waitForElementVisible('css', '[name="id"]')->setValue($id);
$page->find('css', '[name="having_a_party"]')
->check();
$this->assertSession()->waitForElementVisible('css', '[name="party_time"]');
$party_time = 'Evening';
$page->find('css', '[name="party_time"]')
->setValue($party_time);
$page->find('css', '[value="Save"]')
->click();
$url = Url::fromRoute('entity.action.collection');
$this->assertSession()->pageTextContains('The action has been successfully saved.');
$this->assertSession()->addressEquals($url);
// Check storage.
$instance = Action::load($id);
$configuration = $instance->getPlugin()->getConfiguration();
$this->assertEquals(['party_time' => $party_time], $configuration);
// Configuration should be shown in edit form.
$this->drupalGet($instance->toUrl('edit-form'));
$this->assertSession()->checkboxChecked('having_a_party');
$this->assertSession()->fieldValueEquals('party_time', $party_time);
}
}
@@ -0,0 +1,38 @@
<?php
namespace Drupal\Tests\action\Kernel\Migrate\d6;
use Drupal\Tests\SchemaCheckTestTrait;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
* Upgrade variables to null.
*
* @group migrate_drupal_6
*/
class MigrateActionConfigsTest extends MigrateDrupal6TestBase {
use SchemaCheckTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['action'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('action_settings');
}
/**
* Tests migration of action variables to null.
*/
public function testActionSettings() {
$config = $this->config('action.settings');
$this->assertTrue($config->isNew());
}
}
@@ -0,0 +1,72 @@
<?php
namespace Drupal\Tests\action\Kernel\Migrate\d6;
use Drupal\system\Entity\Action;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
* Tests migration of action items.
*
* @group migrate_drupal_6
*/
class MigrateActionsTest extends MigrateDrupal6TestBase {
public static $modules = ['action', 'comment', 'node'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_action');
}
/**
* Test Drupal 6 action migration to Drupal 8.
*/
public function testActions() {
// Test default actions.
$this->assertEntity('node_publish_action', 'Publish post', 'node', []);
$this->assertEntity('node_make_sticky_action', 'Make post sticky', 'node', []);
$this->assertEntity('user_block_user_action', 'Block current user', 'user', []);
$this->assertEntity('comment_publish_action', 'Publish comment', 'comment', []);
// Test advanced actions.
$this->assertEntity('unpublish_comment_containing_keyword_s_', 'Unpublish comment containing keyword(s)', 'comment', ["keywords" => [0 => "drupal"]]);
$this->assertEntity('change_the_author_of_a_post', 'Change the author of a post', 'node', ["owner_uid" => "2"]);
$this->assertEntity('unpublish_post_containing_keyword_s_', 'Unpublish post containing keyword(s)', 'node', ["keywords" => [0 => "drupal"]]);
$this->assertEntity('display_a_message_to_the_user', 'Display a message to the user', 'system', ["message" => "Drupal migration test"]);
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
"recipient" => "test@example.com",
"subject" => "Drupal migration test",
"message" => "Drupal migration test",
]);
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
}
/**
* Asserts various aspects of an Action entity.
*
* @param string $id
* The expected Action ID.
* @param string $label
* The expected Action label.
* @param string $type
* The expected Action type.
* @param array $configuration
* The expected Action configuration.
*/
protected function assertEntity($id, $label, $type, $configuration) {
$action = Action::load($id);
$this->assertInstanceOf(Action::class, $action);
/** @var \Drupal\system\Entity\Action $action */
$this->assertIdentical($id, $action->id());
$this->assertIdentical($label, $action->label());
$this->assertIdentical($type, $action->getType());
$this->assertIdentical($configuration, $action->get('configuration'));
}
}
@@ -0,0 +1,38 @@
<?php
namespace Drupal\Tests\action\Kernel\Migrate\d7;
use Drupal\Tests\SchemaCheckTestTrait;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
* Upgrade variables to null.
*
* @group migrate_drupal_7
*/
class MigrateActionConfigsTest extends MigrateDrupal7TestBase {
use SchemaCheckTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['action'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('action_settings');
}
/**
* Tests migration of action variables to null.
*/
public function testActionSettings() {
$config = $this->config('action.settings');
$this->assertTrue($config->isNew());
}
}
@@ -0,0 +1,72 @@
<?php
namespace Drupal\Tests\action\Kernel\Migrate\d7;
use Drupal\system\Entity\Action;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
* Tests migration of action items.
*
* @group action
*/
class MigrateActionsTest extends MigrateDrupal7TestBase {
public static $modules = ['action', 'comment', 'node'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d7_action');
}
/**
* Test Drupal 7 action migration to Drupal 8.
*/
public function testActions() {
// Test default actions.
$this->assertEntity('node_publish_action', 'Publish content', 'node', []);
$this->assertEntity('node_make_sticky_action', 'Make content sticky', 'node', []);
$this->assertEntity('user_block_user_action', 'Block current user', 'user', []);
$this->assertEntity('comment_publish_action', 'Publish comment', 'comment', []);
// Test advanced actions.
$this->assertEntity('unpublish_comment_containing_keyword_s_', 'Unpublish comment containing keyword(s)', 'comment', ["keywords" => [0 => "drupal"]]);
$this->assertEntity('change_the_author_of_content', 'Change the author of content', 'node', ["owner_uid" => "2"]);
$this->assertEntity('unpublish_content_containing_keyword_s_', 'Unpublish content containing keyword(s)', 'node', ["keywords" => [0 => "drupal"]]);
$this->assertEntity('display_a_message_to_the_user', 'Display a message to the user', 'system', ["message" => "Drupal migration test"]);
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
"recipient" => "test@example.com",
"subject" => "Drupal migration test",
"message" => "Drupal migration test",
]);
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
}
/**
* Asserts various aspects of an Action entity.
*
* @param string $id
* The expected Action ID.
* @param string $label
* The expected Action label.
* @param string $type
* The expected Action type.
* @param array $configuration
* The expected Action configuration.
*/
protected function assertEntity($id, $label, $type, $configuration) {
$action = Action::load($id);
$this->assertInstanceOf(Action::class, $action);
/** @var \Drupal\system\Entity\Action $action */
$this->assertIdentical($id, $action->id());
$this->assertIdentical($label, $action->label());
$this->assertIdentical($type, $action->getType());
$this->assertIdentical($configuration, $action->get('configuration'));
}
}
@@ -0,0 +1,62 @@
<?php
namespace Drupal\Tests\action\Kernel\Plugin\migrate\source;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests actions source plugin.
*
* @covers \Drupal\action\Plugin\migrate\source\Action
* @group action
*/
class ActionTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['action', 'migrate_drupal', 'system'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0][0]['actions'] = [
[
'aid' => 'Redirect to node list page',
'type' => 'system',
'callback' => 'system_goto_action',
'parameters' => 'a:1:{s:3:"url";s:4:"node";}',
'description' => 'Redirect to node list page',
],
[
'aid' => 'Test notice email',
'type' => 'system',
'callback' => 'system_send_email_action',
'parameters' => 'a:3:{s:9:"recipient";s:7:"%author";s:7:"subject";s:4:"Test";s:7:"message";s:4:"Test',
'description' => 'Test notice email',
],
[
'aid' => 'comment_publish_action',
'type' => 'comment',
'callback' => 'comment_publish_action',
'parameters' => NULL,
'description' => NULL,
],
[
'aid' => 'node_publish_action',
'type' => 'comment',
'callback' => 'node_publish_action',
'parameters' => NULL,
'description' => NULL,
],
];
// The expected results are identical to the source data.
$tests[0][1] = $tests[0][0]['actions'];
return $tests;
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\action\Unit\Menu;
use Drupal\Tests\Core\Menu\LocalTaskIntegrationTestBase;
/**
* Tests action local tasks.
*
* @group action
*/
class ActionLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = ['action' => 'core/modules/action'];
parent::setUp();
}
/**
* Tests local task existence.
*/
public function testActionLocalTasks() {
$this->assertLocalTasks('entity.action.collection', [['action.admin']]);
}
}