views_groupby.test 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <?php
  2. /**
  3. * @file
  4. * Tests aggregate functionality of Views.
  5. */
  6. /**
  7. * Tests aggregate functionality of views, for example count.
  8. */
  9. class ViewsQueryGroupByTest extends ViewsSqlTest {
  10. public static function getInfo() {
  11. return array(
  12. 'name' => 'Groupby',
  13. 'description' => 'Tests aggregate functionality of views, for example count.',
  14. 'group' => 'Views',
  15. );
  16. }
  17. /**
  18. * Tests aggregate count feature.
  19. */
  20. public function testAggregateCount() {
  21. // Create 2 nodes of type1 and 3 nodes of type2
  22. $type1 = $this->drupalCreateContentType();
  23. $type2 = $this->drupalCreateContentType();
  24. $node_1 = array(
  25. 'type' => $type1->type,
  26. );
  27. $this->drupalCreateNode($node_1);
  28. $this->drupalCreateNode($node_1);
  29. $this->drupalCreateNode($node_1);
  30. $this->drupalCreateNode($node_1);
  31. $node_2 = array(
  32. 'type' => $type2->type,
  33. );
  34. $this->drupalCreateNode($node_2);
  35. $this->drupalCreateNode($node_2);
  36. $this->drupalCreateNode($node_2);
  37. $view = $this->viewsAggregateCountView();
  38. $output = $view->execute_display();
  39. $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.');
  40. $types = array();
  41. foreach ($view->result as $item) {
  42. // num_records is a alias for nid.
  43. $types[$item->node_type] = $item->num_records;
  44. }
  45. $this->assertEqual($types[$type1->type], 4);
  46. $this->assertEqual($types[$type2->type], 3);
  47. }
  48. //public function testAggregateSum() {
  49. //}
  50. public function viewsAggregateCountView() {
  51. $view = new view;
  52. $view->name = 'aggregate_count';
  53. $view->description = '';
  54. $view->tag = '';
  55. $view->base_table = 'node';
  56. $view->human_name = '';
  57. $view->core = 7;
  58. $view->api_version = '3.0';
  59. $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
  60. /* Display: Master */
  61. $handler = $view->new_display('default', 'Master', 'default');
  62. $handler->display->display_options['group_by'] = TRUE;
  63. $handler->display->display_options['access']['type'] = 'none';
  64. $handler->display->display_options['cache']['type'] = 'none';
  65. $handler->display->display_options['query']['type'] = 'views_query';
  66. $handler->display->display_options['query']['options']['query_comment'] = FALSE;
  67. $handler->display->display_options['exposed_form']['type'] = 'basic';
  68. $handler->display->display_options['pager']['type'] = 'some';
  69. $handler->display->display_options['style_plugin'] = 'default';
  70. $handler->display->display_options['row_plugin'] = 'fields';
  71. /* Field: Content: Title */
  72. $handler->display->display_options['fields']['nid']['id'] = 'nid';
  73. $handler->display->display_options['fields']['nid']['table'] = 'node';
  74. $handler->display->display_options['fields']['nid']['field'] = 'title';
  75. $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0;
  76. $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0;
  77. $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1;
  78. $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1;
  79. $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0;
  80. $handler->display->display_options['fields']['nid']['alter']['trim'] = 0;
  81. $handler->display->display_options['fields']['nid']['alter']['html'] = 0;
  82. $handler->display->display_options['fields']['nid']['hide_empty'] = 0;
  83. $handler->display->display_options['fields']['nid']['empty_zero'] = 0;
  84. $handler->display->display_options['fields']['nid']['link_to_node'] = 0;
  85. /* Contextual filter: Content: Type */
  86. $handler->display->display_options['arguments']['type']['id'] = 'type';
  87. $handler->display->display_options['arguments']['type']['table'] = 'node';
  88. $handler->display->display_options['arguments']['type']['field'] = 'type';
  89. $handler->display->display_options['arguments']['type']['default_action'] = 'summary';
  90. $handler->display->display_options['arguments']['type']['default_argument_type'] = 'fixed';
  91. $handler->display->display_options['arguments']['type']['summary']['format'] = 'default_summary';
  92. return $view;
  93. }
  94. /**
  95. * @param string|null $group_by
  96. * (optional) Which group_by function should be used, for example sum or
  97. * count. If omitted, the aggregation is tested with no group function.
  98. * @param array|null $values
  99. * (optional) Expected values.
  100. */
  101. function GroupByTestHelper($group_by = NULL, $values = NULL) {
  102. // Create 4 nodes of type1 and 3 nodes of type2
  103. $type1 = $this->drupalCreateContentType();
  104. $type2 = $this->drupalCreateContentType();
  105. $node_1 = array(
  106. 'type' => $type1->type,
  107. );
  108. // Nids from 1 to 4.
  109. $this->drupalCreateNode($node_1);
  110. $this->drupalCreateNode($node_1);
  111. $this->drupalCreateNode($node_1);
  112. $this->drupalCreateNode($node_1);
  113. $node_2 = array(
  114. 'type' => $type2->type,
  115. );
  116. // Nids from 5 to 7.
  117. $this->drupalCreateNode($node_2);
  118. $this->drupalCreateNode($node_2);
  119. $this->drupalCreateNode($node_2);
  120. $view = $this->viewsGroupByViewHelper($group_by);
  121. $output = $view->execute_display();
  122. $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.');
  123. $results = array();
  124. // There's no need for a function in order to have aggregation.
  125. if (empty($group_by)) {
  126. $types = array($type1->type, $type2->type);
  127. $results = array_map(function ($item) { return $item->node_type; }, $view->result);
  128. sort($types);
  129. sort($results);
  130. $this->assertIdentical($results, $types);
  131. // Exit here with no aggregation function.
  132. return;
  133. }
  134. // Group by nodetype to identify the right count.
  135. foreach ($view->result as $item) {
  136. $results[$item->node_type] = $item->nid;
  137. }
  138. $this->assertEqual($results[$type1->type], $values[0]);
  139. $this->assertEqual($results[$type2->type], $values[1]);
  140. }
  141. function viewsGroupByViewHelper($group_by = NULL) {
  142. $view = new view;
  143. $view->name = 'group_by_count';
  144. $view->description = '';
  145. $view->tag = '';
  146. $view->view_php = '';
  147. $view->base_table = 'node';
  148. $view->is_cacheable = FALSE;
  149. $view->api_version = 2;
  150. $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
  151. /* Display: Master */
  152. $handler = $view->new_display('default', 'Master', 'default');
  153. $handler->display->display_options['group_by'] = TRUE;
  154. $handler->display->display_options['access']['type'] = 'none';
  155. $handler->display->display_options['cache']['type'] = 'none';
  156. $handler->display->display_options['exposed_form']['type'] = 'basic';
  157. $handler->display->display_options['pager']['type'] = 'some';
  158. $handler->display->display_options['style_plugin'] = 'default';
  159. $handler->display->display_options['row_plugin'] = 'fields';
  160. // The test view has 2 fields ('nid' and 'type'). Don't add 'nid' when
  161. // having no aggregation function. We just want to aggregate on node type.
  162. if (!empty($group_by)) {
  163. /* Field: Content: Nid */
  164. $handler->display->display_options['fields']['nid']['id'] = 'nid';
  165. $handler->display->display_options['fields']['nid']['table'] = 'node';
  166. $handler->display->display_options['fields']['nid']['field'] = 'nid';
  167. $handler->display->display_options['fields']['nid']['group_type'] = $group_by;
  168. $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0;
  169. $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0;
  170. $handler->display->display_options['fields']['nid']['alter']['trim'] = 0;
  171. $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1;
  172. $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1;
  173. $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0;
  174. $handler->display->display_options['fields']['nid']['alter']['html'] = 0;
  175. $handler->display->display_options['fields']['nid']['hide_empty'] = 0;
  176. $handler->display->display_options['fields']['nid']['empty_zero'] = 0;
  177. $handler->display->display_options['fields']['nid']['link_to_node'] = 0;
  178. }
  179. /* Field: Content: Type */
  180. $handler->display->display_options['fields']['type']['id'] = 'type';
  181. $handler->display->display_options['fields']['type']['table'] = 'node';
  182. $handler->display->display_options['fields']['type']['field'] = 'type';
  183. $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0;
  184. $handler->display->display_options['fields']['type']['alter']['make_link'] = 0;
  185. $handler->display->display_options['fields']['type']['alter']['trim'] = 0;
  186. $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1;
  187. $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1;
  188. $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0;
  189. $handler->display->display_options['fields']['type']['alter']['html'] = 0;
  190. $handler->display->display_options['fields']['type']['hide_empty'] = 0;
  191. $handler->display->display_options['fields']['type']['empty_zero'] = 0;
  192. $handler->display->display_options['fields']['type']['link_to_node'] = 0;
  193. return $view;
  194. }
  195. public function testGroupByCount() {
  196. $this->GroupByTestHelper('count', array(4, 3));
  197. }
  198. function testGroupBySum() {
  199. $this->GroupByTestHelper('sum', array(10, 18));
  200. }
  201. function testGroupByAverage() {
  202. $this->GroupByTestHelper('avg', array(2.5, 6));
  203. }
  204. function testGroupByMin() {
  205. $this->GroupByTestHelper('min', array(1, 5));
  206. }
  207. function testGroupByMax() {
  208. $this->GroupByTestHelper('max', array(4, 7));
  209. }
  210. function testGroupByNone() {
  211. $this->GroupByTestHelper();
  212. }
  213. public function testGroupByCountOnlyFilters() {
  214. // Check if GROUP BY and HAVING are included when a view
  215. // Doesn't display SUM, COUNT, MAX... functions in SELECT statment
  216. $type1 = $this->drupalCreateContentType();
  217. $node_1 = array(
  218. 'type' => $type1->type,
  219. );
  220. for ($x = 0; $x < 10; $x++) {
  221. $this->drupalCreateNode($node_1);
  222. }
  223. $view = $this->viewsGroupByCountViewOnlyFilters();
  224. $output = $view->execute_display();
  225. $this->assertTrue(strpos($view->build_info['query'], 'GROUP BY'), t('Make sure that GROUP BY is in the query'));
  226. $this->assertTrue(strpos($view->build_info['query'], 'HAVING'), t('Make sure that HAVING is in the query'));
  227. }
  228. function viewsGroupByCountViewOnlyFilters() {
  229. $view = new view;
  230. $view->name = 'group_by_in_filters';
  231. $view->description = '';
  232. $view->tag = '';
  233. $view->view_php = '';
  234. $view->base_table = 'node';
  235. $view->is_cacheable = FALSE;
  236. $view->api_version = 2;
  237. $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
  238. /* Display: Master */
  239. $handler = $view->new_display('default', 'Master', 'default');
  240. $handler->display->display_options['group_by'] = TRUE;
  241. $handler->display->display_options['access']['type'] = 'none';
  242. $handler->display->display_options['cache']['type'] = 'none';
  243. $handler->display->display_options['exposed_form']['type'] = 'basic';
  244. $handler->display->display_options['pager']['type'] = 'some';
  245. $handler->display->display_options['style_plugin'] = 'default';
  246. $handler->display->display_options['row_plugin'] = 'fields';
  247. /* Field: Nodo: Tipo */
  248. $handler->display->display_options['fields']['type']['id'] = 'type';
  249. $handler->display->display_options['fields']['type']['table'] = 'node';
  250. $handler->display->display_options['fields']['type']['field'] = 'type';
  251. $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0;
  252. $handler->display->display_options['fields']['type']['alter']['make_link'] = 0;
  253. $handler->display->display_options['fields']['type']['alter']['trim'] = 0;
  254. $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1;
  255. $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1;
  256. $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0;
  257. $handler->display->display_options['fields']['type']['alter']['html'] = 0;
  258. $handler->display->display_options['fields']['type']['hide_empty'] = 0;
  259. $handler->display->display_options['fields']['type']['empty_zero'] = 0;
  260. $handler->display->display_options['fields']['type']['link_to_node'] = 0;
  261. /* Filtrar: Nodo: Nid */
  262. $handler->display->display_options['filters']['nid']['id'] = 'nid';
  263. $handler->display->display_options['filters']['nid']['table'] = 'node';
  264. $handler->display->display_options['filters']['nid']['field'] = 'nid';
  265. $handler->display->display_options['filters']['nid']['group_type'] = 'count';
  266. $handler->display->display_options['filters']['nid']['operator'] = '>';
  267. $handler->display->display_options['filters']['nid']['value']['value'] = '3';
  268. return $view;
  269. }
  270. }
  271. /**
  272. * Tests UI of aggregate functionality..
  273. */
  274. class viewsUiGroupbyTestCase extends DrupalWebTestCase {
  275. function setUp() {
  276. // Enable views_ui.
  277. parent::setUp('views_ui', 'views_test');
  278. // Create and log in a user with administer views permission.
  279. $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view revisions'));
  280. $this->drupalLogin($views_admin);
  281. }
  282. public static function getInfo() {
  283. return array(
  284. 'name' => 'Groupby UI',
  285. 'description' => 'Tests UI of aggregate functionality.',
  286. 'group' => 'Views UI',
  287. );
  288. }
  289. /**
  290. * Tests whether basic saving works.
  291. *
  292. * @todo: this should check the change of the settings as well.
  293. */
  294. function testGroupBySave() {
  295. $this->drupalGet('admin/structure/views/view/test_views_groupby_save/edit');
  296. $edit = array(
  297. 'group_by' => TRUE,
  298. );
  299. $this->drupalPost('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by', $edit, t('Apply'));
  300. $this->drupalGet('admin/structure/views/view/test_views_groupby_save/edit');
  301. $this->drupalPost('admin/structure/views/view/test_views_groupby_save/edit', array(), t('Save'));
  302. $this->drupalGet('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by');
  303. }
  304. }