class RulesTriggerTestCase
Same name in other branches
- 7.x-2.x tests/rules.test \RulesTriggerTestCase
Test triggering rules.
Hierarchy
- class \RulesTriggerTestCase extends \DrupalWebTestCase
Expanded class hierarchy of RulesTriggerTestCase
File
-
d7-tests/
rules_test_trigger_case.test, line 17
View source
class RulesTriggerTestCase extends DrupalWebTestCase {
static function getInfo() {
return array(
'name' => 'Reaction Rules',
'description' => 'Tests triggering reactive rules.',
'group' => 'Rules',
);
}
function setUp() {
parent::setUp('rules', 'rules_test');
RulesLog::logger()->clear();
variable_set('rules_debug_log', 1);
}
protected function createTestRule($action = TRUE, $event = 'node_presave') {
$rule = rules_reaction_rule();
$rule->event($event)
->condition(rules_condition('data_is', array(
'data:select' => 'node:status',
'value' => TRUE,
))->negate())
->condition('data_is', array(
'data:select' => 'node:type',
'value' => 'page',
));
if ($action) {
$rule->action('rules_action_delete_node');
}
return $rule;
}
/**
* Tests CRUD for reaction rules - making sure the events are stored properly.
*/
function testReactiveRuleCreation() {
$rule = $this->createTestRule();
$rule->save();
$result = db_query("SELECT event FROM {rules_trigger} WHERE id = :id", array(
':id' => $rule->id,
));
$this->assertEqual($result->fetchField(), 'node_presave', 'Associated event has been saved.');
// Try updating.
$rule->removeEvent('node_presave');
$rule->event('node_insert');
$rule->event('node_update');
$rule->active = FALSE;
$rule->integrityCheck()
->save();
$result = db_query("SELECT event FROM {rules_trigger} WHERE id = :id", array(
':id' => $rule->id,
));
$this->assertEqual($result->fetchCol(), array_values($rule->events()), 'Updated associated events.');
// Try deleting.
$rule->delete();
$result = db_query("SELECT event FROM {rules_trigger} WHERE id = :id", array(
':id' => $rule->id,
));
$this->assertEqual($result->fetchField(), FALSE, 'Deleted associated events.');
}
/**
* Tests creating and triggering a basic reaction rule.
*/
function testBasicReactionRule() {
$node = $this->drupalCreateNode(array(
'type' => 'page',
));
$rule = $this->createTestRule();
$rule->integrityCheck()
->save();
// Test the basics of the event set work right.
$event = rules_get_cache('event_node_presave');
$this->assertEqual(array_keys($event->parameterInfo()), array(
'node',
), 'EventSet returns correct argument info.');
// Trigger the rule by updating the node.
$nid = $node->nid;
$node->status = 0;
node_save($node);
RulesLog::logger()->checkLog();
$this->assertFalse(node_load($nid), 'Rule successfully triggered and executed');
//debug(RulesLog::logger()->render());
}
/**
* Test a rule using a handler to load a variable.
*/
function testVariableHandler() {
$node = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
$rule = $this->createTestRule(FALSE, 'node_update');
$rule->action('rules_node_publish_action_save', array(
'node:select' => 'node_unchanged',
));
// Test without recursion prevention to make sure recursive invocations
// work right too. This rule won't ran in an infinite loop anyway.
$rule->recursion = TRUE;
$rule->label = 'rule 1';
$rule->integrityCheck()
->save();
$node->status = 0;
$node->sticky = 1;
node_save($node);
RulesLog::logger()->checkLog();
entity_get_controller('node')->resetCache();
$node = node_load($node->nid);
$this->assertFalse($node->sticky, 'Parameter has been loaded and saved.');
$this->assertTrue($node->status, 'Action has been executed.');
// Ensure the rule was evaluated a second time
$text = RulesLog::logger()->render();
$msg = RulesTestCase::t('Evaluating conditions of rule %rule 1', array(
'rule 1',
));
$pos = strpos($text, $msg);
$pos = $pos !== FALSE ? strpos($text, $msg, $pos) : FALSE;
$this->assertTrue($pos !== FALSE, "Recursion prevented.");
//debug(RulesLog::logger()->render());
}
/**
* Test aborting silently when handlers are not able to load.
*/
function testVariableHandlerFailing() {
$rule = $this->createTestRule(FALSE, 'node_presave');
$rule->action('rules_node_publish_action_save', array(
'node:select' => 'node_unchanged',
));
$rule->integrityCheck()
->save();
// On insert it's not possible to get the unchanged node during presave.
$node = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
//debug(RulesLog::logger()->render());
$text = RulesTestCase::t('Unable to load variable %node_unchanged, aborting.', array(
'node_unchanged',
));
$this->assertTrue(strpos(RulesLog::logger()->render(), $text) !== FALSE, "Aborted evaluation.");
}
/**
* Tests preventing recursive rule invocations by creating a rule that reacts
* on node-update and generates a node update that would trigger it itself.
*/
function testRecursionPrevention() {
$rule = $this->createTestRule(FALSE, 'node_update');
$rule->action('rules_node_make_sticky_action');
$rule->integrityCheck()
->save();
// Now trigger the rule.
$node = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
node_save($node);
$text = RulesTestCase::t('Not evaluating reaction rule %label to prevent recursion.', array(
'label' => $rule->name,
));
//debug(RulesLog::logger()->render());
$this->assertTrue(strpos(RulesLog::logger()->render(), $text) !== FALSE, "Recursion prevented.");
//debug(RulesLog::logger()->render());
}
/**
* Ensure the recursion prevention still allows to let the rule trigger again
* during evaluation of the same event set, if the event isn't caused by the
* rule itself - thus we won't run in an infinite loop.
*/
function testRecursionOnDifferentArguments() {
// Create rule1 - which might recurse.
$rule = $this->createTestRule(FALSE, 'node_update');
$rule->action('rules_node_make_sticky_action');
$rule->label = 'rule 1';
$rule->integrityCheck()
->save();
// Create rule2 - which triggers rule1 on another node.
$node2 = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
$rule2 = $this->createTestRule(FALSE, 'node_update');
$rule2->action('rules_action_load_node', array(
'nid' => $node2->nid,
))
->action('rules_node_make_sticky_action', array(
'node:select' => 'node_loaded',
));
$rule2->label = 'rule 2';
$rule2->save();
// Now trigger both rules by generating the event.
$node = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
node_save($node);
//debug(RulesLog::logger()->render());
$text = RulesLog::logger()->render();
$pos = strpos($text, RulesTestCase::t('Evaluating conditions of rule %rule 1', array(
'rule 1',
)));
$pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Evaluating conditions of rule %rule 2', array(
'rule 2',
)), $pos) : FALSE;
$pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Saved %node_loaded of type %node.', array(
'node_loaded',
'node',
)), $pos) : FALSE;
$pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Evaluating conditions of rule %rule 1', array(
'rule 1',
)), $pos) : FALSE;
$pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Not evaluating reaction rule %rule 2 to prevent recursion', array(
'rule 2',
)), $pos) : FALSE;
$this->assertTrue($pos !== FALSE, 'Rule1 was triggered on the event caused by Rule2.');
}
/**
* Tests the provided default rule 'rules_test_default_1'.
*/
function testDefaultRule() {
$rule = rules_config_load('rules_test_default_1');
$this->assertTrue($rule->status & ENTITY_IN_CODE && !($rule->status & ENTITY_IN_DB), 'Default rule can be loaded and has the right status.');
// Enable.
$rule->active = TRUE;
$rule->save();
// Create a node that triggers the rule.
$node = $this->drupalCreateNode(array(
'type' => 'page',
'sticky' => 0,
'status' => 0,
));
// Clear messages.
drupal_get_messages();
// Let event node_update occur.
node_save($node);
$msg = drupal_get_messages();
$this->assertEqual($msg['status'][0], 'A node has been updated.', 'Default rule has been triggered.');
}
/**
* Tests creating and triggering a reaction rule with event settings.
*/
function testEventSettings() {
$rule = rules_reaction_rule();
$rule->event('node_presave', array(
'bundle' => 'article',
))
->condition('data_is_empty', array(
'data:select' => 'node:field-tags',
))
->action('node_publish', array(
'node:select' => 'node',
));
$rule->integrityCheck()
->save();
$node = $this->drupalCreateNode(array(
'type' => 'page',
'status' => 0,
));
$this->assertEqual($node->status, 0, 'Rule has not been triggered.');
$node = $this->drupalCreateNode(array(
'type' => 'article',
'status' => 0,
));
$this->assertEqual($node->status, 1, 'Rule has been triggered.');
RulesLog::logger()->checkLog();
// Make sure an invalid bundle raises integrity problems.
$rule->event('node_presave', array(
'bundle' => 'invalid',
));
try {
$rule->integrityCheck();
$this->fail('Integrity check failed.');
} catch (RulesIntegrityException $e) {
$this->pass('Integrity check failed: ' . $e);
}
}
}
Members
Title Sort descending | Modifiers | Object type | Summary |
---|---|---|---|
RulesTriggerTestCase::createTestRule | protected | function | |
RulesTriggerTestCase::getInfo | static | function | |
RulesTriggerTestCase::setUp | function | ||
RulesTriggerTestCase::testBasicReactionRule | function | Tests creating and triggering a basic reaction rule. | |
RulesTriggerTestCase::testDefaultRule | function | Tests the provided default rule 'rules_test_default_1'. | |
RulesTriggerTestCase::testEventSettings | function | Tests creating and triggering a reaction rule with event settings. | |
RulesTriggerTestCase::testReactiveRuleCreation | function | Tests CRUD for reaction rules - making sure the events are stored properly. | |
RulesTriggerTestCase::testRecursionOnDifferentArguments | function | Ensure the recursion prevention still allows to let the rule trigger again during evaluation of the same event set, if the event isn't caused by the rule itself - thus we won't run in an infinite loop. |
|
RulesTriggerTestCase::testRecursionPrevention | function | Tests preventing recursive rule invocations by creating a rule that reacts on node-update and generates a node update that would trigger it itself. |
|
RulesTriggerTestCase::testVariableHandler | function | Test a rule using a handler to load a variable. | |
RulesTriggerTestCase::testVariableHandlerFailing | function | Test aborting silently when handlers are not able to load. |