Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -29,8 +29,9 @@ function action_help($route_name, RouteMatchInterface $route_match) {
$output = '<p>' . t('There are two types of actions: simple and advanced. Simple actions do not require any additional configuration and are listed here automatically. Advanced actions need to be created and configured before they can be used because they have options that need to be specified; for example, sending an email to a specified address or unpublishing content containing certain words. To create an advanced action, select the action from the drop-down list in the advanced action section below and click the <em>Create</em> button.') . '</p>';
return $output;
case 'action.admin_add':
case 'entity.action.edit_form':
return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Description</em> field is recommended in order to better identify the precise action taking place.');
return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Label</em> field is recommended in order to better identify the precise action taking place.');
}
}

View file

@ -29,4 +29,3 @@ entity.action.delete_form:
_title: 'Delete'
requirements:
_permission: 'administer actions'

View file

@ -15,6 +15,6 @@ function action_views_form_substitutions() {
'#attributes' => ['class' => ['action-table-select-all']],
];
return [
'<!--action-bulk-form-select-all-->' => drupal_render($select_all),
'<!--action-bulk-form-select-all-->' => \Drupal::service('renderer')->render($select_all),
];
}

View file

@ -3,10 +3,12 @@ label: Action configuration
migration_tags:
- Drupal 6
- Drupal 7
- Configuration
source:
plugin: variable
variables:
- actions_max_stack
source_module: action
process:
recursion_limit: actions_max_stack
destination:

View file

@ -2,6 +2,7 @@ id: d6_action
label: Actions
migration_tags:
- Drupal 6
- Configuration
source:
plugin: action
process:
@ -23,6 +24,12 @@ process:
imagecache_flush_action: 0
imagecache_generate_all_action: 0
imagecache_generate_action: 0
comment_publish_action: entity:publish_action:comment
comment_unpublish_action: entity:unpublish_action:comment
comment_save_action: entity:save_action:comment
node_publish_action: entity:publish_action:node
node_unpublish_action: entity:unpublish_action:node
node_save_action: entity:save_action:node
bypass: true
-
plugin: skip_on_empty

View file

@ -2,6 +2,7 @@ id: d7_action
label: Actions
migration_tags:
- Drupal 7
- Configuration
source:
plugin: action
process:
@ -20,6 +21,12 @@ process:
system_send_email_action: action_send_email_action
system_message_action: action_message_action
system_block_ip_action: 0
comment_publish_action: entity:publish_action:comment
comment_unpublish_action: entity:unpublish_action:comment
comment_save_action: entity:save_action:comment
node_publish_action: entity:publish_action:node
node_unpublish_action: entity:unpublish_action:node
node_save_action: entity:save_action:node
bypass: true
-
plugin: skip_on_empty

View file

@ -2,67 +2,28 @@
namespace Drupal\action;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Action\ActionManager;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for action add forms.
*
* @internal
*/
class ActionAddForm extends ActionFormBase {
/**
* The action manager.
*
* @var \Drupal\Core\Action\ActionManager
*/
protected $actionManager;
/**
* Constructs a new ActionAddForm.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The action storage.
* @param \Drupal\Core\Action\ActionManager $action_manager
* The action plugin manager.
*/
public function __construct(EntityStorageInterface $storage, ActionManager $action_manager) {
parent::__construct($storage);
$this->actionManager = $action_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('action'),
$container->get('plugin.manager.action')
);
}
/**
* {@inheritdoc}
*
* @param string $action_id
* The hashed version of the action ID.
* The action ID.
*/
public function buildForm(array $form, FormStateInterface $form_state, $action_id = NULL) {
// In \Drupal\action\Form\ActionAdminManageForm::buildForm() the action
// are hashed. Here we have to decrypt it to find the desired action ID.
foreach ($this->actionManager->getDefinitions() as $id => $definition) {
$key = Crypt::hashBase64($id);
if ($key === $action_id) {
$this->entity->setPlugin($id);
// Derive the label and type from the action definition.
$this->entity->set('label', $definition['label']);
$this->entity->set('type', $definition['type']);
break;
}
}
$this->entity->setPlugin($action_id);
// Derive the label and type from the action definition.
$definition = $this->entity->getPluginDefinition();
$this->entity->set('label', $definition['label']);
$this->entity->set('type', $definition['type']);
return parent::buildForm($form, $form_state);
}

