'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'] = '[title]'; $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' => 'Node 1'), array('title' => 'Node 2'), array('title' => 'Node 3'), ); $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.'); } }