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