commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / views / tests / views_ui.test
1 <?php
2
3 /**
4 * @file
5 * Tests Views UI Wizard.
6 */
7
8 /**
9 * Views UI wizard tests.
10 */
11 class ViewsUIWizardHelper extends DrupalWebTestCase {
12 function setUp() {
13 // Enable views_ui.
14 parent::setUp('views_ui');
15
16 // Create and log in a user with administer views permission.
17 $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view revisions'));
18 $this->drupalLogin($views_admin);
19 }
20 }
21
22 /**
23 * Tests creating views with the wizard and viewing them on the listing page.
24 */
25 class ViewsUIWizardBasicTestCase extends ViewsUIWizardHelper {
26 public static function getInfo() {
27 return array(
28 'name' => 'Views UI wizard basic functionality',
29 'description' => 'Test creating basic views with the wizard and viewing them on the listing page.',
30 'group' => 'Views UI',
31 );
32 }
33
34 function testViewsWizardAndListing() {
35 // Check if we can access the main views admin page.
36 $this->drupalGet('admin/structure/views');
37 $this->assertText(t('Add new view'));
38
39 // Create a simple and not at all useful view.
40 $view1 = array();
41 $view1['human_name'] = $this->randomName(16);
42 $view1['name'] = strtolower($this->randomName(16));
43 $view1['description'] = $this->randomName(16);
44 $view1['page[create]'] = FALSE;
45 $this->drupalPost('admin/structure/views/add', $view1, t('Save & exit'));
46 $this->assertText(t('Your view was saved. You may edit it from the list below.'));
47 $this->assertText($view1['human_name']);
48 $this->assertText($view1['description']);
49 foreach(array('delete', 'clone', 'edit') as $operation) {
50 $this->assertLinkByHref(url('admin/structure/views/view/' . $view1['name'] . '/' . $operation));
51 }
52
53 // This view should not have a block.
54 $this->drupalGet('admin/structure/block');
55 $this->assertNoText('View: ' . $view1['human_name']);
56
57 // Create two nodes.
58 $node1 = $this->drupalCreateNode(array('type' => 'page'));
59 $node2 = $this->drupalCreateNode(array('type' => 'article'));
60
61 // Now create a page with simple node listing and an attached feed.
62 $view2 = array();
63 $view2['human_name'] = $this->randomName(16);
64 $view2['name'] = strtolower($this->randomName(16));
65 $view2['description'] = $this->randomName(16);
66 $view2['page[create]'] = 1;
67 $view2['page[title]'] = $this->randomName(16);
68 $view2['page[path]'] = $this->randomName(16);
69 $view2['page[feed]'] = 1;
70 $view2['page[feed_properties][path]'] = $this->randomName(16);
71 $this->drupalPost('admin/structure/views/add', $view2, t('Save & exit'));
72
73 // Since the view has a page, we expect to be automatically redirected to
74 // it.
75 $this->assertUrl($view2['page[path]']);
76 $this->assertText($view2['page[title]']);
77 $this->assertText($node1->title);
78 $this->assertText($node2->title);
79
80 // Check if we have the feed.
81 $this->assertLinkByHref(url($view2['page[feed_properties][path]']));
82 $this->drupalGet($view2['page[feed_properties][path]']);
83 $this->assertRaw('<rss version="2.0"');
84 // The feed should have the same title and nodes as the page.
85 $this->assertText($view2['page[title]']);
86 $this->assertRaw(url('node/' . $node1->nid, array('absolute' => TRUE)));
87 $this->assertText($node1->title);
88 $this->assertRaw(url('node/' . $node2->nid, array('absolute' => TRUE)));
89 $this->assertText($node2->title);
90
91 // Go back to the views page and check if this view is there.
92 $this->drupalGet('admin/structure/views');
93 $this->assertText($view2['human_name']);
94 $this->assertText($view2['description']);
95 $this->assertLinkByHref(url($view2['page[path]']));
96
97 // This view should not have a block.
98 $this->drupalGet('admin/structure/block');
99 $this->assertNoText('View: ' . $view2['human_name']);
100
101 // Create a view with a page and a block, and filter the listing.
102 $view3 = array();
103 $view3['human_name'] = $this->randomName(16);
104 $view3['name'] = strtolower($this->randomName(16));
105 $view3['description'] = $this->randomName(16);
106 $view3['show[wizard_key]'] = 'node';
107 $view3['show[type]'] = 'page';
108 $view3['page[create]'] = 1;
109 $view3['page[title]'] = $this->randomName(16);
110 $view3['page[path]'] = $this->randomName(16);
111 $view3['block[create]'] = 1;
112 $view3['block[title]'] = $this->randomName(16);
113 $this->drupalPost('admin/structure/views/add', $view3, t('Save & exit'));
114
115 // Make sure the view only displays the node we expect.
116 $this->assertUrl($view3['page[path]']);
117 $this->assertText($view3['page[title]']);
118 $this->assertText($node1->title);
119 $this->assertNoText($node2->title);
120
121 // Go back to the views page and check if this view is there.
122 $this->drupalGet('admin/structure/views');
123 $this->assertText($view3['human_name']);
124 $this->assertText($view3['description']);
125 $this->assertLinkByHref(url($view3['page[path]']));
126
127 // Put the block into the first sidebar region.
128 $this->drupalGet('admin/structure/block');
129 $this->assertText('View: ' . $view3['human_name']);
130 $edit = array();
131 $edit["blocks[views_{$view3['name']}-block][region]"] = 'sidebar_first';
132 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
133
134 // Visit a random page (not the one that displays the view itself) and look
135 // for the expected node title in the block.
136 $this->drupalGet('user');
137 $this->assertText($node1->title);
138 $this->assertNoText($node2->title);
139
140 // Check if the export screen works.
141 $this->drupalGet('admin/structure/views/view/' . $view3['name'] . '/export');
142 $this->assertRaw('$view = new view();');
143 $this->assertRaw($view3['human_name']);
144 $this->assertRaw($view3['description']);
145
146 // Make sure the listing page doesn't show disabled default views.
147 $this->assertNoText('tracker', t('Default tracker view does not show on the listing page.'));
148 }
149 }
150
151 /**
152 * Tests enabling, disabling, and reverting default views via the listing page.
153 */
154 class ViewsUIWizardDefaultViewsTestCase extends ViewsUIWizardHelper {
155 public static function getInfo() {
156 return array(
157 'name' => 'Views UI default views functionality',
158 'description' => 'Test enabling, disabling, and reverting default views via the listing page.',
159 'group' => 'Views UI',
160 );
161 }
162
163 /**
164 * Tests default views.
165 */
166 function testDefaultViews() {
167 // Make sure the front page view starts off as disabled (does not appear on
168 // the listing page).
169 $edit_href = 'admin/structure/views/view/frontpage/edit';
170 $this->drupalGet('admin/structure/views');
171 // TODO: Disabled default views do now appear on the front page. Test this
172 // behavior with templates instead.
173 // $this->assertNoLinkByHref($edit_href);
174
175 // Enable the front page view, and make sure it is now visible on the main
176 // listing page.
177 $this->drupalGet('admin/structure/views/templates');
178 $this->clickViewsOperationLink(t('Enable'), '/frontpage/');
179 $this->assertUrl('admin/structure/views');
180 $this->assertLinkByHref($edit_href);
181
182 // It should not be possible to revert the view yet.
183 $this->assertNoLink(t('Revert'));
184 $revert_href = 'admin/structure/views/view/frontpage/revert';
185 $this->assertNoLinkByHref($revert_href);
186
187 // Edit the view and change the title. Make sure that the new title is
188 // displayed.
189 $new_title = $this->randomName(16);
190 $edit = array('title' => $new_title);
191 $this->drupalPost('admin/structure/views/nojs/display/frontpage/page/title', $edit, t('Apply'));
192 $this->drupalPost('admin/structure/views/view/frontpage/edit/page', array(), t('Save'));
193 $this->drupalGet('frontpage');
194 $this->assertText($new_title);
195
196 // It should now be possible to revert the view. Do that, and make sure the
197 // view title we added above no longer is displayed.
198 $this->drupalGet('admin/structure/views');
199 $this->assertLink(t('Revert'));
200 $this->assertLinkByHref($revert_href);
201 $this->drupalPost($revert_href, array(), t('Revert'));
202 $this->drupalGet('frontpage');
203 $this->assertNoText($new_title);
204
205 // Now disable the view, and make sure it stops appearing on the main view
206 // listing page but instead goes back to displaying on the disabled views
207 // listing page.
208 // TODO: Test this behavior with templates instead.
209 $this->drupalGet('admin/structure/views');
210 $this->clickViewsOperationLink(t('Disable'), '/frontpage/');
211 // $this->assertUrl('admin/structure/views');
212 // $this->assertNoLinkByHref($edit_href);
213 // The easiest way to verify it appears on the disabled views listing page
214 // is to try to click the "enable" link from there again.
215 $this->drupalGet('admin/structure/views/templates');
216 $this->clickViewsOperationLink(t('Enable'), '/frontpage/');
217 $this->assertUrl('admin/structure/views');
218 $this->assertLinkByHref($edit_href);
219 }
220
221 /**
222 * Click a link to perform an operation on a view.
223 *
224 * In general, we expect lots of links titled "enable" or "disable" on the
225 * various views listing pages, and they might have tokens in them. So we
226 * need special code to find the correct one to click.
227 *
228 * @param $label
229 * Text between the anchor tags of the desired link.
230 * @param $unique_href_part
231 * A unique string that is expected to occur within the href of the desired
232 * link. For example, if the link URL is expected to look like
233 * "admin/structure/views/view/frontpage/...", then "/frontpage/" could be
234 * passed as the expected unique string.
235 *
236 * @return
237 * The page content that results from clicking on the link, or FALSE on
238 * failure. Failure also results in a failed assertion.
239 */
240 function clickViewsOperationLink($label, $unique_href_part) {
241 $links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label));
242 foreach ($links as $link_index => $link) {
243 $position = strpos($link['href'], $unique_href_part);
244 if ($position !== FALSE) {
245 $index = $link_index;
246 break;
247 }
248 }
249 $this->assertTrue(isset($index), t('Link to "@label" containing @part found.', array('@label' => $label, '@part' => $unique_href_part)));
250 if (isset($index)) {
251 return $this->clickLink($label, $index);
252 }
253 else {
254 return FALSE;
255 }
256 }
257 }
258
259 /**
260 * Tests the ability of the views wizard to create views filtered by taxonomy.
261 */
262 class ViewsUIWizardTaggedWithTestCase extends ViewsUIWizardHelper {
263 protected $node_type_with_tags;
264 protected $node_type_without_tags;
265 protected $tag_vocabulary;
266 protected $tag_field;
267 protected $tag_instance;
268
269 public static function getInfo() {
270 return array(
271 'name' => 'Views UI wizard taxonomy functionality',
272 'description' => 'Test the ability of the views wizard to create views filtered by taxonomy.',
273 'group' => 'Views UI',
274 );
275 }
276
277 function setUp() {
278 parent::setUp();
279
280 // Create two content types. One will have an autocomplete tagging field,
281 // and one won't.
282 $this->node_type_with_tags = $this->drupalCreateContentType();
283 $this->node_type_without_tags = $this->drupalCreateContentType();
284
285 // Create the vocabulary for the tag field.
286 $this->tag_vocabulary = new stdClass();
287 $this->tag_vocabulary->name = 'Views testing tags';
288 $this->tag_vocabulary->machine_name = 'views_testing_tags';
289 taxonomy_vocabulary_save($this->tag_vocabulary);
290
291 // Create the tag field itself.
292 $this->tag_field = array(
293 'field_name' => 'field_views_testing_tags',
294 'type' => 'taxonomy_term_reference',
295 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
296 'settings' => array(
297 'allowed_values' => array(
298 array(
299 'vocabulary' => $this->tag_vocabulary->machine_name,
300 'parent' => 0,
301 ),
302 ),
303 ),
304 );
305 field_create_field($this->tag_field);
306
307 // Create an instance of the tag field on one of the content types, and
308 // configure it to display an autocomplete widget.
309 $this->tag_instance = array(
310 'field_name' => 'field_views_testing_tags',
311 'entity_type' => 'node',
312 'bundle' => $this->node_type_with_tags->type,
313 'widget' => array(
314 'type' => 'taxonomy_autocomplete',
315 ),
316 'display' => array(
317 'default' => array(
318 'type' => 'taxonomy_term_reference_link',
319 'weight' => 10,
320 ),
321 'teaser' => array(
322 'type' => 'taxonomy_term_reference_link',
323 'weight' => 10,
324 ),
325 ),
326 );
327 field_create_instance($this->tag_instance);
328 }
329
330 /**
331 * Tests the "tagged with" functionality.
332 */
333 function testTaggedWith() {
334 // In this test we will only create nodes that have an instance of the tag
335 // field.
336 $node_add_path = 'node/add/' . $this->node_type_with_tags->type;
337
338 // Create three nodes, with different tags.
339 $tag_field = $this->tag_field['field_name'] . '[' . LANGUAGE_NONE . ']';
340 $edit = array();
341 $edit['title'] = $node_tag1_title = $this->randomName();
342 $edit[$tag_field] = 'tag1';
343 $this->drupalPost($node_add_path, $edit, t('Save'));
344 $edit = array();
345 $edit['title'] = $node_tag1_tag2_title = $this->randomName();
346 $edit[$tag_field] = 'tag1, tag2';
347 $this->drupalPost($node_add_path, $edit, t('Save'));
348 $edit = array();
349 $edit['title'] = $node_no_tags_title = $this->randomName();
350 $this->drupalPost($node_add_path, $edit, t('Save'));
351
352 // Create a view that filters by taxonomy term "tag1". It should show only
353 // the two nodes from above that are tagged with "tag1".
354 $view1 = array();
355 // First select the node type and update the form so the correct tag field
356 // is used.
357 $view1['show[type]'] = $this->node_type_with_tags->type;
358 $this->drupalPost('admin/structure/views/add', $view1, t('Update "of type" choice'));
359 // Now resubmit the entire form to the same URL.
360 $view1['human_name'] = $this->randomName(16);
361 $view1['name'] = strtolower($this->randomName(16));
362 $view1['description'] = $this->randomName(16);
363 $view1['show[tagged_with]'] = 'tag1';
364 $view1['page[create]'] = 1;
365 $view1['page[title]'] = $this->randomName(16);
366 $view1['page[path]'] = $this->randomName(16);
367 $this->drupalPost(NULL, $view1, t('Save & exit'));
368 // Visit the page and check that the nodes we expect are present and the
369 // ones we don't expect are absent.
370 $this->drupalGet($view1['page[path]']);
371 $this->assertText($node_tag1_title);
372 $this->assertText($node_tag1_tag2_title);
373 $this->assertNoText($node_no_tags_title);
374
375 // Create a view that filters by taxonomy term "tag2". It should show only
376 // the one node from above that is tagged with "tag2".
377 $view2 = array();
378 $view2['show[type]'] = $this->node_type_with_tags->type;
379 $this->drupalPost('admin/structure/views/add', $view2, t('Update "of type" choice'));
380 $view2['human_name'] = $this->randomName(16);
381 $view2['name'] = strtolower($this->randomName(16));
382 $view2['description'] = $this->randomName(16);
383 $view2['show[tagged_with]'] = 'tag2';
384 $view2['page[create]'] = 1;
385 $view2['page[title]'] = $this->randomName(16);
386 $view2['page[path]'] = $this->randomName(16);
387 $this->drupalPost(NULL, $view2, t('Save & exit'));
388 $this->drupalGet($view2['page[path]']);
389 $this->assertNoText($node_tag1_title);
390 $this->assertText($node_tag1_tag2_title);
391 $this->assertNoText($node_no_tags_title);
392 }
393
394 /**
395 * Tests that the "tagged with" form element only shows for node types that support it.
396 */
397 function testTaggedWithByNodeType() {
398 // The tagging field is associated with one of our node types only. So the
399 // "tagged with" form element on the view wizard should appear on the form
400 // by default (when the wizard is configured to display all content) and
401 // also when the node type that has the tagging field is selected, but not
402 // when the node type that doesn't have the tagging field is selected.
403 $tags_xpath = '//input[@name="show[tagged_with]"]';
404 $this->drupalGet('admin/structure/views/add');
405 $this->assertFieldByXpath($tags_xpath);
406 $view['show[type]'] = $this->node_type_with_tags->type;
407 $this->drupalPost('admin/structure/views/add', $view, t('Update "of type" choice'));
408 $this->assertFieldByXpath($tags_xpath);
409 $view['show[type]'] = $this->node_type_without_tags->type;
410 $this->drupalPost(NULL, $view, t('Update "of type" choice'));
411 $this->assertNoFieldByXpath($tags_xpath);
412
413 // If we add an instance of the tagging field to the second node type, the
414 // "tagged with" form element should not appear for it too.
415 $instance = $this->tag_instance;
416 $instance['bundle'] = $this->node_type_without_tags->type;
417 field_create_instance($instance);
418 $view['show[type]'] = $this->node_type_with_tags->type;
419 $this->drupalPost('admin/structure/views/add', $view, t('Update "of type" choice'));
420 $this->assertFieldByXpath($tags_xpath);
421 $view['show[type]'] = $this->node_type_without_tags->type;
422 $this->drupalPost(NULL, $view, t('Update "of type" choice'));
423 $this->assertFieldByXpath($tags_xpath);
424 }
425 }
426
427 /**
428 * Tests the ability of the views wizard to create views with sorts.
429 */
430 class ViewsUIWizardSortingTestCase extends ViewsUIWizardHelper {
431 public static function getInfo() {
432 return array(
433 'name' => 'Views UI wizard sorting functionality',
434 'description' => 'Test the ability of the views wizard to create views with sorts.',
435 'group' => 'Views UI',
436 );
437 }
438
439 /**
440 * Tests the sorting functionality.
441 */
442 function testSorting() {
443 // Create nodes, each with a different creation time so that we can do a
444 // meaningful sort.
445 $node1 = $this->drupalCreateNode(array('created' => REQUEST_TIME));
446 $node2 = $this->drupalCreateNode(array('created' => REQUEST_TIME + 1));
447 $node3 = $this->drupalCreateNode(array('created' => REQUEST_TIME + 2));
448
449 // Create a view that sorts oldest first.
450 $view1 = array();
451 $view1['human_name'] = $this->randomName(16);
452 $view1['name'] = strtolower($this->randomName(16));
453 $view1['description'] = $this->randomName(16);
454 $view1['show[sort]'] = 'created:ASC';
455 $view1['page[create]'] = 1;
456 $view1['page[title]'] = $this->randomName(16);
457 $view1['page[path]'] = $this->randomName(16);
458 $this->drupalPost('admin/structure/views/add', $view1, t('Save & exit'));
459
460 // Make sure the view shows the nodes in the expected order.
461 $this->assertUrl($view1['page[path]']);
462 $this->assertText($view1['page[title]']);
463 $content = $this->drupalGetContent();
464 $this->assertText($node1->title);
465 $this->assertText($node2->title);
466 $this->assertText($node3->title);
467 $pos1 = strpos($content, $node1->title);
468 $pos2 = strpos($content, $node2->title);
469 $pos3 = strpos($content, $node3->title);
470 $this->assertTrue($pos1 < $pos2 && $pos2 < $pos3, t('The nodes appear in the expected order in a view that sorts by oldest first.'));
471
472 // Create a view that sorts newest first.
473 $view2 = array();
474 $view2['human_name'] = $this->randomName(16);
475 $view2['name'] = strtolower($this->randomName(16));
476 $view2['description'] = $this->randomName(16);
477 $view2['show[sort]'] = 'created:DESC';
478 $view2['page[create]'] = 1;
479 $view2['page[title]'] = $this->randomName(16);
480 $view2['page[path]'] = $this->randomName(16);
481 $this->drupalPost('admin/structure/views/add', $view2, t('Save & exit'));
482
483 // Make sure the view shows the nodes in the expected order.
484 $this->assertUrl($view2['page[path]']);
485 $this->assertText($view2['page[title]']);
486 $content = $this->drupalGetContent();
487 $this->assertText($node3->title);
488 $this->assertText($node2->title);
489 $this->assertText($node1->title);
490 $pos3 = strpos($content, $node3->title);
491 $pos2 = strpos($content, $node2->title);
492 $pos1 = strpos($content, $node1->title);
493 $this->assertTrue($pos3 < $pos2 && $pos2 < $pos1, t('The nodes appear in the expected order in a view that sorts by newest first.'));
494 }
495 }
496
497 /**
498 * Tests the ability of the views wizard to specify the number of items per page.
499 */
500 class ViewsUIWizardItemsPerPageTestCase extends ViewsUIWizardHelper {
501 public static function getInfo() {
502 return array(
503 'name' => 'Views UI wizard items per page functionality',
504 'description' => 'Test the ability of the views wizard to specify the number of items per page.',
505 'group' => 'Views UI',
506 );
507 }
508
509 /**
510 * Tests the number of items per page.
511 */
512 function testItemsPerPage() {
513 // Create articles, each with a different creation time so that we can do a
514 // meaningful sort.
515 $node1 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME));
516 $node2 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 1));
517 $node3 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 2));
518 $node4 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 3));
519 $node5 = $this->drupalCreateNode(array('type' => 'article', 'created' => REQUEST_TIME + 4));
520
521 // Create a page. This should never appear in the view created below.
522 $page_node = $this->drupalCreateNode(array('type' => 'page', 'created' => REQUEST_TIME + 2));
523
524 // Create a view that sorts newest first, and shows 4 items in the page and
525 // 3 in the block.
526 $view = array();
527 $view['human_name'] = $this->randomName(16);
528 $view['name'] = strtolower($this->randomName(16));
529 $view['description'] = $this->randomName(16);
530 $view['show[wizard_key]'] = 'node';
531 $view['show[type]'] = 'article';
532 $view['show[sort]'] = 'created:DESC';
533 $view['page[create]'] = 1;
534 $view['page[title]'] = $this->randomName(16);
535 $view['page[path]'] = $this->randomName(16);
536 $view['page[items_per_page]'] = 4;
537 $view['block[create]'] = 1;
538 $view['block[title]'] = $this->randomName(16);
539 $view['block[items_per_page]'] = 3;
540 $this->drupalPost('admin/structure/views/add', $view, t('Save & exit'));
541
542 // Make sure the page display shows the nodes we expect, and that they
543 // appear in the expected order.
544 $this->assertUrl($view['page[path]']);
545 $this->assertText($view['page[title]']);
546 $content = $this->drupalGetContent();
547 $this->assertText($node5->title);
548 $this->assertText($node4->title);
549 $this->assertText($node3->title);
550 $this->assertText($node2->title);
551 $this->assertNoText($node1->title);
552 $this->assertNoText($page_node->title);
553 $pos5 = strpos($content, $node5->title);
554 $pos4 = strpos($content, $node4->title);
555 $pos3 = strpos($content, $node3->title);
556 $pos2 = strpos($content, $node2->title);
557 $this->assertTrue($pos5 < $pos4 && $pos4 < $pos3 && $pos3 < $pos2, t('The nodes appear in the expected order in the page display.'));
558
559 // Put the block into the first sidebar region, visit a page that displays
560 // the block, and check that the nodes we expect appear in the correct
561 // order.
562 $this->drupalGet('admin/structure/block');
563 $this->assertText('View: ' . $view['human_name']);
564 $edit = array();
565 $edit["blocks[views_{$view['name']}-block][region]"] = 'sidebar_first';
566 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
567 $this->drupalGet('user');
568 $content = $this->drupalGetContent();
569 $this->assertText($node5->title);
570 $this->assertText($node4->title);
571 $this->assertText($node3->title);
572 $this->assertNoText($node2->title);
573 $this->assertNoText($node1->title);
574 $this->assertNoText($page_node->title);
575 $pos5 = strpos($content, $node5->title);
576 $pos4 = strpos($content, $node4->title);
577 $pos3 = strpos($content, $node3->title);
578 $this->assertTrue($pos5 < $pos4 && $pos4 < $pos3, t('The nodes appear in the expected order in the block display.'));
579 }
580 }
581
582 /**
583 * Tests the ability of the views wizard to put views in a menu.
584 */
585 class ViewsUIWizardMenuTestCase extends ViewsUIWizardHelper {
586 public static function getInfo() {
587 return array(
588 'name' => 'Views UI wizard menu functionality',
589 'description' => 'Test the ability of the views wizard to put views in a menu.',
590 'group' => 'Views UI',
591 );
592 }
593
594 /**
595 * Tests the menu functionality.
596 */
597 function testMenus() {
598 // Create a view with a page display and a menu link in the Main Menu.
599 $view = array();
600 $view['human_name'] = $this->randomName(16);
601 $view['name'] = strtolower($this->randomName(16));
602 $view['description'] = $this->randomName(16);
603 $view['page[create]'] = 1;
604 $view['page[title]'] = $this->randomName(16);
605 $view['page[path]'] = $this->randomName(16);
606 $view['page[link]'] = 1;
607 $view['page[link_properties][menu_name]'] = 'main-menu';
608 $view['page[link_properties][title]'] = $this->randomName(16);
609 $this->drupalPost('admin/structure/views/add', $view, t('Save & exit'));
610
611 // Make sure there is a link to the view from the front page (where we
612 // expect the main menu to display).
613 $this->drupalGet('');
614 $this->assertLink($view['page[link_properties][title]']);
615 $this->assertLinkByHref(url($view['page[path]']));
616
617 // Make sure the link is associated with the main menu.
618 $links = menu_load_links('main-menu');
619 $found = FALSE;
620 foreach ($links as $link) {
621 if ($link['link_path'] == $view['page[path]']) {
622 $found = TRUE;
623 break;
624 }
625 }
626 $this->assertTrue($found, t('Found a link to %path in the main menu', array('%path' => $view['page[path]'])));
627 }
628 }
629
630 /**
631 * Tests the ability of the views wizard to create views with a jump menu style plugin.
632 */
633 class ViewsUIWizardJumpMenuTestCase extends ViewsUIWizardHelper {
634 public static function getInfo() {
635 return array(
636 'name' => 'Views UI wizard jump menu functionality',
637 'description' => 'Test the ability of the views wizard to create views with a jump menu style plugin.',
638 'group' => 'Views UI',
639 );
640 }
641
642 /**
643 * Tests the jump menu style plugin.
644 */
645 function testJumpMenus() {
646 // We'll run this test for several different base tables that appear in the
647 // wizard.
648 $base_table_methods = array(
649 'node' => 'createNodeAndGetPath',
650 'users' => 'createUserAndGetPath',
651 'comment' => 'createCommentAndGetPath',
652 'taxonomy_term' => 'createTaxonomyTermAndGetPath',
653 'file_managed' => 'createFileAndGetPath',
654 'node_revision' => 'createNodeRevisionAndGetPath',
655 );
656
657 foreach ($base_table_methods as $base_table => $method) {
658 // For each base table, find the path that we expect the jump menu to
659 // redirect us to.
660 $path_info = $this->{$method}();
661 if (is_array($path_info)) {
662 $path = $path_info['path'];
663 $options = isset($path_info['options']) ? $path_info['options'] : array();
664 }
665 else {
666 $path = $path_info;
667 $options = array();
668 }
669
670 // Create a page view for the specified base table that uses the jump
671 // menu style plugin.
672 $view = array();
673 $view['human_name'] = $this->randomName(16);
674 $view['name'] = strtolower($this->randomName(16));
675 $view['description'] = $this->randomName(16);
676 $view['show[wizard_key]'] = $base_table;
677 $view['page[create]'] = 1;
678 $view['page[title]'] = $this->randomName(16);
679 $view['page[path]'] = $this->randomName(16);
680 $view['page[style][style_plugin]'] = 'jump_menu';
681 $view['page[style][row_plugin]'] = 'fields';
682 $this->drupalPost('admin/structure/views/add', $view, t('Save & exit'));
683
684 // Submit the jump menu form, and check that we are redirected to the
685 // expected URL.
686
687 $edit = array();
688 $edit['jump'] = url($path, $options);
689
690 // The urls are built with :: to be able to have a unique path all the time,
691 // so try to find out the real path of $edit.
692 $view_object = views_get_view($view['name']);
693 $view_object->preview('page');
694 $form = $view_object->style_plugin->render();
695 $jump_options = $form['jump']['#options'];
696 foreach ($jump_options as $key => $title) {
697 if (strpos($key, $edit['jump']) !== FALSE) {
698 $edit['jump'] = $key;
699 }
700 }
701
702 $this->drupalPost($view['page[path]'], $edit, t('Go'));
703 $this->assertResponse(200);
704 $this->assertUrl($path, $options);
705 }
706 }
707
708 /**
709 * Helper function to create a node and return its expected path.
710 */
711 function createNodeAndGetPath() {
712 $node = $this->drupalCreateNode();
713 return entity_uri('node', $node);
714 }
715
716 /**
717 * Helper function to create a user and return its expected path.
718 */
719 function createUserAndGetPath() {
720 $account = $this->drupalCreateUser();
721 return entity_uri('user', $account);
722 }
723
724 /**
725 * Helper function to create a comment and return its expected path.
726 */
727 function createCommentAndGetPath() {
728 $node = $this->drupalCreateNode();
729 $comment = (object) array(
730 'cid' => NULL,
731 'nid' => $node->nid,
732 'pid' => 0,
733 'uid' => 0,
734 'status' => COMMENT_PUBLISHED,
735 'subject' => $this->randomName(),
736 'language' => LANGUAGE_NONE,
737 'comment_body' => array(LANGUAGE_NONE => array($this->randomName())),
738 );
739 comment_save($comment);
740 return entity_uri('comment', $comment);
741 }
742
743 /**
744 * Helper function to create a taxonomy term and return its expected path.
745 */
746 function createTaxonomyTermAndGetPath() {
747 $vocabulary = new stdClass();
748 $vocabulary->name = $this->randomName();
749 $vocabulary->machine_name = drupal_strtolower($this->randomName());
750 taxonomy_vocabulary_save($vocabulary);
751
752 $term = new stdClass();
753 $term->name = $this->randomName();
754 $term->vid = $vocabulary->vid;
755 taxonomy_term_save($term);
756
757 return entity_uri('taxonomy_term', $term);
758 }
759
760 /**
761 * Helper function to create a file and return its expected path.
762 */
763 function createFileAndGetPath() {
764 $file = (object) array(
765 'uid' => 1,
766 'filename' => 'views-ui-jump-menu-test.txt',
767 'uri' => 'public://views-ui-jump-menu-test.txt',
768 'filemime' => 'text/plain',
769 'timestamp' => 1,
770 'status' => FILE_STATUS_PERMANENT,
771 );
772 file_put_contents($file->uri, 'test content');
773 $file = file_save($file);
774 return file_create_url($file->uri);
775 }
776
777 /**
778 * Helper function to create a node revision and return its expected path.
779 */
780 function createNodeRevisionAndGetPath() {
781 // The node needs at least two revisions in order for Drupal to allow
782 // access to the revision path.
783 $settings = array('revision' => TRUE);
784 $node = $this->drupalCreateNode($settings);
785 $node->vid = NULL;
786 node_save($node);
787 return 'node/' . $node->nid . '/revisions/' . $node->vid . '/view';
788 }
789 }
790
791 /**
792 * Tests that displays can be correctly overridden via the user interface.
793 */
794 class ViewsUIWizardOverrideDisplaysTestCase extends ViewsUIWizardHelper {
795 public static function getInfo() {
796 return array(
797 'name' => 'Views UI overridden displays',
798 'description' => 'Test that displays can be correctly overridden via the user interface.',
799 'group' => 'Views UI',
800 );
801 }
802
803 /**
804 * Tests that displays can be overridden via the UI.
805 */
806 function testOverrideDisplays() {
807 // Create a basic view that shows all content, with a page and a block
808 // display.
809 $view['human_name'] = $this->randomName(16);
810 $view['name'] = strtolower($this->randomName(16));
811 $view['page[create]'] = 1;
812 $view['page[path]'] = $this->randomName(16);
813 $view['block[create]'] = 1;
814 $view_path = $view['page[path]'];
815 $this->drupalPost('admin/structure/views/add', $view, t('Save & exit'));
816
817 // Configure its title. Since the page and block both started off with the
818 // same (empty) title in the views wizard, we expect the wizard to have set
819 // things up so that they both inherit from the default display, and we
820 // therefore only need to change that to have it take effect for both.
821 $edit = array();
822 $edit['title'] = $original_title = $this->randomName(16);
823 $edit['override[dropdown]'] = 'default';
824 $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page/title", $edit, t('Apply'));
825 $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/page", array(), t('Save'));
826
827 // Put the block into the first sidebar region, and make sure it will not
828 // display on the view's page display (since we will be searching for the
829 // presence/absence of the view's title in both the page and the block).
830 $this->drupalGet('admin/structure/block');
831 $edit = array();
832 $edit["blocks[views_{$view['name']}-block][region]"] = 'sidebar_first';
833 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
834 $edit = array();
835 $edit['visibility'] = BLOCK_VISIBILITY_NOTLISTED;
836 $edit['pages'] = $view_path;
837 $this->drupalPost("admin/structure/block/manage/views/{$view['name']}-block/configure", $edit, t('Save block'));
838
839 // Add a node that will appear in the view, so that the block will actually
840 // be displayed.
841 $this->drupalCreateNode();
842
843 // Make sure the title appears in both the page and the block.
844 $this->drupalGet($view_path);
845 $this->assertText($original_title);
846 $this->drupalGet('');
847 $this->assertText($original_title);
848
849 // Change the title for the page display only, and make sure that is the
850 // only one that is changed.
851 $edit = array();
852 $edit['title'] = $new_title = $this->randomName(16);
853 $edit['override[dropdown]'] = 'page';
854 $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page/title", $edit, t('Apply'));
855 $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/page", array(), t('Save'));
856 $this->drupalGet($view_path);
857 $this->assertText($new_title);
858 $this->assertNoText($original_title);
859 $this->drupalGet('');
860 $this->assertText($original_title);
861 $this->assertNoText($new_title);
862 }
863
864 /**
865 * Tests that the wizard correctly sets up default and overridden displays.
866 */
867 function testWizardMixedDefaultOverriddenDisplays() {
868 // Create a basic view with a page, block, and feed. Give the page and feed
869 // identical titles, but give the block a different one, so we expect the
870 // page and feed to inherit their titles from the default display, but the
871 // block to override it.
872 $view['human_name'] = $this->randomName(16);
873 $view['name'] = strtolower($this->randomName(16));
874 $view['page[create]'] = 1;
875 $view['page[title]'] = $this->randomName(16);
876 $view['page[path]'] = $this->randomName(16);
877 $view['page[feed]'] = 1;
878 $view['page[feed_properties][path]'] = $this->randomName(16);
879 $view['block[create]'] = 1;
880 $view['block[title]'] = $this->randomName(16);
881 $this->drupalPost('admin/structure/views/add', $view, t('Save & exit'));
882
883 // Put the block into the first sidebar region, and make sure it will not
884 // display on the view's page display (since we will be searching for the
885 // presence/absence of the view's title in both the page and the block).
886 $this->drupalGet('admin/structure/block');
887 $edit = array();
888 $edit["blocks[views_{$view['name']}-block][region]"] = 'sidebar_first';
889 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
890 $edit = array();
891 $edit['visibility'] = BLOCK_VISIBILITY_NOTLISTED;
892 $edit['pages'] = $view['page[path]'];
893 $this->drupalPost("admin/structure/block/manage/views/{$view['name']}-block/configure", $edit, t('Save block'));
894
895 // Add a node that will appear in the view, so that the block will actually
896 // be displayed.
897 $this->drupalCreateNode();
898
899 // Make sure that the feed, page and block all start off with the correct
900 // titles.
901 $this->drupalGet($view['page[path]']);
902 $this->assertText($view['page[title]']);
903 $this->assertNoText($view['block[title]']);
904 $this->drupalGet($view['page[feed_properties][path]']);
905 $this->assertText($view['page[title]']);
906 $this->assertNoText($view['block[title]']);
907 $this->drupalGet('');
908 $this->assertText($view['block[title]']);
909 $this->assertNoText($view['page[title]']);
910
911 // Edit the page and change the title. This should automatically change
912 // the feed's title also, but not the block.
913 $edit = array();
914 $edit['title'] = $new_default_title = $this->randomName(16);
915 $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page/title", $edit, t('Apply'));
916 $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/page", array(), t('Save'));
917 $this->drupalGet($view['page[path]']);
918 $this->assertText($new_default_title);
919 $this->assertNoText($view['page[title]']);
920 $this->assertNoText($view['block[title]']);
921 $this->drupalGet($view['page[feed_properties][path]']);
922 $this->assertText($new_default_title);
923 $this->assertNoText($view['page[title]']);
924 $this->assertNoText($view['block[title]']);
925 $this->drupalGet('');
926 $this->assertText($view['block[title]']);
927 $this->assertNoText($new_default_title);
928 $this->assertNoText($view['page[title]']);
929
930 // Edit the block and change the title. This should automatically change
931 // the block title only, and leave the defaults alone.
932 $edit = array();
933 $edit['title'] = $new_block_title = $this->randomName(16);
934 $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/block/title", $edit, t('Apply'));
935 $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/block", array(), t('Save'));
936 $this->drupalGet($view['page[path]']);
937 $this->assertText($new_default_title);
938 $this->assertNoText($new_block_title);
939 $this->drupalGet($view['page[feed_properties][path]']);
940 $this->assertText($new_default_title);
941 $this->assertNoText($new_block_title);
942 $this->drupalGet('');
943 $this->assertText($new_block_title);
944 $this->assertNoText($view['block[title]']);
945 }
946
947 /**
948 * Tests that the revert to all displays select-option works as expected.
949 */
950 function testRevertAllDisplays() {
951 // Create a basic view with a page, block.
952 // Because there is both a title on page and block we expect the title on
953 // the block be overriden.
954 $view['human_name'] = $this->randomName(16);
955 $view['name'] = strtolower($this->randomName(16));
956 $view['page[create]'] = 1;
957 $view['page[title]'] = $this->randomName(16);
958 $view['page[path]'] = $this->randomName(16);
959 $view['block[create]'] = 1;
960 $view['block[title]'] = $this->randomName(16);
961 $this->drupalPost('admin/structure/views/add', $view, t('Continue & edit'));
962
963 // Revert the title of the block back to the default ones, but submit some
964 // new values to be sure that the new value is not stored.
965 $edit = array();
966 $edit['title'] = $new_block_title = $this->randomName();
967 $edit['override[dropdown]'] = 'default_revert';
968
969 $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/block/title", $edit, t('Apply'));
970 $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/block", array(), t('Save'));
971 $this->assertText($view['page[title]']);
972 }
973 }