You are here

class RulesIntegrationTestCase in Rules 8.3

Same name and namespace in other branches
  1. 7.2 tests/rules.test \RulesIntegrationTestCase

Tests provided module integration.

Hierarchy

Expanded class hierarchy of RulesIntegrationTestCase

File

d7-tests/rules_integration_test_case.test, line 17
Rules 7.x tests.

View source
class RulesIntegrationTestCase extends DrupalWebTestCase {
  static function getInfo() {
    return array(
      'name' => 'Rules Core Integration',
      'description' => 'Tests provided integration for drupal core.',
      'group' => 'Rules',
    );
  }
  function setUp() {
    parent::setUp('rules', 'rules_test', 'php', 'path');
    RulesLog::logger()
      ->clear();
    variable_set('rules_debug_log', 1);
  }

  /**
   * Just make sure the access callback run without errors.
   */
  function testAccessCallbacks() {
    $cache = rules_get_cache();
    foreach (array(
      'action',
      'condition',
      'event',
    ) as $type) {
      foreach (rules_fetch_data($type . '_info') as $name => $info) {
        if (isset($info['access callback'])) {
          $info['access callback']($type, $name);
        }
      }
    }
  }

  /**
   * Test data integration.
   */
  function testDataIntegration() {

    // Test data_create action.
    $action = rules_action('data_create', array(
      'type' => 'log_entry',
      'param_type' => 'rules_test',
      'param_message' => 'Rules test log message',
      'param_severity' => WATCHDOG_WARNING,
      'param_request_uri' => 'http://example.com',
      'param_link' => '',
    ));
    $action
      ->access();
    $action
      ->execute();
    $text = RulesLog::logger()
      ->render();
    $pos = strpos($text, RulesTestCase::t('Added the provided variable %data_created of type %log_entry', array(
      'data_created',
      'log_entry',
    )));
    $this
      ->assertTrue($pos !== FALSE, 'Data of type log entry has been created.');

    // Test variable_add action.
    $action = rules_action('variable_add', array(
      'type' => 'text_formatted',
      'value' => array(
        'value' => 'test text',
        'format' => 1,
      ),
    ));
    $action
      ->access();
    $action
      ->execute();
    $text = RulesLog::logger()
      ->render();
    $pos = strpos($text, RulesTestCase::t('Added the provided variable %variable_added of type %text_formatted', array(
      'variable_added',
      'text_formatted',
    )));
    $this
      ->assertTrue($pos !== FALSE, 'Data of type text formatted has been created.');

    // Test using the list actions.
    $rule = rule(array(
      'list' => array(
        'type' => 'list<text>',
        'label' => 'A list of text',
      ),
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'list',
      'item' => 'bar2',
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'list',
      'item' => 'bar',
      'pos' => 'start',
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'list',
      'item' => 'bar',
      'unique' => TRUE,
    ));
    $rule
      ->action('list_remove', array(
      'list:select' => 'list',
      'item' => 'bar2',
    ));
    $list = entity_metadata_wrapper('list', array(
      'foo',
      'foo2',
    ));
    $rule
      ->execute($list);
    RulesLog::logger()
      ->checkLog();
    $this
      ->assertEqual($list
      ->value(), array(
      'bar',
      'foo',
      'foo2',
    ), 'List items removed and added.');
    $this
      ->assertFalse(rules_condition('list_contains')
      ->execute($list, 'foo-bar'), 'Condition "List item contains" evaluates to FALSE');
    $this
      ->assertTrue(rules_condition('list_contains')
      ->execute($list, 'foo'), 'Condition "List item contains" evaluates to TRUE');

    //debug(RulesLog::logger()->render());

    // Test data_is condition with IN operation.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('data_is', array(
      'data:select' => 'node:title',
      'op' => 'IN',
      'value' => array(
        'foo',
        'bar',
      ),
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:title',
      'value' => 'bar',
    ));
    $rule
      ->integrityCheck();
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
    ));
    $rule
      ->execute($node);
    $this
      ->assertEqual($node->title, 'bar', "Data comparison using IN operation evaluates to TRUE.");

    // Test Condition: Data is empty.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('data_is_empty', array(
      'data:select' => 'node:title',
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:title',
      'value' => 'bar',
    ));
    $rule
      ->integrityCheck();

    // Data is empty condition evaluates to TRUE
    // for node with empty title, action sets title to 'bar'.
    $node = $this
      ->drupalCreateNode(array(
      'title' => '',
      'type' => 'article',
    ));
    $rule
      ->execute($node);
    $this
      ->assertEqual($node->title, 'bar', "Data is empty condition evaluates to TRUE for node with empty title, action sets title to 'bar'.");

    // Data is empty condition evaluates to FALSE
    // for node with title 'foo', action is not executed.
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
      'type' => 'article',
    ));
    $rule
      ->execute($node);
    $this
      ->assertEqual($node->title, 'foo', "Data is empty condition evaluates to FALSE for node with title 'foo', action is not executed.");

    // Data is empty condition evaluates to TRUE for the parent of a
    // not existing term in the tags field of the node.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('node_is_of_type', array(
      'type' => array(
        'article',
      ),
    ));
    $rule
      ->condition('data_is_empty', array(
      'data:select' => 'node:field-tags:0:parent',
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:title',
      'value' => 'bar',
    ));
    $rule
      ->integrityCheck();
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
      'type' => 'article',
    ));
    $rule
      ->execute($node);
    $this
      ->assertEqual($node->title, 'bar', "Data is empty condition evaluates to TRUE for not existing data structures");

    // Test Action: Calculate a value.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->action('data_calc', array(
      'input_1:select' => 'node:nid',
      'op' => '*',
      'input_2' => 2,
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:title',
      'value:select' => 'result',
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute($node);
    $this
      ->assertEqual($node->title, $node->nid * 2, "Value has been calculated.");

    // Test moving a date.
    $action_set = rules_action_set(array(
      'date' => array(
        'type' => 'date',
      ),
    ), array(
      'date',
    ));
    $action_set
      ->action('data_calc', array(
      'input_1:select' => 'date',
      'op' => '+',
      'input_2' => 3600,
    ))
      ->action('data_set', array(
      'data:select' => 'date',
      'value:select' => 'result',
    ));
    $action_set
      ->integrityCheck();
    list($result) = $action_set
      ->execute(REQUEST_TIME);
    $this
      ->assertEqual($result, REQUEST_TIME + 3600, 'Used data calculation action to move a date by an hour.');

    // Test data type conversion action.
    $set = rules_action_set(array(
      'result' => array(
        'type' => 'text',
        'parameter' => FALSE,
      ),
    ), array(
      'result',
    ));
    $set
      ->action('data_convert', array(
      'type' => 'text',
      'value:select' => 'site:login-url',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'result',
      'value:select' => 'conversion_result',
    ));
    list($result) = $set
      ->execute();
    $set
      ->integrityCheck();
    $this
      ->assertEqual($result, url('user', array(
      'absolute' => TRUE,
    )), 'Converted URI to text.');
    $set = rules_action_set(array(
      'result' => array(
        'type' => 'integer',
        'parameter' => FALSE,
      ),
      'source' => array(
        'type' => 'text',
      ),
    ), array(
      'result',
    ));
    $set
      ->action('data_convert', array(
      'type' => 'integer',
      'value:select' => 'source',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'result',
      'value:select' => 'conversion_result',
    ));
    list($result) = $set
      ->execute('9.4');
    $this
      ->assertEqual($result, 9, 'Converted decimal to integer using rounding.');
    $set = rules_action_set(array(
      'result' => array(
        'type' => 'integer',
        'parameter' => FALSE,
      ),
      'source' => array(
        'type' => 'text',
      ),
    ), array(
      'result',
    ));
    $set
      ->action('data_convert', array(
      'type' => 'integer',
      'value:select' => 'source',
      'rounding_behavior' => 'down',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'result',
      'value:select' => 'conversion_result',
    ));
    list($result) = $set
      ->execute('9.6');
    $this
      ->assertEqual($result, 9, 'Converted decimal to integer using roundin behavio down.');
    $set = rules_action_set(array(
      'result' => array(
        'type' => 'integer',
        'parameter' => FALSE,
      ),
      'source' => array(
        'type' => 'text',
      ),
    ), array(
      'result',
    ));
    $set
      ->action('data_convert', array(
      'type' => 'integer',
      'value:select' => 'source',
      'rounding_behavior' => 'up',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'result',
      'value:select' => 'conversion_result',
    ));
    list($result) = $set
      ->execute('9.4');
    $this
      ->assertEqual($result, 10, 'Converted decimal to integer using rounding behavior up.');

    // Test text matching condition.
    $result = rules_condition('text_matches')
      ->execute('my-text', 'text', 'contains');
    $result2 = rules_condition('text_matches')
      ->execute('my-text', 'tex2t', 'contains');
    $this
      ->assertTrue($result && !$result2, 'Text matching condition using operation contain evaluated.');
    $result = rules_condition('text_matches')
      ->execute('my-text', 'my', 'starts');
    $result2 = rules_condition('text_matches')
      ->execute('my-text', 'text', 'starts');
    $this
      ->assertTrue($result && !$result2, 'Text matching condition using operation starts evaluated.');
    $result = rules_condition('text_matches')
      ->execute('my-text', 'text', 'ends');
    $result2 = rules_condition('text_matches')
      ->execute('my-text', 'my', 'ends');
    $this
      ->assertTrue($result && !$result2, 'Text matching condition using operation ends evaluated.');
    $result = rules_condition('text_matches')
      ->execute('my-text', 'me?y-texx?t', 'regex');
    $result2 = rules_condition('text_matches')
      ->execute('my-text', 'me+y-texx?t', 'regex');
    $this
      ->assertTrue($result && !$result2, 'Text matching condition using operation regex evaluated.');
  }

  /**
   * Tests entity related integration.
   */
  function testEntityIntegration() {
    global $user;
    $page = $this
      ->drupalCreateNode(array(
      'type' => 'page',
    ));
    $article = $this
      ->drupalCreateNode(array(
      'type' => 'article',
    ));
    $result = rules_condition('entity_field_access')
      ->execute(entity_metadata_wrapper('node', $article), 'field_tags');
    $this
      ->assertTrue($result);

    // Test entiy_is_of_bundle condition.
    $result = rules_condition('entity_is_of_bundle', array(
      'type' => 'node',
      'bundle' => array(
        'article',
      ),
    ))
      ->execute(entity_metadata_wrapper('node', $page));
    $this
      ->assertFalse($result, 'Entity is of bundle condition has not been met.');
    $result = rules_condition('entity_is_of_bundle', array(
      'type' => 'node',
      'bundle' => array(
        'article',
      ),
    ))
      ->execute(entity_metadata_wrapper('node', $article));
    $this
      ->assertTrue($result, 'Entity is of bundle condition has been met.');

    // Also test a full rule so the integrity check must work.
    $term_wrapped = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->save();
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('entity_is_of_bundle', array(
      'entity:select' => 'node',
      'bundle' => array(
        'article',
      ),
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:field_tags',
      'value' => array(
        $term_wrapped
          ->getIdentifier(),
      ),
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute($article);
    $this
      ->assertEqual($term_wrapped
      ->getIdentifier(), $article->field_tags[LANGUAGE_NONE][0]['tid'], 'Entity is of bundle condition has been met.');

    // Test again using an entity variable.
    $article = $this
      ->drupalCreateNode(array(
      'type' => 'article',
    ));
    $rule = rule(array(
      'entity' => array(
        'type' => 'entity',
      ),
    ));
    $rule
      ->condition('entity_is_of_bundle', array(
      'entity:select' => 'entity',
      'type' => 'node',
      'bundle' => array(
        'article',
      ),
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'entity:field_tags',
      'value' => array(
        $term_wrapped
          ->getIdentifier(),
      ),
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute(entity_metadata_wrapper('node', $article));
    $this
      ->assertEqual($term_wrapped
      ->getIdentifier(), $article->field_tags[LANGUAGE_NONE][0]['tid'], 'Entity is of bundle condition has been met.');

    // Test CRUD actions.
    $action = rules_action('entity_create', array(
      'type' => 'node',
      'param_type' => 'page',
      'param_title' => 'foo',
      'param_author' => $GLOBALS['user'],
    ));
    $action
      ->access();
    $action
      ->execute();
    $text = RulesLog::logger()
      ->render();
    $pos = strpos($text, RulesTestCase::t('Added the provided variable %entity_created of type %node', array(
      'entity_created',
      'node',
    )));
    $pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Saved %entity_created of type %node.', array(
      'entity_created',
      'node',
    )), $pos) : FALSE;
    $this
      ->assertTrue($pos !== FALSE, 'Data has been created and saved.');
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'page',
      'sticky' => 0,
      'status' => 0,
    ));
    $rule = rule();
    $rule
      ->action('entity_fetch', array(
      'type' => 'node',
      'id' => $node->nid,
      'entity_fetched:var' => 'node',
    ));
    $rule
      ->action('entity_save', array(
      'data:select' => 'node',
      'immediate' => TRUE,
    ));
    $rule
      ->action('entity_delete', array(
      'data:select' => 'node',
    ));
    $rule
      ->access();
    $rule
      ->integrityCheck()
      ->execute();
    $text = RulesLog::logger()
      ->render();
    $pos = strpos($text, RulesTestCase::t('Evaluating the action %entity_fetch.', array(
      'entity_fetch',
    )));
    $pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Added the provided variable %node of type %node', array(
      'node',
    )), $pos) : FALSE;
    $pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Saved %node of type %node.', array(
      'node',
    )), $pos) : FALSE;
    $pos = $pos !== FALSE ? strpos($text, RulesTestCase::t('Evaluating the action %entity_delete.', array(
      'entity_delete',
    )), $pos) : FALSE;
    $this
      ->assertTrue($pos !== FALSE, 'Data has been fetched, saved and deleted.');

    //debug(RulesLog::logger()->render());
    $node = entity_property_values_create_entity('node', array(
      'type' => 'article',
      'author' => $user,
      'title' => 'foo',
    ))
      ->value();
    $term_wrapped = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->save();

    // Test asserting the field and using it afterwards.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('entity_has_field', array(
      'entity:select' => 'node',
      'field' => 'field_tags',
    ));
    $rule
      ->condition('entity_is_new', array(
      'entity:select' => 'node',
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'node:field-tags',
      'item' => $term_wrapped,
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute($node);
    $tid = $term_wrapped
      ->getIdentifier();
    $this
      ->assertEqual(array_values($node->field_tags[LANGUAGE_NONE]), array(
      0 => array(
        'tid' => $tid,
      ),
    ), 'Entity has field conditions evaluated.');

    // Test loading a non-node entity.
    $action = rules_action('entity_fetch', array(
      'type' => 'taxonomy_term',
      'id' => $tid,
    ));
    list($term) = $action
      ->execute();
    $this
      ->assertEqual($term->tid, $tid, 'Fetched a taxonomy term using "entity_fetch".');

    // Test the entity is of type condition.
    $rule = rule(array(
      'entity' => array(
        'type' => 'entity',
        'label' => 'entity',
      ),
    ));
    $rule
      ->condition('entity_is_of_type', array(
      'type' => 'node',
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'entity:title',
      'value' => 'bar',
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute(entity_metadata_wrapper('node', $node));
    $this
      ->assertEqual(entity_metadata_wrapper('node', $node->nid)->title
      ->value(), 'bar', 'Entity is of type condition correctly asserts the entity type.');

    // Test the entity_query action.
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'page',
      'title' => 'foo2',
    ));
    $rule = rule();
    $rule
      ->action('entity_query', array(
      'type' => 'node',
      'property' => 'title',
      'value' => 'foo2',
    ))
      ->action('data_set', array(
      'data:select' => 'entity_fetched:0:title',
      'value' => 'bar',
    ));
    $rule
      ->access();
    $rule
      ->integrityCheck();
    $rule
      ->execute();
    $node = node_load($node->nid);
    $this
      ->assertEqual('bar', $node->title, 'Fetched a node by title and modified it.');
    RulesLog::logger()
      ->checkLog();
  }

  /**
   * Test integration for the taxonomy module.
   */
  function testTaxonomyIntegration() {
    $term = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->value();
    $term2 = clone $term;
    taxonomy_term_save($term);
    taxonomy_term_save($term2);
    $tags[LANGUAGE_NONE][0]['tid'] = $term->tid;
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
      'type' => 'article',
      'field_tags' => $tags,
    ));

    // Test assigning and remove a term from an article.
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
        'bundle' => 'article',
      ),
    ));
    $term_wrapped = rules_wrap_data($term->tid, array(
      'type' => 'taxonomy_term',
    ));
    $term_wrapped2 = rules_wrap_data($term2->tid, array(
      'type' => 'taxonomy_term',
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'node:field-tags',
      'item' => $term_wrapped2,
    ));
    $rule
      ->action('list_remove', array(
      'list:select' => 'node:field-tags',
      'item' => $term_wrapped,
    ));
    $rule
      ->execute($node);
    RulesLog::logger()
      ->checkLog();
    $this
      ->assertEqual(array_values($node->field_tags[LANGUAGE_NONE]), array(
      0 => array(
        'tid' => $term2->tid,
      ),
    ), 'Term removed and added from a node.');

    // Test using the taxonomy term reference field on a term object.
    $field_name = drupal_strtolower($this
      ->randomName() . '_field_name');
    $field = field_create_field(array(
      'field_name' => $field_name,
      'type' => 'taxonomy_term_reference',
      // Set cardinality to unlimited for tagging.
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'settings' => array(
        'allowed_values' => array(
          array(
            'vocabulary' => 'tags',
            'parent' => 0,
          ),
        ),
      ),
    ));
    $instance = array(
      'field_name' => $field_name,
      'entity_type' => 'taxonomy_term',
      'bundle' => 'tags',
      // Machine name of vocabulary.
      'label' => $this
        ->randomName() . '_label',
      'description' => $this
        ->randomName() . '_description',
      'weight' => mt_rand(0, 127),
      'widget' => array(
        'type' => 'taxonomy_autocomplete',
        'weight' => -4,
      ),
      'display' => array(
        'default' => array(
          'type' => 'taxonomy_term_reference_link',
          'weight' => 10,
        ),
      ),
    );
    field_create_instance($instance);
    $term1 = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->save();
    $term2 = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->save();

    // Test asserting the term reference field and using it afterwards.
    $rule = rule(array(
      'taxonomy_term' => array(
        'type' => 'taxonomy_term',
      ),
    ));
    $rule
      ->condition('entity_has_field', array(
      'entity:select' => 'taxonomy-term',
      'field' => $field_name,
    ));

    // Add $term2 to $term1 using the term reference field.
    $selector = str_replace('_', '-', 'taxonomy_term:' . $field_name);
    $rule
      ->action('list_add', array(
      'list:select' => $selector,
      'item' => $term2,
    ));
    $rule
      ->integrityCheck();
    $rule
      ->execute($term1);
    RulesLog::logger()
      ->checkLog();
    $this
      ->assertEqual($term1->{$field_name}[0]
      ->getIdentifier(), $term2
      ->getIdentifier(), 'Rule appended a term to the term reference field on a term.');

    // Test an action set for merging term parents, which is provided as default
    // config.
    $term = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
      'parent' => array(
        $term1
          ->value(),
      ),
    ))
      ->save();
    $action = rules_action('component_rules_retrieve_term_parents');
    list($parents) = $action
      ->execute(array(
      $term
        ->getIdentifier(),
    ));
    $this
      ->assertTrue($parents[0]->tid == $term1
      ->getIdentifier(), 'Invoked component to retrieve term parents.');
    RulesLog::logger()
      ->checkLog();
  }

  /**
   * Test integration for the node module.
   */
  function testNodeIntegration() {
    $tests = array(
      array(
        'node_unpublish',
        'node_is_published',
        'node_publish',
        'status',
      ),
      array(
        'node_make_unsticky',
        'node_is_sticky',
        'node_make_sticky',
        'sticky',
      ),
      array(
        'node_unpromote',
        'node_is_promoted',
        'node_promote',
        'promote',
      ),
    );
    $node = $this
      ->drupalCreateNode(array(
      'type' => 'page',
      'status' => 1,
      'sticky' => 1,
      'promote' => 1,
    ));
    foreach ($tests as $info) {
      list($action1, $condition, $action2, $property) = $info;
      rules_action($action1)
        ->execute($node);
      $node = node_load($node->nid, NULL, TRUE);
      $this
        ->assertFalse($node->{$property}, 'Action has permanently disabled node ' . $property);
      $return = rules_condition($condition)
        ->execute($node);
      $this
        ->assertFalse($return, 'Condition determines node ' . $property . ' is disabled.');
      rules_action($action2)
        ->execute($node);
      $node = node_load($node->nid, NULL, TRUE);
      $this
        ->assertTrue($node->{$property}, 'Action has permanently enabled node ' . $property);
      $return = rules_condition($condition)
        ->execute($node);
      $this
        ->assertTrue($return, 'Condition determines node ' . $property . ' is enabled.');
    }
    $return = rules_condition('node_is_of_type', array(
      'type' => array(
        'page',
        'article',
      ),
    ))
      ->execute($node);
    $this
      ->assertTrue($return, 'Condition determines node is of type page.');
    $return = rules_condition('node_is_of_type', array(
      'type' => array(
        'article',
      ),
    ))
      ->execute($node);
    $this
      ->assertFalse($return, 'Condition determines node is not of type article.');

    // Test auto saving of a new node after it has been inserted into the DB.
    $rule = rules_reaction_rule();
    $rand = $this
      ->randomName();
    $rule
      ->event('node_insert')
      ->action('data_set', array(
      'data:select' => 'node:title',
      'value' => $rand,
    ));
    $rule
      ->save('test');
    $node = $this
      ->drupalCreateNode();
    $node = node_load($node->nid);
    $this
      ->assertEqual($node->title, $rand, 'Node title is correct.');
    RulesLog::logger()
      ->checkLog();
  }

  /**
   * Test integration for the user module.
   */
  function testUserIntegration() {
    $rid = $this
      ->drupalCreateRole(array(
      'administer nodes',
    ), 'foo');
    $user = $this
      ->drupalCreateUser();

    // Test assigning a role with the list_add action.
    $rule = rule(array(
      'user' => array(
        'type' => 'user',
      ),
    ));
    $rule
      ->action('list_add', array(
      'list:select' => 'user:roles',
      'item' => $rid,
    ));
    $rule
      ->execute($user);
    $this
      ->assertTrue(isset($user->roles[$rid]), 'Role assigned to user.');

    // Test removing a role with the list_remove action.
    $rule = rule(array(
      'user' => array(
        'type' => 'user',
      ),
    ));
    $rule
      ->action('list_remove', array(
      'list:select' => 'user:roles',
      'item' => $rid,
    ));
    $rule
      ->execute($user);
    $this
      ->assertTrue(!isset($user->roles[$rid]), 'Role removed from user.');

    // Test assigning a role with user_add_role action.
    $rule = rule(array(
      'user' => array(
        'type' => 'user',
      ),
    ));
    $rule
      ->action('user_add_role', array(
      'account:select' => 'user',
      'roles' => array(
        $rid,
      ),
    ));
    $rule
      ->execute($user);
    $user = user_load($user->uid, TRUE);
    $result = rules_condition('user_has_role', array(
      'roles' => array(
        $rid,
      ),
    ))
      ->execute($user);
    $this
      ->assertTrue($result, 'Role assigned to user.');

    // Test removing a role with the user_remove_role action.
    $rule = rule(array(
      'user' => array(
        'type' => 'user',
      ),
    ));
    $rule
      ->action('user_remove_role', array(
      'account:select' => 'user',
      'roles' => array(
        $rid,
      ),
    ));
    $rule
      ->execute($user);
    $user = user_load($user->uid, TRUE);
    $result = rules_condition('user_has_role', array(
      'roles' => array(
        $rid,
      ),
    ))
      ->execute($user);
    $this
      ->assertFalse($result, 'Role removed from user.');

    // Test user blocking.
    rules_action('user_block')
      ->execute($user);
    $user = user_load($user->uid, TRUE);
    $this
      ->assertTrue(rules_condition('user_is_blocked')
      ->execute($user), 'User has been blocked.');
    rules_action('user_unblock')
      ->execute($user);
    $user = user_load($user->uid, TRUE);
    $this
      ->assertFalse(rules_condition('user_is_blocked')
      ->execute($user), 'User has been unblocked.');
    RulesLog::logger()
      ->checkLog();
  }

  /**
   * Test integration for the php module.
   */
  function testPHPIntegration() {
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
    ));
    $rule = rule(array(
      'var_name' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->condition('php_eval', array(
      'code' => 'return TRUE;',
    ))
      ->action('php_eval', array(
      'code' => 'drupal_set_message("Executed-" . $var_name->title);',
    ))
      ->action('drupal_message', array(
      'message' => 'Title: <?php echo $var_name->title; ?> Token: [var_name:title]',
    ));
    $rule
      ->execute($node);
    $rule
      ->access();
    RulesLog::logger()
      ->checkLog();
    $msg = drupal_get_messages();
    $this
      ->assertEqual(array_pop($msg['status']), "Title: foo Token: foo", 'PHP input evaluation has been applied.');
    $this
      ->assertEqual(array_pop($msg['status']), "Executed-foo", 'PHP code condition and action have been evaluated.');

    // Test PHP data processor
    $rule = rule(array(
      'var_name' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->action('drupal_message', array(
      'message:select' => 'var_name:title',
      'message:process' => array(
        'php' => array(
          'code' => 'return "Title: $value";',
        ),
      ),
    ));
    $rule
      ->execute($node);
    $rule
      ->access();
    RulesLog::logger()
      ->checkLog();
    $msg = drupal_get_messages();
    $this
      ->assertEqual(array_pop($msg['status']), "Title: foo", 'PHP data processor has been applied.');
  }

  /**
   * Test the "rules_core" integration.
   */
  function testRulesCoreIntegration() {

    // Make sure the date input evaluator evaluates properly using strtotime().
    $node = $this
      ->drupalCreateNode(array(
      'title' => 'foo',
    ));
    $rule = rule(array(
      'node' => array(
        'type' => 'node',
      ),
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'node:created',
      'value' => '+1 day',
    ));
    $rule
      ->execute($node);
    RulesLog::logger()
      ->checkLog();
    $node = node_load($node->nid, NULL, TRUE);
    $now = RulesDateInputEvaluator::gmstrtotime('now');

    // Tolerate a difference of a second.
    $this
      ->assertTrue(abs($node->created - $now - 86400) <= 1, 'Date input has been evaluated.');

    // Test using a numeric offset.
    $rule = rule(array(
      'number' => array(
        'type' => 'decimal',
      ),
    ), array(
      'number',
    ));
    $rule
      ->action('data_set', array(
      'data:select' => 'number',
      'value:select' => 'number',
      'value:process' => array(
        'num_offset' => array(
          'value' => 1,
        ),
      ),
    ));
    $rule
      ->integrityCheck();
    list($result) = $rule
      ->execute(10);
    $this
      ->assertTrue($result == 11, 'Numeric offset has been applied');

    // Test using a date offset.
    $set = rules_action_set(array(
      'date' => array(
        'type' => 'date',
      ),
    ), array(
      'date',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'date',
      'value:select' => 'date',
      'value:process' => array(
        'date_offset' => array(
          'value' => 1000,
        ),
      ),
    ));
    $date = date_create("14 Mar 1984 10:19:23 +01:00")
      ->format('U');
    list($result) = $set
      ->execute($date);
    $this
      ->assertEqual($result, $date + 1000, 'Date offset in seconds has been added.');

    // Test using a negative offset of 2 months.
    $set = rules_action_set(array(
      'date' => array(
        'type' => 'date',
      ),
    ), array(
      'date',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'date',
      'value:select' => 'date',
      'value:process' => array(
        'date_offset' => array(
          'value' => -86400 * 30 * 2,
        ),
      ),
    ));
    $date = date_create("14 Mar 1984 10:19:23 +01:00")
      ->format('U');
    list($result) = $set
      ->execute($date);
    $this
      ->assertEqual($result, date_create("14 Jan 1984 10:19:23 +01:00")
      ->format('U'), 'Date offset of -2 months has been added.');

    // Test using a positive offset of 1 year 6 months and 30 minutes.
    $set = rules_action_set(array(
      'date' => array(
        'type' => 'date',
      ),
    ), array(
      'date',
    ));
    $set
      ->action('data_set', array(
      'data:select' => 'date',
      'value:select' => 'date',
      'value:process' => array(
        'date_offset' => array(
          'value' => 86400 * 30 * 18 + 30 * 60,
        ),
      ),
    ));
    $date = date_create("14 Mar 1984 10:19:23 +01:00")
      ->format('U');
    list($result) = $set
      ->execute($date);
    $this
      ->assertEqual($result, date_create("14 Sep 1985 10:49:23 +01:00")
      ->format('U'), 'Date offset of 1 year 6 months and 30 minutes has been added.');
    RulesLog::logger()
      ->checkLog();
  }

  /**
   * Test site/system integration.
   */
  function testSystemIntegration() {

    // Test using the 'site' variable.
    $condition = rules_condition('data_is', array(
      'data:select' => 'site:current-user:name',
      'value' => $GLOBALS['user']->name,
    ));
    $this
      ->assertTrue($condition
      ->execute(), 'Retrieved the current user\'s name.');

    // Another test using a token replacement.
    $condition = rules_condition('data_is', array(
      'data:select' => 'site:current-user:name',
      'value' => '[site:current-user:name]',
    ));
    $this
      ->assertTrue($condition
      ->execute(), 'Replaced the token for the current user\'s name.');

    // Test breadcrumbs and drupal set message.
    $rule = rules_reaction_rule();
    $rule
      ->event('init')
      ->action('breadcrumb_set', array(
      'titles' => array(
        'foo',
      ),
      'paths' => array(
        'bar',
      ),
    ))
      ->action('drupal_message', array(
      'message' => 'A message.',
    ));
    $rule
      ->save('test');
    $this
      ->drupalGet('node');
    $this
      ->assertLink('foo', 0, 'Breadcrumb has been set.');
    $this
      ->assertText('A message.', 'Drupal message has been shown.');

    // Test the page redirect.
    $node = $this
      ->drupalCreateNode();
    $rule = rules_reaction_rule();
    $rule
      ->event('node_view')
      ->action('redirect', array(
      'url' => 'user',
    ));
    $rule
      ->save('test2');
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertEqual($this
      ->getUrl(), url('user', array(
      'absolute' => TRUE,
    )), 'Redirect has been issued.');

    // Also test using a url including a fragment.
    $actions = $rule
      ->actions();
    $actions[0]->settings['url'] = 'user#fragment';
    $rule
      ->save();
    $this
      ->drupalGet('node/' . $node->nid);
    $this
      ->assertEqual($this
      ->getUrl(), url('user', array(
      'absolute' => TRUE,
      'fragment' => 'fragment',
    )), 'Redirect has been issued.');

    // Test sending mail.
    $settings = array(
      'to' => 'mail@example.com',
      'subject' => 'subject',
      'message' => 'hello.',
    );
    rules_action('mail', $settings)
      ->execute();
    $this
      ->assertMail('to', 'mail@example.com', 'Mail has been sent.');
    $this
      ->assertMail('from', variable_get('site_mail', ini_get('sendmail_from')), 'Default from address has been used');
    rules_action('mail', $settings + array(
      'from' => 'sender@example.com',
    ))
      ->execute();
    $this
      ->assertMail('from', 'sender@example.com', 'Specified from address has been used');

    // Test sending mail to all users of a role. First make sure there is a
    // custom role and a user for it.
    $user = $this
      ->drupalCreateUser(array(
      'administer nodes',
    ));
    $roles = $user->roles;

    // Remove the authenticate role so we only use the new role created by
    // drupalCreateUser().
    unset($roles[DRUPAL_AUTHENTICATED_RID]);
    rules_action('mail_to_users_of_role', $settings + array(
      'roles' => array_keys($roles),
    ))
      ->execute();
    $this
      ->assertMail('to', $user->mail, 'Mail to users of a role has been sent.');

    // Test reacting on new log entries and make sure the log entry is usable.
    $rule = rules_reaction_rule();
    $rule
      ->event('watchdog');
    $rule
      ->action('drupal_message', array(
      'message:select' => 'log_entry:message',
    ));
    $rule
      ->integrityCheck()
      ->save('test_watchdog');
    watchdog('php', 'test %message', array(
      '%message' => 'message',
    ));
    $msg = drupal_get_messages();
    $this
      ->assertEqual(array_pop($msg['status']), t('test %message', array(
      '%message' => 'message',
    )), 'Watchdog event occurred and log entry properties can be used.');
  }

  /**
   * Tests the path module integration.
   */
  function testPathIntegration() {
    rules_action('path_alias')
      ->execute('foo', 'bar');
    $path = path_load('foo');
    $this
      ->assertTrue($path['alias'] == 'bar', 'URL alias has been created.');
    $alias_exists = rules_condition('path_alias_exists', array(
      'alias' => 'bar',
    ))
      ->execute();
    $this
      ->assertTrue($alias_exists, 'Created URL alias exists.');
    $has_alias = rules_condition('path_has_alias', array(
      'source' => 'foo',
    ))
      ->execute();
    $this
      ->assertTrue($has_alias, 'System path has an alias.');

    // Test node alias action.
    $node = $this
      ->drupalCreateNode();
    rules_action('node_path_alias')
      ->execute($node, 'test');
    $path = path_load("node/{$node->nid}");
    $this
      ->assertTrue($path['alias'] == 'test', 'Node URL alias has been created.');

    // Test term alias action.
    $term = entity_property_values_create_entity('taxonomy_term', array(
      'name' => $this
        ->randomName(),
      'vocabulary' => 1,
    ))
      ->value();
    rules_action('taxonomy_term_path_alias')
      ->execute($term, 'term-test');
    $path = path_load("taxonomy/term/{$term->tid}");
    $this
      ->assertTrue($path['alias'] == 'term-test', 'Term URL alias has been created.');
    RulesLog::logger()
      ->checkLog();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RulesIntegrationTestCase::getInfo static function
RulesIntegrationTestCase::setUp function
RulesIntegrationTestCase::testAccessCallbacks function Just make sure the access callback run without errors.
RulesIntegrationTestCase::testDataIntegration function Test data integration.
RulesIntegrationTestCase::testEntityIntegration function Tests entity related integration.
RulesIntegrationTestCase::testNodeIntegration function Test integration for the node module.
RulesIntegrationTestCase::testPathIntegration function Tests the path module integration.
RulesIntegrationTestCase::testPHPIntegration function Test integration for the php module.
RulesIntegrationTestCase::testRulesCoreIntegration function Test the "rules_core" integration.
RulesIntegrationTestCase::testSystemIntegration function Test site/system integration.
RulesIntegrationTestCase::testTaxonomyIntegration function Test integration for the taxonomy module.
RulesIntegrationTestCase::testUserIntegration function Test integration for the user module.