View file

@ -4,6 +4,8 @@ namespace Drupal\action;
/**
* Provides a form for action edit forms.
*
* @internal
*/
class ActionEditForm extends ActionFormBase {

View file

@ -13,13 +13,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
abstract class ActionFormBase extends EntityForm {
/**
* The action plugin being configured.
*
* @var \Drupal\Core\Action\ActionInterface
*/
protected $plugin;
/**
* The action storage.
*
@ -27,6 +20,13 @@ abstract class ActionFormBase extends EntityForm {
*/
protected $storage;
/**
* The action entity.
*
* @var \Drupal\system\ActionConfigEntityInterface
*/
protected $entity;
/**
* Constructs a new action form.
*
@ -46,14 +46,6 @@ abstract class ActionFormBase extends EntityForm {
);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$this->plugin = $this->entity->getPlugin();
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
@ -85,8 +77,8 @@ abstract class ActionFormBase extends EntityForm {
'#value' => $this->entity->getType(),
];
if ($this->plugin instanceof PluginFormInterface) {
$form += $this->plugin->buildConfigurationForm($form, $form_state);
if ($plugin = $this->getPlugin()) {
$form += $plugin->buildConfigurationForm($form, $form_state);
}
return parent::form($form, $form_state);
@ -96,7 +88,7 @@ abstract class ActionFormBase extends EntityForm {
* Determines if the action already exists.
*
* @param string $id
* The action ID
* The action ID.
*
* @return bool
* TRUE if the action exists, FALSE otherwise.
@ -120,9 +112,8 @@ abstract class ActionFormBase extends EntityForm {
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
if ($this->plugin instanceof PluginFormInterface) {
$this->plugin->validateConfigurationForm($form, $form_state);
if ($plugin = $this->getPlugin()) {
$plugin->validateConfigurationForm($form, $form_state);
}
}
@ -131,9 +122,8 @@ abstract class ActionFormBase extends EntityForm {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
if ($this->plugin instanceof PluginFormInterface) {
$this->plugin->submitConfigurationForm($form, $form_state);
if ($plugin = $this->getPlugin()) {
$plugin->submitConfigurationForm($form, $form_state);
}
}
@ -142,9 +132,22 @@ abstract class ActionFormBase extends EntityForm {
*/
public function save(array $form, FormStateInterface $form_state) {
$this->entity->save();
drupal_set_message($this->t('The action has been successfully saved.'));
$this->messenger()->addStatus($this->t('The action has been successfully saved.'));
$form_state->setRedirect('entity.action.collection');
}
/**
* Gets the action plugin while ensuring it implements configuration form.
*
* @return \Drupal\Core\Action\ActionInterface|\Drupal\Core\Plugin\PluginFormInterface|null
* The action plugin, or NULL if it does not implement configuration forms.
*/
protected function getPlugin() {
if ($this->entity->getPlugin() instanceof PluginFormInterface) {
return $this->entity->getPlugin();
}
return NULL;
}
}

View file

@ -108,12 +108,12 @@ class ActionListBuilder extends ConfigEntityListBuilder {
* {@inheritdoc}
*/
public function render() {
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
$build['action_header']['#markup'] = '<h3>' . $this->t('Available actions:') . '</h3>';
$build['action_table'] = parent::render();
if (!$this->hasConfigurableActions) {
unset($build['action_table']['table']['#header']['operations']);
}
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
return $build;
}

View file

@ -3,13 +3,14 @@
namespace Drupal\action\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Action\ActionManager;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a configuration form for configurable actions.
*
* @internal
*/
class ActionAdminManageForm extends FormBase {
@ -53,10 +54,10 @@ class ActionAdminManageForm extends FormBase {
$actions = [];
foreach ($this->manager->getDefinitions() as $id => $definition) {
if (is_subclass_of($definition['class'], '\Drupal\Core\Plugin\PluginFormInterface')) {
$key = Crypt::hashBase64($id);
$actions[$key] = $definition['label'] . '...';
$actions[$id] = $definition['label'];
}
}
asort($actions);
$form['parent'] = [
'#type' => 'details',
'#title' => $this->t('Create an advanced action'),
@ -68,10 +69,10 @@ class ActionAdminManageForm extends FormBase {
'#title' => $this->t('Action'),
'#title_display' => 'invisible',
'#options' => $actions,
'#empty_option' => $this->t('Choose an advanced action'),
'#empty_option' => $this->t('- Select -'),
];
$form['parent']['actions'] = [
'#type' => 'actions'
'#type' => 'actions',
];
$form['parent']['actions']['submit'] = [
'#type' => 'submit',

View file

@ -7,6 +7,8 @@ use Drupal\Core\Url;
/**
* Builds a form to delete an action.
*
* @internal
*/
class ActionDeleteForm extends EntityDeleteForm {

View file

@ -139,12 +139,11 @@ class EmailAction extends ConfigurableActionBase implements ContainerFactoryPlug
}
$params = ['context' => $this->configuration];
if ($this->mailManager->mail('system', 'action_send_email', $recipient, $langcode, $params)) {
$message = $this->mailManager->mail('system', 'action_send_email', $recipient, $langcode, $params);
// Error logging is handled by \Drupal\Core\Mail\MailManager::mail().
if ($message['result']) {
$this->logger->notice('Sent email to %recipient', ['%recipient' => $recipient]);
}
else {
$this->logger->error('Unable to send email to %recipient', ['%recipient' => $recipient]);
}
}
/**

View file

@ -40,7 +40,7 @@ class GotoAction extends ConfigurableActionBase implements ContainerFactoryPlugi
protected $unroutedUrlAssembler;
/**
* Constructs a new DeleteNode object.
* Constructs a GotoAction object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
@ -92,7 +92,7 @@ class GotoAction extends ConfigurableActionBase implements ContainerFactoryPlugi
$url = $this->unroutedUrlAssembler->assemble($uri, $options);
}
$response = new RedirectResponse($url);
$listener = function($event) use ($response) {
$listener = function ($event) use ($response) {
$event->setResponse($response);
};
// Add the listener to the event dispatcher.

View file

@ -5,6 +5,7 @@ namespace Drupal\action\Plugin\Action;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
@ -36,6 +37,13 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
*/
protected $renderer;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Constructs a MessageAction object.
*
@ -49,19 +57,22 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
* The token service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token, RendererInterface $renderer) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token, RendererInterface $renderer, MessengerInterface $messenger) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->token = $token;
$this->renderer = $renderer;
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'), $container->get('renderer'));
return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'), $container->get('renderer'), $container->get('messenger'));
}
/**
@ -77,7 +88,7 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
];
// @todo Fix in https://www.drupal.org/node/2577827
drupal_set_message($this->renderer->renderPlain($build));
$this->messenger->addStatus($this->renderer->renderPlain($build));
}
/**

View file

@ -10,7 +10,7 @@ use Drupal\migrate\Row;
*
* @MigrateSource(
* id = "action",
* source_provider = "system"
* source_module = "system"
* )
*/
class Action extends DrupalSqlBase {

View file

@ -5,6 +5,6 @@ package: Testing
version: VERSION
core: 8.x
dependencies:
- action
- views
- node
- drupal:action
- drupal:views
- drupal:node

View file

@ -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

View file

@ -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.'

View file

@ -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');
}
}

View file

@ -28,10 +28,10 @@ class ActionListTest extends BrowserTestBase {
// Ensure the empty text appears on the action list page.
/** @var $storage \Drupal\Core\Entity\EntityStorageInterface */
$storage = $this->container->get('entity.manager')->getStorage('action');
$actions = $storage->loadMultiple();
$actions = $storage->loadMultiple();
$storage->delete($actions);
$this->drupalGet('/admin/config/system/actions');
$this->assertRaw('There is no Action yet.');
$this->assertRaw('There are no actions yet.');
}
}

View file

@ -27,7 +27,7 @@ class ActionUninstallTest extends BrowserTestBase {
$storage = $this->container->get('entity_type.manager')->getStorage('action');
$storage->resetCache(['user_block_user_action']);
$this->assertTrue($storage->load('user_block_user_action'), 'Configuration entity \'user_block_user_action\' still exists after uninstalling action module.' );
$this->assertTrue($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);

View file

@ -148,7 +148,7 @@ class BulkFormTest extends BrowserTestBase {
$errors = $this->xpath('//div[contains(@class, "messages--status")]');
$this->assertFalse($errors, 'No action message shown.');
$this->drupalPostForm(NULL, [], t('Delete'));
$this->assertText(t('Deleted 5 posts.'));
$this->assertText(t('Deleted 5 content items.'));
// Check if we got redirected to the original page.
$this->assertUrl('test_bulk_form');
}

View file

@ -2,7 +2,6 @@
namespace Drupal\Tests\action\Functional;
use Drupal\Component\Utility\Crypt;
use Drupal\system\Entity\Action;
use Drupal\Tests\BrowserTestBase;
@ -31,7 +30,7 @@ class ConfigurationTest extends BrowserTestBase {
// Make a POST request to admin/config/system/actions.
$edit = [];
$edit['action'] = Crypt::hashBase64('action_goto_action');
$edit['action'] = 'action_goto_action';
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
$this->assertResponse(200);
@ -41,17 +40,18 @@ class ConfigurationTest extends BrowserTestBase {
$edit['label'] = $action_label;
$edit['id'] = strtolower($action_label);
$edit['url'] = 'admin';
$this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('action_goto_action'), $edit, t('Save'));
$this->drupalPostForm('admin/config/system/actions/add/action_goto_action', $edit, t('Save'));
$this->assertResponse(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'));
preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
$aid = $matches[1];
$edit = [];
$new_action_label = $this->randomMachineName();
$edit['label'] = $new_action_label;
@ -73,7 +73,7 @@ class ConfigurationTest extends BrowserTestBase {
$this->clickLink(t('Delete'));
$this->assertResponse(200);
$edit = [];
$this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
$this->drupalPostForm(NULL, $edit, t('Delete'));
$this->assertResponse(200);
// Make sure that the action was actually deleted.
@ -82,7 +82,7 @@ class ConfigurationTest extends BrowserTestBase {
$this->assertResponse(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($aid);
$action = Action::load($action_id);
$this->assertFalse($action, 'Make sure the action is gone after being deleted.');
}

View file

@ -0,0 +1,68 @@
<?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 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);
}
}

View file

@ -40,7 +40,7 @@ class MigrateActionsTest extends MigrateDrupal6TestBase {
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
"recipient" => "test@example.com",
"subject" => "Drupal migration test",
"message" => "Drupal migration test"
"message" => "Drupal migration test",
]);
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);

View file

@ -40,7 +40,7 @@ class MigrateActionsTest extends MigrateDrupal7TestBase {
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
"recipient" => "test@example.com",
"subject" => "Drupal migration test",
"message" => "Drupal migration test"
"message" => "Drupal migration test",
]);
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);

