You are here

views_rules.test in Views Rules 7

Simpletest implementations.

File

tests/views_rules.test
View source
<?php

/**
 * @file
 * Simpletest implementations.
 */

/**
 * Base test for Views Rules.
 */
abstract class ViewsRulesBaseTestCase extends DrupalWebTestCase {

  /**
   * Creates site objects.
   */
  protected function createSiteData() {
    $data = array();

    // Create sample items.
    $vocabulary = taxonomy_vocabulary_machine_name_load('tags');
    $data['term'] = (object) array(
      'name' => 'Term 1',
      'vid' => $vocabulary->vid,
      'vocabulary_machine_name' => 'tags',
    );
    taxonomy_term_save($data['term']);
    $nodeBase = array(
      'type' => 'article',
      'language' => LANGUAGE_NONE,
      'field_tags' => array(
        LANGUAGE_NONE => array(
          array(
            'tid' => $data['term']->tid,
          ),
        ),
      ),
    );
    $data['node1'] = $this
      ->drupalCreateNode(array(
      'title' => 'Node 1',
    ) + $nodeBase);
    $data['node2'] = $this
      ->drupalCreateNode(array(
      'title' => 'Node 2',
    ) + $nodeBase);
    $data['node3'] = $this
      ->drupalCreateNode(array(
      'title' => 'Node 3',
    ) + $nodeBase);
    return $data;
  }

  /**
   * Retrieves a file in the test directory.
   */
  protected function getFileContents($fileName) {
    $filePath = drupal_get_path('module', 'views_rules_test') . '/' . $fileName;
    return file_get_contents($filePath);
  }

}

/**
 * Framework function tests.
 */
class ViewsRulesFrameworkTestCase extends ViewsRulesBaseTestCase {

  /**
   * Declares test.
   */
  public static function getInfo() {
    return array(
      'name' => 'Framework tests',
      'description' => 'Tests basic module functionality.',
      'group' => 'Views Rules',
    );
  }
  protected function setUp() {
    parent::setUp('views_rules_test');
  }

  /**
   * Tests data type listing.
   */
  public function testDataTypes() {
    $entityInfo = entity_get_info();

    // Check only primitives are returned.
    $items = views_rules_data_types();
    $this
      ->assertIdentical(array(), array_intersect_key($items, $entityInfo), 'Default data types do not include entity types.');
    $this
      ->assertIdentical(array(), array_filter(array_keys($items), array(
      __CLASS__,
      'filterListDataTypes',
    )), 'Default data types do not include lists.');

    // Check list types are returned.
    $items = views_rules_data_types(array(
      'list' => TRUE,
    ));
    $this
      ->assertNotIdentical(array(), array_filter(array_keys($items), array(
      __CLASS__,
      'filterListDataTypes',
    )), 'List types are correctly enumerated.');
    $this
      ->assertIdentical($items, array_diff_key($items, $entityInfo), 'List types do not include entity types.');

    // Check entity types are returned.
    $items = views_rules_data_types(array(
      'entity' => TRUE,
    ));
    $this
      ->assertIdentical(array(), array_diff_key($entityInfo, $items), 'Entity types are correctly enumerated.');
    $this
      ->assertIdentical(array(), array_filter(array_keys($items), array(
      __CLASS__,
      'filterListDataTypes',
    )), 'Entity data types do not include lists.');
  }

  /**
   * Filters list data types.
   */
  public static function filterListDataTypes($type) {
    return (bool) preg_match('/^list($|<)/', $type);
  }

  /**
   * Tests listing rule iterator view displays.
   */
  public function testListIterators() {
    $views_rules_test_id = 'views_rules_test:views_rules_1';
    $iterators = views_rules_list_iterators(FALSE);
    $this
      ->assertTrue(array_key_exists($views_rules_test_id, $iterators), 'Views iterators are corrected listed.');
  }

  /**
   * Tests retrieving a view by view and display names joined by a colon.
   */
  public function testGetView() {
    $displayId = 'views_rules_1';
    $view = views_rules_get_view('views_rules_test:' . $displayId);
    $this
      ->assertTrue(is_object($view) && $view instanceof view, 'Iterator view can be retrieved.');
    $this
      ->assertEqual($displayId, $view->current_display, 'Iterator display is active in retrieved view.');
    $this
      ->assertTrue($view->display_handler instanceof views_rules_iterator, 'Iterator object is ready.');
  }

}

/**
 * Views display tests.
 */
class ViewsRulesViewsDisplayTestCase extends ViewsRulesBaseTestCase {

