'Groupby', 'description' => 'Tests aggregate functionality of views, for example count.', 'group' => 'Views', ); } // tests ambiguous group by column error (postgresql) public function testAggregateAmbiguity() { // Create 4 nodes of type1 $type1 = $this->drupalCreateContentType(); $node_1 = array( 'type' => $type1->type, ); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $view = $this->viewsAggregateAmbiguityView(); $output = $view->execute_display(); $this->assertEqual(count($view->result), 1, 'Make sure there are no ambiguity problems with the group by operation.'); } public function viewsAggregateAmbiguityView() { $view = new view(); $view->name = 'aggregate_ambiguity'; $view->description = ''; $view->tag = 'default'; $view->base_table = 'node'; $view->human_name = ''; $view->core = 7; $view->api_version = '3.0'; $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ /* Display: Master */ $handler = $view->new_display('default', 'Master', 'default'); $handler->display->display_options['use_more_always'] = FALSE; $handler->display->display_options['group_by'] = TRUE; $handler->display->display_options['access']['type'] = 'none'; $handler->display->display_options['cache']['type'] = 'none'; $handler->display->display_options['query']['type'] = 'views_query'; $handler->display->display_options['exposed_form']['type'] = 'basic'; $handler->display->display_options['pager']['type'] = 'full'; $handler->display->display_options['style_plugin'] = 'default'; $handler->display->display_options['row_plugin'] = 'fields'; /* Field: COUNT(Content revision: Nid) */ $handler->display->display_options['fields']['nid']['id'] = 'nid'; $handler->display->display_options['fields']['nid']['table'] = 'node_revision'; $handler->display->display_options['fields']['nid']['field'] = 'nid'; $handler->display->display_options['fields']['nid']['group_type'] = 'count'; $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; $handler->display->display_options['fields']['nid']['alter']['html'] = 0; $handler->display->display_options['fields']['nid']['hide_empty'] = 0; $handler->display->display_options['fields']['nid']['empty_zero'] = 0; /* Field: Content: Nid */ $handler->display->display_options['fields']['nid_1']['id'] = 'nid_1'; $handler->display->display_options['fields']['nid_1']['table'] = 'node'; $handler->display->display_options['fields']['nid_1']['field'] = 'nid'; $handler->display->display_options['fields']['nid_1']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['nid_1']['alter']['make_link'] = 0; $handler->display->display_options['fields']['nid_1']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['nid_1']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['nid_1']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['nid_1']['alter']['trim'] = 0; $handler->display->display_options['fields']['nid_1']['alter']['html'] = 0; $handler->display->display_options['fields']['nid_1']['hide_empty'] = 0; $handler->display->display_options['fields']['nid_1']['empty_zero'] = 0; /* Contextual filter: Content: Type */ $handler->display->display_options['arguments']['type']['id'] = 'type'; $handler->display->display_options['arguments']['type']['table'] = 'node'; $handler->display->display_options['arguments']['type']['field'] = 'type'; $handler->display->display_options['arguments']['type']['default_action'] = 'summary'; $handler->display->display_options['arguments']['type']['default_argument_type'] = 'fixed'; $handler->display->display_options['arguments']['type']['summary']['format'] = 'default_summary'; return $view; } /** * Tests aggregate count feature. */ public function testAggregateCount() { // Create 2 nodes of type1 and 3 nodes of type2 $type1 = $this->drupalCreateContentType(); $type2 = $this->drupalCreateContentType(); $node_1 = array( 'type' => $type1->type, ); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $node_2 = array( 'type' => $type2->type, ); $this->drupalCreateNode($node_2); $this->drupalCreateNode($node_2); $this->drupalCreateNode($node_2); $view = $this->viewsAggregateCountView(); $output = $view->execute_display(); $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); $types = array(); foreach ($view->result as $item) { // 'num_records' is a alias for nid. $types[$item->node_type] = $item->num_records; } $this->assertEqual($types[$type1->type], 4); $this->assertEqual($types[$type2->type], 3); } /** * */ // public function testAggregateSum() { // } /** * */ public function viewsAggregateCountView() { $view = new view; $view->name = 'aggregate_count'; $view->description = ''; $view->tag = ''; $view->base_table = 'node'; $view->human_name = ''; $view->core = 7; $view->api_version = '3.0'; $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ /* Display: Master */ $handler = $view->new_display('default', 'Master', 'default'); $handler->display->display_options['group_by'] = TRUE; $handler->display->display_options['access']['type'] = 'none'; $handler->display->display_options['cache']['type'] = 'none'; $handler->display->display_options['query']['type'] = 'views_query'; $handler->display->display_options['query']['options']['query_comment'] = FALSE; $handler->display->display_options['exposed_form']['type'] = 'basic'; $handler->display->display_options['pager']['type'] = 'some'; $handler->display->display_options['style_plugin'] = 'default'; $handler->display->display_options['row_plugin'] = 'fields'; /* Field: Content: Title */ $handler->display->display_options['fields']['nid']['id'] = 'nid'; $handler->display->display_options['fields']['nid']['table'] = 'node'; $handler->display->display_options['fields']['nid']['field'] = 'title'; $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; $handler->display->display_options['fields']['nid']['alter']['html'] = 0; $handler->display->display_options['fields']['nid']['hide_empty'] = 0; $handler->display->display_options['fields']['nid']['empty_zero'] = 0; $handler->display->display_options['fields']['nid']['link_to_node'] = 0; /* Contextual filter: Content: Type */ $handler->display->display_options['arguments']['type']['id'] = 'type'; $handler->display->display_options['arguments']['type']['table'] = 'node'; $handler->display->display_options['arguments']['type']['field'] = 'type'; $handler->display->display_options['arguments']['type']['default_action'] = 'summary'; $handler->display->display_options['arguments']['type']['default_argument_type'] = 'fixed'; $handler->display->display_options['arguments']['type']['summary']['format'] = 'default_summary'; return $view; } /** * @param string|null $group_by * (optional) Which group_by function should be used, for example sum or * count. If omitted, the aggregation is tested with no group function. * @param array|null $values * (optional) Expected values. */ function GroupByTestHelper($group_by = NULL, $values = NULL) { // Create 4 nodes of type1 and 3 nodes of type2 $type1 = $this->drupalCreateContentType(); $type2 = $this->drupalCreateContentType(); $node_1 = array( 'type' => $type1->type, ); // Nids from 1 to 4. $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $this->drupalCreateNode($node_1); $node_2 = array( 'type' => $type2->type, ); // Nids from 5 to 7. $this->drupalCreateNode($node_2); $this->drupalCreateNode($node_2); $this->drupalCreateNode($node_2); $view = $this->viewsGroupByViewHelper($group_by); $output = $view->execute_display(); $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); $results = array(); // There's no need for a function in order to have aggregation. if (empty($group_by)) { $types = array($type1->type, $type2->type); $results = array_map(function ($item) { return $item->node_type; }, $view->result); sort($types); sort($results); $this->assertIdentical($results, $types); // Exit here with no aggregation function. return; } // Group by nodetype to identify the right count. foreach ($view->result as $item) { $results[$item->node_type] = $item->nid; } $this->assertEqual($results[$type1->type], $values[0]); $this->assertEqual($results[$type2->type], $values[1]); } /** * */ function viewsGroupByViewHelper($group_by = NULL) { $view = new view; $view->name = 'group_by_count'; $view->description = ''; $view->tag = ''; $view->view_php = ''; $view->base_table = 'node'; $view->is_cacheable = FALSE; $view->api_version = 2; $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ /* Display: Master */ $handler = $view->new_display('default', 'Master', 'default'); $handler->display->display_options['group_by'] = TRUE; $handler->display->display_options['access']['type'] = 'none'; $handler->display->display_options['cache']['type'] = 'none'; $handler->display->display_options['exposed_form']['type'] = 'basic'; $handler->display->display_options['pager']['type'] = 'some'; $handler->display->display_options['style_plugin'] = 'default'; $handler->display->display_options['row_plugin'] = 'fields'; // The test view has 2 fields ('nid' and 'type'). Don't add 'nid' when // having no aggregation function. We just want to aggregate on node type. if (!empty($group_by)) { /* Field: Content: Nid */ $handler->display->display_options['fields']['nid']['id'] = 'nid'; $handler->display->display_options['fields']['nid']['table'] = 'node'; $handler->display->display_options['fields']['nid']['field'] = 'nid'; $handler->display->display_options['fields']['nid']['group_type'] = $group_by; $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['nid']['alter']['html'] = 0; $handler->display->display_options['fields']['nid']['hide_empty'] = 0; $handler->display->display_options['fields']['nid']['empty_zero'] = 0; $handler->display->display_options['fields']['nid']['link_to_node'] = 0; } /* Field: Content: Type */ $handler->display->display_options['fields']['type']['id'] = 'type'; $handler->display->display_options['fields']['type']['table'] = 'node'; $handler->display->display_options['fields']['type']['field'] = 'type'; $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['type']['alter']['make_link'] = 0; $handler->display->display_options['fields']['type']['alter']['trim'] = 0; $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['type']['alter']['html'] = 0; $handler->display->display_options['fields']['type']['hide_empty'] = 0; $handler->display->display_options['fields']['type']['empty_zero'] = 0; $handler->display->display_options['fields']['type']['link_to_node'] = 0; return $view; } /** * */ public function testGroupByCount() { $this->GroupByTestHelper('count', array(4, 3)); } /** * */ public function testGroupBySum() { $this->GroupByTestHelper('sum', array(10, 18)); } /** * */ public function testGroupByAverage() { $this->GroupByTestHelper('avg', array(2.5, 6)); } /** * */ public function testGroupByMin() { $this->GroupByTestHelper('min', array(1, 5)); } /** * {@inheritdoc} */ public function testGroupByMax() { $this->GroupByTestHelper('max', array(4, 7)); } /** * */ public function testGroupByNone() { $this->GroupByTestHelper(); } /** * */ public function testGroupByCountOnlyFilters() { // Check if GROUP BY and HAVING are included when a view // Doesn't display SUM, COUNT, MAX... functions in SELECT statment $type1 = $this->drupalCreateContentType(); $node_1 = array( 'type' => $type1->type, ); for ($x = 0; $x < 10; $x++) { $this->drupalCreateNode($node_1); } $view = $this->viewsGroupByCountViewOnlyFilters(); $output = $view->execute_display(); $this->assertTrue(strpos($view->build_info['query'], 'GROUP BY'), t('Make sure that GROUP BY is in the query')); $this->assertTrue(strpos($view->build_info['query'], 'HAVING'), t('Make sure that HAVING is in the query')); } /** * */ function viewsGroupByCountViewOnlyFilters() { $view = new view; $view->name = 'group_by_in_filters'; $view->description = ''; $view->tag = ''; $view->view_php = ''; $view->base_table = 'node'; $view->is_cacheable = FALSE; $view->api_version = 2; $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ /* Display: Master */ $handler = $view->new_display('default', 'Master', 'default'); $handler->display->display_options['group_by'] = TRUE; $handler->display->display_options['access']['type'] = 'none'; $handler->display->display_options['cache']['type'] = 'none'; $handler->display->display_options['exposed_form']['type'] = 'basic'; $handler->display->display_options['pager']['type'] = 'some'; $handler->display->display_options['style_plugin'] = 'default'; $handler->display->display_options['row_plugin'] = 'fields'; /* Field: Nodo: Tipo */ $handler->display->display_options['fields']['type']['id'] = 'type'; $handler->display->display_options['fields']['type']['table'] = 'node'; $handler->display->display_options['fields']['type']['field'] = 'type'; $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0; $handler->display->display_options['fields']['type']['alter']['make_link'] = 0; $handler->display->display_options['fields']['type']['alter']['trim'] = 0; $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1; $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0; $handler->display->display_options['fields']['type']['alter']['html'] = 0; $handler->display->display_options['fields']['type']['hide_empty'] = 0; $handler->display->display_options['fields']['type']['empty_zero'] = 0; $handler->display->display_options['fields']['type']['link_to_node'] = 0; /* Filtrar: Nodo: Nid */ $handler->display->display_options['filters']['nid']['id'] = 'nid'; $handler->display->display_options['filters']['nid']['table'] = 'node'; $handler->display->display_options['filters']['nid']['field'] = 'nid'; $handler->display->display_options['filters']['nid']['group_type'] = 'count'; $handler->display->display_options['filters']['nid']['operator'] = '>'; $handler->display->display_options['filters']['nid']['value']['value'] = '3'; return $view; } } /** * Tests UI of aggregate functionality. */ class ViewsUiGroupbyTestCase extends DrupalWebTestCase { /** * {@inheritdoc} */ function setUp() { // Enable views_ui. parent::setUp('views_ui', 'views_test'); // Create and log in a user with administer views permission. $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view revisions')); $this->drupalLogin($views_admin); } /** * Test meta data. */ public static function getInfo() { return array( 'name' => 'Groupby UI', 'description' => 'Tests UI of aggregate functionality.', 'group' => 'Views UI', ); } /** * Tests whether basic saving works. * * @todo: this should check the change of the settings as well. */ function testGroupBySave() { $this->drupalGet('admin/structure/views/view/test_views_groupby_save/edit'); $edit = array( 'group_by' => TRUE, ); $this->drupalPost('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by', $edit, t('Apply')); $this->drupalGet('admin/structure/views/view/test_views_groupby_save/edit'); $this->drupalPost('admin/structure/views/view/test_views_groupby_save/edit', array(), t('Save')); $this->drupalGet('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by'); } }