View file

@ -0,0 +1,65 @@
<?php
namespace Drupal\Tests\action\Kernel\Plugin\Action;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests for the EmailAction plugin.
*
* @group action
*/
class EmailActionTest extends KernelTestBase {
use AssertMailTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user', 'action', 'dblog'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installSchema('dblog', ['watchdog']);
}
/**
* Test the email action plugin.
*/
public function testEmailAction() {
/** @var \Drupal\Core\Action\ActionManager $plugin_manager */
$plugin_manager = $this->container->get('plugin.manager.action');
$configuration = [
'recipient' => 'test@example.com',
'subject' => 'Test subject',
'message' => 'Test message',
];
$plugin_manager
->createInstance('action_send_email_action', $configuration)
->execute();
$mails = $this->getMails();
$this->assertCount(1, $this->getMails());
$this->assertEquals('test@example.com', $mails[0]['to']);
$this->assertEquals('Test subject', $mails[0]['subject']);
$this->assertEquals("Test message\n", $mails[0]['body']);
// Ensure that the email sending is logged.
$log = \Drupal::database()
->select('watchdog', 'w')
->fields('w', ['message', 'variables'])
->orderBy('wid', 'DESC')
->range(0, 1)
->execute()
->fetch();
$this->assertEquals($log->message, 'Sent email to %recipient');
$variables = unserialize($log->variables);
$this->assertEquals($variables['%recipient'], 'test@example.com');
}
}

View file

@ -15,7 +15,7 @@ class ActionTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['action', 'migrate_drupal'];
public static $modules = ['action', 'migrate_drupal', 'system'];
/**
* {@inheritdoc}