  /**
   * Declares test.
   */
  public static function getInfo() {
    return array(
      'name' => 'Views display tests',
      'description' => 'Tests Views display plugin implementation.',
      'group' => 'Views Rules',
    );
  }
  protected function setUp() {
    parent::setUp('views_rules_test', 'views_ui');
    $user = $this
      ->drupalCreateUser(array(
      'administer views',
    ));
    $this
      ->drupalLogin($user);
  }

  /**
   * Tests iterator evaluation.
   */
  public function testExecuteIterator() {
    $iterable = new ViewsRulesTestIterable();

    /** @var $iterator views_rules_plugin_display_rules */
    $iterator = views_rules_get_view('views_rules_test:views_rules_1')->display_handler;

    // Create sample items.
    $data = $this
      ->createSiteData();

    // Disable nid and test executing iterator.
    $option = $iterator
      ->get_option('rules_variables');
    $option['nid']['enabled'] = 0;
    $iterator
      ->set_option('rules_variables', $option);
    $iterator
      ->execute_iterator(array(
      $data['term']->tid,
    ), $iterable);
    $expectedData = array(
      array(
        'title' => 'Node 1',
      ),
      array(
        'title' => 'Node 2',
      ),
      array(
        'title' => 'Node 3',
      ),
    );
    $this
      ->assertIdentical($expectedData, $iterable->rows, 'Iterator display correctly evaluates.');

    // Check execution for rendered result.
    $iterator = views_rules_get_view('views_rules_test:views_rules_1')->display_handler;
    $option = $iterator
      ->get_option('fields');
    $option['title']['alter']['alter_text'] = 1;
    $option['title']['alter']['text'] = '<em>[title]</em>';
    $option['title']['link_to_node'] = 0;
    $iterator
      ->set_option('fields', $option);
    $option = $iterator
      ->get_option('rules_variables');
    $option['nid']['enabled'] = 0;
    $option['title']['rendered'] = 1;
    $iterator
      ->set_option('rules_variables', $option);
    $iterator
      ->execute_iterator(array(
      $data['term']->tid,
    ), $iterable
      ->reset());
    $expectedData = array(
      array(
        'title' => '<em>Node 1</em>',
      ),
      array(
        'title' => '<em>Node 2</em>',
      ),
      array(
        'title' => '<em>Node 3</em>',
      ),
    );
    $this
      ->assertIdentical($expectedData, $iterable->rows, 'Iterator display correctly evaluates rendered result.');

    // Check execution for non-field row styles.
    $iterator = views_rules_get_view('views_rules_non_field_test:views_rules_1')->display_handler;
    $iterator
      ->execute_iterator(array(
      $data['term']->tid,
    ), $iterable
      ->reset());
    $expectedData = array(
      array(
        'node' => $data['node1']->nid,
      ),
      array(
        'node' => $data['node2']->nid,
      ),
      array(
        'node' => $data['node3']->nid,
      ),
    );
    $this
      ->assertIdentical($expectedData, $iterable->rows, 'Iterator display correctly evaluates for non-field row style.');
  }

}

/**
 * Rules plugin tests.
 */
class ViewsRulesViewLoopTestCase extends ViewsRulesBaseTestCase {

  /**
   * Declares test.
   */
  public static function getInfo() {
    return array(
      'name' => 'Rules view loop tests',
      'description' => 'Tests view loop integration with Rules.',
      'group' => 'Views Rules',
    );
  }
  protected function setUp() {
    parent::setUp('views_rules_test', 'rules_admin', 'views_ui');
    $user = $this
      ->drupalCreateUser(array(
      'administer rules',
      'administer views',
    ));
    $this
      ->drupalLogin($user);
  }

  /**
   * Tests creation of a view loop.
   */
  public function testViewLoopUI() {

    // Check redirection.
    rules_action_set(array(
      'term' => array(
        'type' => 'taxonomy_term',
        'label' => 'Term',
      ),
    ))
      ->save('test');
    $this
      ->drupalGet('admin/config/workflow/rules/components/manage/test/add/1/view loop');
    $this
      ->assertUrl('admin/config/workflow/rules/components/manage/test/add-view-loop/1', array(), 'Form redirects when adding a view loop.');

    // Create view loop.
    $this
      ->drupalPost(NULL, array(
      'views_rules_display' => 'views_rules_non_field_test:views_rules_1',
    ), t('Continue'));
    $this
      ->drupalPost(NULL, array(), t('Switch to data selection'));
    $this
      ->drupalPost(NULL, array(
      'parameter[tid][settings][tid:select]' => 'term:tid',
    ), t('Save'));
    $this
      ->assertUrl('admin/config/workflow/rules/components/manage/test', array(), 'View loop creation form is saved.');
    $this
      ->assertLinkByHref('admin/structure/views/view/views_rules_non_field_test/edit/views_rules_1', 0, 'View loop can be added via UI.');
  }

