View source
<?php
namespace Drupal\Tests\rules\Functional;
use Drupal\rules\Context\ContextConfig;
use Drupal\user\Entity\User;
class ConfigureAndExecuteTest extends RulesBrowserTestBase {
protected static $modules = [
'rules',
];
protected $profile = 'minimal';
protected $account;
protected $storage;
protected $expressionManager;
protected function setUp() : void {
parent::setUp();
$this->storage = $this->container
->get('entity_type.manager')
->getStorage('rules_reaction_rule');
$this->expressionManager = $this->container
->get('plugin.manager.rules_expression');
$type = $this->container
->get('entity_type.manager')
->getStorage('node_type')
->create([
'type' => 'article',
'name' => 'Article',
]);
$type->save();
$this->account = $this->drupalCreateUser([
'create article content',
'edit any article content',
'administer rules',
'administer site configuration',
]);
$this->drupalLogin($this->account);
$this->createRole([
'administer nodes',
], 'test-editor', 'Test Editor');
}
protected function createRule($label, $machine_name, $event, $description = '') {
$this->drupalGet('admin/config/workflow/rules');
$this->clickLink('Add reaction rule');
$this->fillField('Label', $label);
$this->fillField('Machine-readable name', $machine_name);
$this->fillField('React on event', $event);
$this->fillField('Description', $description);
$this->pressButton('Save');
$this->assertSession()
->pageTextContains('Reaction rule ' . $label . ' has been created');
$config_factory = $this->container
->get('config.factory');
$rule = $config_factory->get('rules.reaction.' . $machine_name);
return $rule;
}
public function testConfigureAndExecute() {
$this->createRule('Test rule', 'test_rule', 'rules_entity_presave:node');
$this->clickLink('Add condition');
$this->fillField('Condition', 'rules_data_comparison');
$this->pressButton('Continue');
$this->fillField('context_definitions[data][setting]', 'node.title.0.value');
$this->fillField('context_definitions[value][setting]', 'Test title');
$this->pressButton('Save');
$this->clickLink('Add action');
$this->fillField('Action', 'rules_system_message');
$this->pressButton('Continue');
$this->fillField('context_definitions[message][setting]', 'Title matched "Test title"!');
$this->fillField('context_definitions[type][setting]', 'status');
$this->pressButton('Save');
$this->pressButton('Save');
$assert = $this->assertSession();
$this->drupalGet('node/add/article');
$this->fillField('Title', 'Test title');
$this->pressButton('Save');
$assert->pageTextContains('Title matched "Test title"!');
$this->drupalGet('node/add/article');
$this->fillField('Title', 'Test title');
$this->pressButton('Save');
$assert->pageTextContains('Title matched "Test title"!');
$this->drupalGet('admin/config/workflow/rules');
$this->clickLink('Disable');
$this->drupalGet('node/add/article');
$this->fillField('Title', 'Test title');
$this->pressButton('Save');
$assert->pageTextNotContains('Title matched "Test title"!');
$this->drupalGet('admin/config/workflow/rules');
$this->clickLink('Enable');
$this->drupalGet('node/add/article');
$this->fillField('Title', 'Test title');
$this->pressButton('Save');
$assert->pageTextContains('Title matched "Test title"!');
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule');
$this->clickLink('Edit', 0);
$this->getSession()
->getPage()
->checkField('negate');
$this->pressButton('Save');
$this->pressButton('Save');
$this->drupalGet('node/add/article');
$this->fillField('Title', 'Test title');
$this->pressButton('Save');
$assert->pageTextNotContains('Title matched "Test title"!');
}
public function testAddEventAndExecute() {
$node = $this->drupalCreateNode([
'type' => 'article',
]);
$message = 'Rule is triggered';
$rule = $this->expressionManager
->createRule();
$rule->addAction('rules_system_message', ContextConfig::create()->setValue('message', $message)
->setValue('type', 'status'));
$config_entity = $this->storage
->create([
'id' => 'test_rule',
'label' => 'Test rule',
'events' => [
[
'event_name' => 'rules_entity_insert:node--article',
],
],
'expression' => $rule->getConfiguration(),
]);
$config_entity->save();
$this->drupalLogin($this->account);
$assert = $this->assertSession();
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule');
$this->clickLink('Add event');
$assert->pageTextContains('Add event to Test rule');
$assert->pageTextContains('Event selection');
$assert->pageTextContains('React on event');
$this->findField('events[0][event_name]')
->selectOption('rules_entity_update:node');
$this->pressButton('Add');
$this->findField('bundle')
->selectOption('article');
$this->pressButton('Add');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextContains($message);
}
public function testDeleteEventAndExecute() {
$message = 'Rule is triggered';
$rule = $this->expressionManager
->createRule();
$rule->addAction('rules_system_message', ContextConfig::create()->setValue('message', $message)
->setValue('type', 'status'));
$config_entity = $this->storage
->create([
'id' => 'test_rule',
'label' => 'Test rule',
'events' => [
[
'event_name' => 'rules_entity_insert:node',
],
[
'event_name' => 'rules_entity_update:node',
],
],
'expression' => $rule->getConfiguration(),
]);
$config_entity->save();
$this->drupalLogin($this->account);
$assert = $this->assertSession();
$this->drupalGet('node/add/article');
$this->submitForm([
'title[0][value]' => 'Foo',
], 'Save');
$assert->pageTextContains($message);
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule');
$this->clickLinkByHref('event-delete/rules_entity_insert');
$assert->pageTextContains('Are you sure you want to delete the event After saving a new content item entity from Test rule?');
$this->pressButton('Delete');
$assert->pageTextContains('Deleted event After saving a new content item entity from Test rule.');
$this->drupalGet('node/add/article');
$this->submitForm([
'title[0][value]' => 'Bar',
], 'Save');
$node = $this->drupalGetNodeByTitle('Bar');
$assert->pageTextNotContains($message);
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextContains($message);
}
public function testTwoRulesSameEvent() {
$assert = $this->assertSession();
$rule1 = $this->expressionManager
->createRule();
$rule1->addCondition('rules_data_comparison', ContextConfig::create()->map('data', 'node.title.value')
->setValue('operation', 'contains')
->setValue('value', 'Two Rules Same Event'));
$message1 = 'RULE ONE is triggered';
$rule1->addAction('rules_system_message', ContextConfig::create()->setValue('message', $message1)
->setValue('type', 'status'));
$config_entity = $this->storage
->create([
'id' => 'rule1',
'label' => 'Rule One',
'events' => [
[
'event_name' => 'rules_entity_presave:node',
],
],
'expression' => $rule1->getConfiguration(),
]);
$config_entity->save();
$this->drupalGet('node/add/article');
$this->submitForm([
'title[0][value]' => 'Two Rules Same Event',
], 'Save');
$node = $this->drupalGetNodeByTitle('Two Rules Same Event');
$assert->pageTextContains($message1);
$rule2 = $this->expressionManager
->createRule();
$rule2->addCondition('rules_data_comparison', ContextConfig::create()->map('data', 'node.title.value')
->setValue('operation', 'contains')
->setValue('value', 'Two Rules Same Event'));
$message2 = 'RULE TWO is triggered';
$rule2->addAction('rules_system_message', ContextConfig::create()->setValue('message', $message2)
->setValue('type', 'status'));
$config_entity = $this->storage
->create([
'id' => 'rule2',
'label' => 'Rule Two',
'events' => [
[
'event_name' => 'rules_entity_presave:node',
],
],
'expression' => $rule2->getConfiguration(),
]);
$config_entity->save();
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextContains($message1);
$assert->pageTextContains($message2);
$this->drupalGet('admin/config/workflow/rules');
$this->clickLinkByHref('disable/rule2');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextContains($message1);
$assert->pageTextNotContains($message2);
$this->drupalGet('admin/config/workflow/rules');
$this->clickLinkByHref('enable/rule2');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextContains($message1);
$assert->pageTextContains($message2);
$message1updated = 'RULE ONE has a new message.';
$this->drupalGet('admin/config/workflow/rules/reactions/edit/rule1');
$this->clickLink('Edit', 1);
$this->fillField('context_definitions[message][setting]', $message1updated);
$this->pressButton('Save');
$this->pressButton('Save');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextNotContains($message1);
$assert->pageTextContains($message1updated);
$assert->pageTextContains($message2);
$this->drupalGet('admin/config/workflow/rules');
$this->clickLinkByHref('delete/rule1');
$this->pressButton('Delete');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextNotContains($message1);
$assert->pageTextNotContains($message1updated);
$assert->pageTextContains($message2);
$this->drupalGet('admin/config/workflow/rules');
$this->clickLinkByHref('disable/rule2');
$this->drupalGet('node/' . $node->id() . '/edit/');
$this->submitForm([], 'Save');
$assert->pageTextNotContains($message1);
$assert->pageTextNotContains($message1updated);
$assert->pageTextNotContains($message2);
}
public function testMultipleInputContext() {
$this->drupalGet('admin/config/workflow/rules');
$this->clickLink('Add reaction rule');
$this->fillField('Label', 'Test Multiple Input via UI');
$this->fillField('Machine-readable name', 'test_rule');
$this->fillField('React on event', 'rules_entity_insert:node');
$this->pressButton('Save');
$this->clickLink('Add action');
$this->fillField('Action', 'rules_send_email');
$this->pressButton('Continue');
$suboptimal_user_input = [
" \r\nwhitespace at beginning of input\r\n",
"text\r\n",
"trailing space \r\n",
"\rleading terminator\r\n",
" leading space\r\n",
"multiple words, followed by primitive values\r\n",
"0\r\n",
"0.0\r\n",
"128\r\n",
" false\r\n",
"true \r\n",
"null\r\n",
"terminator r\r",
"two empty lines\n\r\n\r",
"terminator n\n",
"terminator nr\n\r",
"whitespace at end of input\r\n \r\n",
];
$this->fillField('context_definitions[to][setting]', implode($suboptimal_user_input));
$this->fillField('context_definitions[subject][setting]', 'Hello');
$this->fillField('context_definitions[message][setting]', 'Dear Heart');
$this->pressButton('Save');
$this->pressButton('Save');
$expected_config_value = [
"whitespace at beginning of input",
"text",
"trailing space",
"leading terminator",
"leading space",
"multiple words, followed by primitive values",
"0",
"0.0",
"128",
"false",
"true",
"null",
"terminator r",
"two empty lines",
"terminator n",
"terminator nr",
"whitespace at end of input",
];
$config_factory = $this->container
->get('config.factory');
$config_factory->clearStaticCache();
$rule = $config_factory->get('rules.reaction.test_rule');
$to = $rule->get('expression.actions.actions.0.context_values.to');
$this->assertEquals($expected_config_value, $to);
}
public function testAssignmentRestriction() {
$rule = $this->expressionManager
->createRule();
$condition1 = $this->expressionManager
->createCondition('rules_data_comparison');
$rule->addExpressionObject($condition1);
$action1 = $this->expressionManager
->createAction('rules_system_message');
$rule->addExpressionObject($action1);
$config_entity = $this->storage
->create([
'id' => 'test_rule',
'expression' => $rule->getConfiguration(),
]);
$config_entity->save();
$assert = $this->assertSession();
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule');
$assert->statusCodeEquals(200);
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule/edit/' . $condition1->getUuid());
$assert->statusCodeEquals(200);
$assert->buttonNotExists('edit-context-definitions-data-switch-button');
$assert->elementExists('xpath', '//input[@id="edit-context-definitions-data-setting" and contains(@class, "rules-autocomplete")]');
$assert->buttonNotExists('edit-context-definitions-operation-switch-button');
$assert->buttonExists('edit-context-definitions-value-switch-button');
$assert->elementExists('xpath', '//input[@id="edit-context-definitions-value-setting" and not(contains(@class, "rules-autocomplete"))]');
$this->drupalGet('admin/config/workflow/rules/reactions/edit/test_rule/edit/' . $action1->getUuid());
$assert->statusCodeEquals(200);
$assert->buttonExists('edit-context-definitions-message-switch-button');
$assert->elementExists('xpath', '//input[@id="edit-context-definitions-message-setting" and not(contains(@class, "rules-autocomplete"))]');
$assert->buttonExists('edit-context-definitions-type-switch-button');
$assert->buttonNotExists('edit-context-definitions-repeat-switch-button');
}
public function testUpcastInCondition() {
$assert = $this->assertSession();
$rule = $this->expressionManager
->createRule();
$rule->addCondition('rules_user_has_role', ContextConfig::create()->map('user', '@user.current_user_context:current_user')
->setValue('roles', [
'test-editor',
]));
$message = '-- RULE to test upcasting in condition --';
$rule->addAction('rules_system_message', ContextConfig::create()->setValue('message', $message)
->setValue('type', 'status'));
$expr_id = 'test_upcast';
$config_entity = $this->storage
->create([
'id' => $expr_id,
'expression' => $rule->getConfiguration(),
'events' => [
[
'event_name' => 'rules_user_login',
],
],
]);
$config_entity->save();
$this->drupalLogin($this->account);
$assert->pageTextNotContains($message);
$this->account
->addRole('test-editor');
$this->account
->save();
$this->drupalLogout();
$this->drupalLogin($this->account);
$assert->pageTextContains($message);
$this->account
->removeRole('test-editor');
$this->account
->save();
$this->drupalLogout();
$this->drupalLogin($this->account);
$assert->pageTextNotContains($message);
}
public function testUpcastInAction() {
$this->drupalLogin($this->account);
$rule = $this->expressionManager
->createRule();
$rule->addAction('rules_user_role_add', ContextConfig::create()->map('user', '@user.current_user_context:current_user')
->setValue('roles', [
'test-editor',
]));
$expr_id = 'test_upcast';
$config_entity = $this->storage
->create([
'id' => $expr_id,
'expression' => $rule->getConfiguration(),
'events' => [
[
'event_name' => 'rules_entity_insert:node',
],
],
]);
$config_entity->save();
$this->assertEmpty(array_intersect([
'test-editor',
], $this->account
->getRoles()));
$this->drupalCreateNode([
'type' => 'article',
'title' => 'Upcasting role in action',
]);
$account = User::load($this->account
->id());
$this->assertNotEmpty(array_intersect([
'test-editor',
], $account->getRoles()));
}
}