views_query.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. <?php
  2. /**
  3. * @file
  4. * Abstract class for views testing.
  5. */
  6. /**
  7. *
  8. */
  9. abstract class ViewsTestCase extends DrupalWebTestCase {
  10. /**
  11. *
  12. */
  13. protected $sort_column = NULL;
  14. /**
  15. *
  16. */
  17. protected $sort_order = 1;
  18. /**
  19. * Helper function: verify a result set returned by view.
  20. *
  21. * The comparison is done on the string representation of the columns of the
  22. * column map, taking the order of the rows into account, but not the order
  23. * of the columns.
  24. *
  25. * @param view $view
  26. * An executed View.
  27. * @param array $expected_result
  28. * An expected result set.
  29. * @param array $column_map
  30. * An associative array mapping the columns of the result set from the view
  31. * (as keys) and the expected result set (as values).
  32. */
  33. protected function assertIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Identical result set') {
  34. return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertIdentical');
  35. }
  36. /**
  37. * Helper function: verify a result set returned by view..
  38. *
  39. * Inverse of ViewsTestCase::assertIdenticalResultset().
  40. *
  41. * @param view $view
  42. * An executed View.
  43. * @param array $expected_result
  44. * An expected result set.
  45. * @param array $column_map
  46. * An associative array mapping the columns of the result set from the view
  47. * (as keys) and the expected result set (as values).
  48. */
  49. protected function assertNotIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Identical result set') {
  50. return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertNotIdentical');
  51. }
  52. /**
  53. *
  54. */
  55. protected function assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, $assert_method) {
  56. // Convert $view->result to an array of arrays.
  57. $result = array();
  58. foreach ($view->result as $key => $value) {
  59. $row = array();
  60. foreach ($column_map as $view_column => $expected_column) {
  61. // The comparison will be done on the string representation of the
  62. // value.
  63. $row[$expected_column] = (string) $value->$view_column;
  64. }
  65. $result[$key] = $row;
  66. }
  67. // Remove the columns we don't need from the expected result.
  68. foreach ($expected_result as $key => $value) {
  69. $row = array();
  70. foreach ($column_map as $expected_column) {
  71. // The comparison will be done on the string representation of the
  72. // value.
  73. $row[$expected_column] = (string) (is_object($value) ? $value->$expected_column : $value[$expected_column]);
  74. }
  75. $expected_result[$key] = $row;
  76. }
  77. // Reset the numbering of the arrays.
  78. $result = array_values($result);
  79. $expected_result = array_values($expected_result);
  80. $this->verbose('<pre>Returned data set: ' . print_r($result, TRUE) . "\n\nExpected: " . print_r($expected_result, TRUE));
  81. // Do the actual comparison.
  82. return $this->$assert_method($result, $expected_result, $message);
  83. }
  84. /**
  85. * Order an array of array based on a column.
  86. */
  87. protected function orderResultSet($result_set, $column, $reverse = FALSE) {
  88. $this->sort_column = $column;
  89. $this->sort_order = $reverse ? -1 : 1;
  90. usort($result_set, array($this, 'helperCompareFunction'));
  91. return $result_set;
  92. }
  93. /**
  94. * Helper comparison function for orderResultSet().
  95. */
  96. protected function helperCompareFunction($a, $b) {
  97. $value1 = $a[$this->sort_column];
  98. $value2 = $b[$this->sort_column];
  99. if ($value1 == $value2) {
  100. return 0;
  101. }
  102. return $this->sort_order * (($value1 < $value2) ? -1 : 1);
  103. }
  104. /**
  105. * Check whether a button with a certain id exists and has a certain label.
  106. */
  107. protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') {
  108. return $this->assertFieldById($id, $expected_label, t($message, array('%label' => $expected_label)));
  109. }
  110. /**
  111. * Execute a view with debugging.
  112. *
  113. * @param view $view
  114. * @param array $args
  115. */
  116. protected function executeView($view, $args = array()) {
  117. $view->set_display();
  118. $view->pre_execute($args);
  119. $view->execute();
  120. $this->verbose('<pre>Executed view: ' . ((string) $view->build_info['query']) . '</pre>');
  121. }
  122. /**
  123. * Log in as user 1.
  124. */
  125. protected function loginUser1() {
  126. $password = user_password();
  127. // Reset the user 1 password.
  128. $account = user_load(1);
  129. $edit = array(
  130. 'pass' => $password,
  131. );
  132. $account = user_save($account, $edit);
  133. $account->pass_raw = $password;
  134. // Log in as user 1.
  135. $this->drupalLogin($account);
  136. }
  137. }
  138. /**
  139. *
  140. */
  141. abstract class ViewsSqlTest extends ViewsTestCase {
  142. /**
  143. * {@inheritdoc}
  144. */
  145. protected function setUp() {
  146. parent::setUp('views', 'views_ui');
  147. // Define the schema and views data variable before enabling the test
  148. // module.
  149. variable_set('views_test_schema', $this->schemaDefinition());
  150. variable_set('views_test_views_data', $this->viewsData());
  151. variable_set('views_test_views_plugins', $this->viewsPlugins());
  152. module_enable(array('views_test'));
  153. $this->resetAll();
  154. // Load the test dataset.
  155. $data_set = $this->dataSet();
  156. $query = db_insert('views_test')
  157. ->fields(array_keys($data_set[0]));
  158. foreach ($data_set as $record) {
  159. $query->values($record);
  160. }
  161. $query->execute();
  162. $this->checkPermissions(array(), TRUE);
  163. }
  164. /**
  165. * Create a term.
  166. *
  167. * @param int $vid
  168. * The vocabulary ID that the term is to be added to.
  169. *
  170. * @return object
  171. * A full term object with a random name.
  172. */
  173. protected function drupalCreateTerm($vid) {
  174. $term = new stdClass();
  175. $term->name = $this->randomName();
  176. $term->description = $this->randomName();
  177. $term->vid = $vid;
  178. taxonomy_term_save($term);
  179. return $term;
  180. }
  181. /**
  182. * This function allows to enable views ui from a higher class which can't
  183. * change the setup function anymore.
  184. *
  185. * @todo Convert existing setUp functions.
  186. */
  187. function enableViewsUi() {
  188. module_enable(array('views_ui'));
  189. // @todo Figure out why it's required to clear the cache here.
  190. views_module_include('views_default', TRUE);
  191. views_get_all_views(TRUE);
  192. menu_rebuild();
  193. }
  194. /**
  195. * The schema definition.
  196. */
  197. protected function schemaDefinition() {
  198. $schema['views_test'] = array(
  199. 'description' => 'Basic test table for Views tests.',
  200. 'fields' => array(
  201. 'id' => array(
  202. 'type' => 'serial',
  203. 'unsigned' => TRUE,
  204. 'not null' => TRUE,
  205. ),
  206. 'name' => array(
  207. 'description' => "A person's name",
  208. 'type' => 'varchar',
  209. 'length' => 255,
  210. 'not null' => TRUE,
  211. 'default' => '',
  212. ),
  213. 'age' => array(
  214. 'description' => "The person's age",
  215. 'type' => 'int',
  216. 'unsigned' => TRUE,
  217. 'not null' => TRUE,
  218. 'default' => 0),
  219. 'job' => array(
  220. 'description' => "The person's job",
  221. 'type' => 'varchar',
  222. 'length' => 255,
  223. 'not null' => TRUE,
  224. 'default' => 'Undefined',
  225. ),
  226. 'created' => array(
  227. 'description' => "The creation date of this record",
  228. 'type' => 'int',
  229. 'unsigned' => TRUE,
  230. 'not null' => TRUE,
  231. 'default' => 0,
  232. ),
  233. ),
  234. 'primary key' => array('id'),
  235. 'unique keys' => array(
  236. 'name' => array('name'),
  237. ),
  238. 'indexes' => array(
  239. 'ages' => array('age'),
  240. ),
  241. );
  242. return $schema;
  243. }
  244. /**
  245. * The views data definition.
  246. */
  247. protected function viewsData() {
  248. // Declaration of the base table.
  249. $data['views_test']['table'] = array(
  250. 'group' => t('Views test'),
  251. 'base' => array(
  252. 'field' => 'id',
  253. 'title' => t('Views test'),
  254. 'help' => t('Users who have created accounts on your site.'),
  255. ),
  256. );
  257. // Declaration of fields.
  258. $data['views_test']['id'] = array(
  259. 'title' => t('ID'),
  260. 'help' => t('The test data ID'),
  261. 'field' => array(
  262. 'handler' => 'views_handler_field_numeric',
  263. 'click sortable' => TRUE,
  264. ),
  265. 'argument' => array(
  266. 'handler' => 'views_handler_argument_numeric',
  267. ),
  268. 'filter' => array(
  269. 'handler' => 'views_handler_filter_numeric',
  270. ),
  271. 'sort' => array(
  272. 'handler' => 'views_handler_sort',
  273. ),
  274. );
  275. $data['views_test']['name'] = array(
  276. 'title' => t('Name'),
  277. 'help' => t('The name of the person'),
  278. 'field' => array(
  279. 'handler' => 'views_handler_field',
  280. 'click sortable' => TRUE,
  281. ),
  282. 'argument' => array(
  283. 'handler' => 'views_handler_argument_string',
  284. ),
  285. 'filter' => array(
  286. 'handler' => 'views_handler_filter_string',
  287. ),
  288. 'sort' => array(
  289. 'handler' => 'views_handler_sort',
  290. ),
  291. );
  292. $data['views_test']['age'] = array(
  293. 'title' => t('Age'),
  294. 'help' => t('The age of the person'),
  295. 'field' => array(
  296. 'handler' => 'views_handler_field_numeric',
  297. 'click sortable' => TRUE,
  298. ),
  299. 'argument' => array(
  300. 'handler' => 'views_handler_argument_numeric',
  301. ),
  302. 'filter' => array(
  303. 'handler' => 'views_handler_filter_numeric',
  304. ),
  305. 'sort' => array(
  306. 'handler' => 'views_handler_sort',
  307. ),
  308. );
  309. $data['views_test']['job'] = array(
  310. 'title' => t('Job'),
  311. 'help' => t('The job of the person'),
  312. 'field' => array(
  313. 'handler' => 'views_handler_field',
  314. 'click sortable' => TRUE,
  315. ),
  316. 'argument' => array(
  317. 'handler' => 'views_handler_argument_string',
  318. ),
  319. 'filter' => array(
  320. 'handler' => 'views_handler_filter_string',
  321. ),
  322. 'sort' => array(
  323. 'handler' => 'views_handler_sort',
  324. ),
  325. );
  326. $data['views_test']['created'] = array(
  327. 'title' => t('Created'),
  328. 'help' => t('The creation date of this record'),
  329. 'field' => array(
  330. 'handler' => 'views_handler_field_date',
  331. 'click sortable' => TRUE,
  332. ),
  333. 'argument' => array(
  334. 'handler' => 'views_handler_argument_date',
  335. ),
  336. 'filter' => array(
  337. 'handler' => 'views_handler_filter_date',
  338. ),
  339. 'sort' => array(
  340. 'handler' => 'views_handler_sort_date',
  341. ),
  342. );
  343. return $data;
  344. }
  345. /**
  346. *
  347. */
  348. protected function viewsPlugins() {
  349. return array();
  350. }
  351. /**
  352. * A very simple test dataset.
  353. */
  354. protected function dataSet() {
  355. return array(
  356. array(
  357. 'name' => 'John',
  358. 'age' => 25,
  359. 'job' => 'Singer',
  360. 'created' => gmmktime(0, 0, 0, 1, 1, 2000),
  361. ),
  362. array(
  363. 'name' => 'George',
  364. 'age' => 27,
  365. 'job' => 'Singer',
  366. 'created' => gmmktime(0, 0, 0, 1, 2, 2000),
  367. ),
  368. array(
  369. 'name' => 'Ringo',
  370. 'age' => 28,
  371. 'job' => 'Drummer',
  372. 'created' => gmmktime(6, 30, 30, 1, 1, 2000),
  373. ),
  374. array(
  375. 'name' => 'Paul',
  376. 'age' => 26,
  377. 'job' => 'Songwriter',
  378. 'created' => gmmktime(6, 0, 0, 1, 1, 2000),
  379. ),
  380. array(
  381. 'name' => 'Meredith',
  382. 'age' => 30,
  383. 'job' => 'Speaker',
  384. 'created' => gmmktime(6, 30, 10, 1, 1, 2000),
  385. ),
  386. );
  387. }
  388. /**
  389. * Build and return a basic view of the views_test table.
  390. *
  391. * @return view
  392. */
  393. protected function getBasicView() {
  394. views_include('view');
  395. // Create the basic view.
  396. $view = new view();
  397. $view->name = 'test_view';
  398. $view->add_display('default');
  399. $view->base_table = 'views_test';
  400. // Set up the fields we need.
  401. $display = $view->new_display('default', 'Master', 'default');
  402. $display->override_option('fields', array(
  403. 'id' => array(
  404. 'id' => 'id',
  405. 'table' => 'views_test',
  406. 'field' => 'id',
  407. 'relationship' => 'none',
  408. ),
  409. 'name' => array(
  410. 'id' => 'name',
  411. 'table' => 'views_test',
  412. 'field' => 'name',
  413. 'relationship' => 'none',
  414. ),
  415. 'age' => array(
  416. 'id' => 'age',
  417. 'table' => 'views_test',
  418. 'field' => 'age',
  419. 'relationship' => 'none',
  420. ),
  421. ));
  422. // Set up the sort order.
  423. $display->override_option('sorts', array(
  424. 'id' => array(
  425. 'order' => 'ASC',
  426. 'id' => 'id',
  427. 'table' => 'views_test',
  428. 'field' => 'id',
  429. 'relationship' => 'none',
  430. ),
  431. ));
  432. // Set up the pager.
  433. $display->override_option('pager', array(
  434. 'type' => 'none',
  435. 'options' => array('offset' => 0),
  436. ));
  437. return $view;
  438. }
  439. /**
  440. * Build and return a Page view of the views_test table.
  441. *
  442. * @return view
  443. */
  444. protected function getBasicPageView() {
  445. views_include('view');
  446. $view = $this->getBasicView();
  447. // In order to test exposed filters, we have to disable the exposed forms
  448. // cache.
  449. drupal_static_reset('views_exposed_form_cache');
  450. $display = $view->new_display('page', 'Page', 'page_1');
  451. return $view;
  452. }
  453. }