  /**
   * Tests evaluation of a view loop.
   */
  public function testEvaluate() {
    $data = $this
      ->createSiteData();
    $expectedData = array(
      $data['node1']->title,
      $data['node2']->title,
      $data['node3']->title,
    );

    // Test view loop with fields.
    $comp = $this
      ->createTestComponent();
    $result = $comp
      ->execute($data['term']);
    $this
      ->assertIdentical($expectedData, reset($result), 'View loop evaluates correctly.');

    // Test view loop without fields.
    $comp = $this
      ->createTestNonFieldComponent();
    $result = $comp
      ->execute($data['term']);
    $this
      ->assertIdentical($expectedData, reset($result), 'Non-field view loop evaluates correctly.');

    // Test evaluating view loop after data has changed.
    $newNode = (array) $data['node1'];
    $newNode = array_intersect_key($newNode, array_flip(array(
      'title',
      'type',
      'field_tags',
    )));
    $this
      ->drupalCreateNode($newNode);
    $result = $comp
      ->execute($data['term']);
    $this
      ->assertNotIdentical($expectedData, reset($result), 'View loop result data is not prematurely cached.');
  }

  /**
   * Tests exporting a view loop.
   */
  public function testExport() {
    $comp = $this
      ->createTestComponent();
    $comp->name = 'view_loop_test';
    $export = $this
      ->getFileContents('view_loop_test.export.txt');
    $this
      ->assertEqual($export, $comp
      ->export(), 'View loop exports correctly.');
    $this
      ->assertTrue(in_array('views_rules', $comp
      ->dependencies()), 'View loop depends on Views Rules.');
  }

  /**
   * Tests importing a view loop.
   */
  public function testImport() {
    $export = $this
      ->getFileContents('view_loop_test.export.txt');
    $comp = entity_import('rules_config', $export);
    $data = $this
      ->createSiteData();
    $expectedData = array(
      $data['node1']->title,
      $data['node2']->title,
      $data['node3']->title,
    );
    $result = $comp
      ->execute($data['term']);
    $this
      ->assertIdentical($expectedData, reset($result), 'Imported view loop evaluates correctly.');
  }

  /**
   * Tests importing a view loop for an invalid display.
   */
  public function testImportInvalidDisplay() {
    $export = $this
      ->getFileContents('view_loop_test_invalid_display.export.txt');
    $message = 'Importing view loop for missing display triggers integrity error.';
    try {

      /** @var $rules_config RulesPlugin */
      $rules_config = entity_import('rules_config', $export);
      $rules_config
        ->integrityCheck();
      $this
        ->fail($message);
    } catch (RulesIntegrityException $e) {
      $this
        ->pass($message);
    }
  }

  /**
   * Creates an action set to test a view loop.
   */
  protected function createTestComponent() {
    $variables = array(
      'term' => array(
        'type' => 'taxonomy_term',
        'label' => 'Term',
      ),
      'list' => array(
        'type' => 'list',
        'label' => 'List',
        'parameter' => FALSE,
      ),
    );
    $provides = array(
      'list',
    );
    $loop = views_rules_loop('views_rules_test', 'views_rules_1', array(
      'tid:select' => 'term:tid',
      'type' => 'article',
      'nid:var' => 'nid',
      'nid:label' => 'Node ID',
      'title:var' => 'title',
      'title:label' => 'Title',
    ));
    return rules_action_set($variables, $provides)
      ->action($loop
      ->action('list_add', array(
      'list:select' => 'list',
      'item:select' => 'title',
    )));
  }

  /**
   * Creates an action set to test a view loop for a non-field view.
   */
  protected function createTestNonFieldComponent() {
    $variables = array(
      'term' => array(
        'type' => 'taxonomy_term',
        'label' => 'Term',
      ),
      'list' => array(
        'type' => 'list',
        'label' => 'List',
        'parameter' => FALSE,
      ),
    );
    $provides = array(
      'list',
    );
    $loop = views_rules_loop('views_rules_non_field_test', 'views_rules_1', array(
      'tid:select' => 'term:tid',
      'node:var' => 'node',
      'node:label' => 'Node',
    ));
    return rules_action_set($variables, $provides)
      ->action($loop
      ->action('list_add', array(
      'list:select' => 'list',
      'item:select' => 'node:title',
    )));
  }

}

/**
 * Rules plugin tests.
 */
class ViewsRulesCollectActionTestCase extends ViewsRulesBaseTestCase {

  /**
   * Declares test.
   */
  public static function getInfo() {
    return array(
      'name' => 'Rules collect action tests',
      'description' => 'Tests view loop integration with Rules.',
      'group' => 'Views Rules',
    );
  }
  protected function setUp() {
    parent::setUp('views_rules_test');
  }

  /**
   * Tests data collector.
   */
  public function testCollector() {
    $data = $this
      ->createSiteData();

    /** @var $iterator views_rules_plugin_display_rules */
    $iterator = views_rules_get_view('views_rules_test:views_rules_1')->display_handler;
    $collector = new ViewsRulesResultCollector(array_keys($iterator
      ->get_rules_variable_info()));
    $iterator
      ->execute_iterator(array(
      $data['term']->tid,
    ), $collector);
    $expectedData = array();
    foreach (array(
      'nid',
      'title',
    ) as $field) {
      foreach (array(
        'node1',
        'node2',
        'node3',
      ) as $dataKey) {
        $expectedData[$field][] = $data[$dataKey]->{$field};
      }
    }
    $this
      ->assertIdentical($expectedData, $collector
      ->getData(), 'Collector correctly returns executed view data.');
  }

  /**
   * Tests evaluating the action.
   */
  public function testEvaluate() {
    $data = $this
      ->createSiteData();
    $variables = array(
      'term' => array(
        'type' => 'taxonomy_term',
        'label' => 'Term',
      ),
      'list1' => array(
        'type' => 'list',
        'label' => 'List 1',
        'parameter' => FALSE,
      ),
      'list2' => array(
        'type' => 'list',
        'label' => 'List 2',
        'parameter' => FALSE,
      ),
    );
    $provides = array(
      'list1',
      'list2',
    );
    $comp = rules_action_set($variables, $provides)
      ->action('views_rules_collect_rows', array(
      'views_rules_display' => 'views_rules_test:views_rules_1',
      'tid:select' => 'term:tid',
      'type' => 'article',
      'nid:var' => 'list_nid',
      'nid:label' => 'List of node IDs',
      'title:var' => 'list_title',
      'title:label' => 'List of node titles',
    ))
      ->action('data_set', array(
      'data:select' => 'list1',
      'value:select' => 'list_nid',
    ))
      ->action('data_set', array(
      'data:select' => 'list2',
      'value:select' => 'list_title',
    ));

    // Test evaluation.
    $expectedList1 = array(
      $data['node1']->nid,
      $data['node2']->nid,
      $data['node3']->nid,
    );
    $expectedList2 = array(
      $data['node1']->title,
      $data['node2']->title,
      $data['node3']->title,
    );
    $return = $comp
      ->execute($data['term']);
    $this
      ->assertIdentical($expectedList1, reset($return), 'Collect action correctly returns a list of data.');
    $this
      ->assertIdentical($expectedList2, next($return), 'Collect action correctly returns all lists of data.');
  }

}

/**
 * Test suite for updates.
 */
class ViewsRulesUpdateTestCase extends ViewsRulesBaseTestCase {

  /**
   * Declares test.
   */
  public static function getInfo() {
    return array(
      'name' => 'Update tests',
      'description' => 'Tests module updates.',
      'group' => 'Views Rules',
    );
  }
  protected function setUp() {
    parent::setUp('views_rules_test');
    module_load_all_includes('install');
  }

  /**
   * Tests views_rules_update_clean_collect_action_variable_names().
   */
  public function testCleanCollectActionVariableNames() {
    $action = rules_action('views_rules_collect_rows', array(
      'views_rules_display' => 'views_rules_test:views_rules_1',
      'tid:select' => 'term:tid',
      'type' => 'article',
      'nid:var' => 'list_nid',
      'nid:label' => 'List of node IDs',
      'title:var' => 'list_title',
      'title:label' => 'List of node titles',
    ));
    $comp = rules_action_set(array(
      'term' => array(
        'type' => 'taxonomy_term',
        'label' => 'Term',
      ),
    ))
      ->action($action);
    views_rules_update_clean_collect_action_variable_names($comp);
    $expectedSettings = array(
      'views_rules_display' => 'views_rules_test:views_rules_1',
      'tid:select' => 'term:tid',
      'type' => 'article',
      'nid:var' => 'list_nid',
      'nid:label' => 'List of node IDs',
      'title:var' => 'list_title',
      'title:label' => 'List of node titles',
    );
    $updatedSettings = array_intersect_key($action->settings, array_flip(array_filter(array_keys($action->settings), 'element_child')));
    $this
      ->assertIdentical($expectedSettings, $updatedSettings, 'Prefixed collect action variable names are cleaned.');
  }

}

Classes

Namesort descending Description
ViewsRulesBaseTestCase Base test for Views Rules.
ViewsRulesCollectActionTestCase Rules plugin tests.
ViewsRulesFrameworkTestCase Framework function tests.
ViewsRulesUpdateTestCase Test suite for updates.
ViewsRulesViewLoopTestCase Rules plugin tests.
ViewsRulesViewsDisplayTestCase Views display tests.