/[drupal]/drupal/modules/node/node.test
ViewVC logotype

Contents of /drupal/modules/node/node.test

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.52 - (show annotations) (download) (as text)
Tue Nov 3 04:35:01 2009 UTC (3 weeks, 5 days ago) by webchick
Branch: MAIN
Changes since 1.51: +1 -3 lines
File MIME type: text/x-php
#551034 by brandonojc, mgifford, Everett Zufelt, and Cliff: Improved Content filter usability and accessibility.
1 <?php
2 // $Id: node.test,v 1.51 2009/10/30 22:33:35 dries Exp $
3
4 /**
5 * Test the node_load_multiple() function.
6 */
7 class NodeLoadMultipleUnitTest extends DrupalWebTestCase {
8
9 public static function getInfo() {
10 return array(
11 'name' => 'Load multiple nodes',
12 'description' => 'Test the loading of multiple nodes.',
13 'group' => 'Node',
14 );
15 }
16
17 function setUp() {
18 parent::setUp();
19 $web_user = $this->drupalCreateUser(array('create article content', 'create page content'));
20 $this->drupalLogin($web_user);
21 }
22
23 /**
24 * Create four nodes and ensure they're loaded correctly.
25 */
26 function testNodeMultipleLoad() {
27 $node1 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
28 $node2 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
29 $node3 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 0));
30 $node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0));
31
32 // Confirm that promoted nodes appear in the default node listing.
33 $this->drupalGet('node');
34 $this->assertText($node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node title appears on the default listing.'));
35 $this->assertText($node2->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node title appears on the default listing.'));
36 $this->assertNoText($node3->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node title does not appear in the default listing.'));
37 $this->assertNoText($node4->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node title does not appear in the default listing.'));
38
39 // Load nodes with only a condition. Nodes 3 and 4 will be loaded.
40 $nodes = node_load_multiple(NULL, array('promote' => 0));
41 $this->assertEqual($node3->title[FIELD_LANGUAGE_NONE][0]['value'], $nodes[$node3->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node was loaded.'));
42 $this->assertEqual($node4->title[FIELD_LANGUAGE_NONE][0]['value'], $nodes[$node4->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node was loaded.'));
43 $count = count($nodes);
44 $this->assertTrue($count == 2, t('@count nodes loaded.', array('@count' => $count)));
45
46 // Load nodes by nid. Nodes 1, 2 and 4 will be loaded.
47 $nodes = node_load_multiple(array(1, 2, 4));
48 $count = count($nodes);
49 $this->assertTrue(count($nodes) == 3, t('@count nodes loaded', array('@count' => $count)));
50 $this->assertTrue(isset($nodes[$node1->nid]), t('Node is correctly keyed in the array'));
51 $this->assertTrue(isset($nodes[$node2->nid]), t('Node is correctly keyed in the array'));
52 $this->assertTrue(isset($nodes[$node4->nid]), t('Node is correctly keyed in the array'));
53 foreach ($nodes as $node) {
54 $this->assertTrue(is_object($node), t('Node is an object'));
55 }
56
57 // Load nodes by nid, where type = article. Nodes 1, 2 and 3 will be loaded.
58 $nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article'));
59 $count = count($nodes);
60 $this->assertTrue($count == 3, t('@count nodes loaded', array('@count' => $count)));
61 $this->assertEqual($nodes[$node1->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded.'));
62 $this->assertEqual($nodes[$node2->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node2->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded.'));
63 $this->assertEqual($nodes[$node3->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node3->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded.'));
64 $this->assertFalse(isset($nodes[$node4->nid]));
65
66 // Now that all nodes have been loaded into the static cache, ensure that
67 // they are loaded correctly again when a condition is passed.
68 $nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article'));
69 $count = count($nodes);
70 $this->assertTrue($count == 3, t('@count nodes loaded.', array('@count' => $count)));
71 $this->assertEqual($nodes[$node1->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded'));
72 $this->assertEqual($nodes[$node2->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node2->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded'));
73 $this->assertEqual($nodes[$node3->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node3->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded'));
74 $this->assertFalse(isset($nodes[$node4->nid]), t('Node was not loaded'));
75
76 // Load nodes by nid, where type = article and promote = 0.
77 $nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article', 'promote' => 0));
78 $count = count($nodes);
79 $this->assertTrue($count == 1, t('@count node loaded', array('@count' => $count)));
80 $this->assertEqual($nodes[$node3->nid]->title[FIELD_LANGUAGE_NONE][0]['value'], $node3->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node successfully loaded.'));
81 }
82 }
83
84 class NodeRevisionsTestCase extends DrupalWebTestCase {
85 protected $nodes;
86 protected $logs;
87
88 public static function getInfo() {
89 return array(
90 'name' => 'Node revisions',
91 'description' => 'Create a node with revisions and test viewing, reverting, and deleting revisions.',
92 'group' => 'Node',
93 );
94 }
95
96 function setUp() {
97 parent::setUp();
98
99 // Create and login user.
100 $web_user = $this->drupalCreateUser(array('view revisions', 'revert revisions', 'edit any page content',
101 'delete revisions', 'delete any page content'));
102 $this->drupalLogin($web_user);
103
104 // Create initial node.
105 $node = $this->drupalCreateNode();
106 $settings = get_object_vars($node);
107 $settings['revision'] = 1;
108
109 $nodes = array();
110 $logs = array();
111
112 // Get original node.
113 $nodes[] = $node;
114
115 // Create three revisions.
116 $revision_count = 3;
117 for ($i = 0; $i < $revision_count; $i++) {
118 $logs[] = $settings['log'] = $this->randomName(32);
119
120 // Create revision with random title and body and update variables.
121 $this->drupalCreateNode($settings);
122 $node = node_load($node->nid); // Make sure we get revision information.
123 $settings = get_object_vars($node);
124
125 $nodes[] = $node;
126 }
127
128 $this->nodes = $nodes;
129 $this->logs = $logs;
130 }
131
132 /**
133 * Check node revision related operations.
134 */
135 function testRevisions() {
136 $nodes = $this->nodes;
137 $logs = $this->logs;
138
139 // Get last node for simple checks.
140 $node = $nodes[3];
141
142 // Confirm the correct revision text appears on "view revisions" page.
143 $this->drupalGet("node/$node->nid/revisions/$node->vid/view");
144 $this->assertText($node->body[FIELD_LANGUAGE_NONE][0]['value'], t('Correct text displays for version.'));
145
146 // Confirm the correct log message appears on "revisions overview" page.
147 $this->drupalGet("node/$node->nid/revisions");
148 foreach ($logs as $log) {
149 $this->assertText($log, t('Log message found.'));
150 }
151
152 // Confirm that revisions revert properly.
153 $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/revert", array(), t('Revert'));
154 $this->assertRaw(t('@type %title has been reverted back to the revision from %revision-date.',
155 array('@type' => 'Page', '%title' => $nodes[1]->title[FIELD_LANGUAGE_NONE][0]['value'],
156 '%revision-date' => format_date($nodes[1]->revision_timestamp))), t('Revision reverted.'));
157 $reverted_node = node_load($node->nid);
158 $this->assertTrue(($nodes[1]->body[FIELD_LANGUAGE_NONE][0]['value'] == $reverted_node->body[FIELD_LANGUAGE_NONE][0]['value']), t('Node reverted correctly.'));
159
160 // Confirm revisions delete properly.
161 $this->drupalPost("node/$node->nid/revisions/{$nodes[1]->vid}/delete", array(), t('Delete'));
162 $this->assertRaw(t('Revision from %revision-date of @type %title has been deleted.',
163 array('%revision-date' => format_date($nodes[1]->revision_timestamp),
164 '@type' => 'Page', '%title' => $nodes[1]->title[FIELD_LANGUAGE_NONE][0]['value'])), t('Revision deleted.'));
165 $this->assertTrue(db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid and vid = :vid', array(':nid' => $node->nid, ':vid' => $nodes[1]->vid))->fetchField() == 0, t('Revision not found.'));
166 }
167 }
168
169 class PageEditTestCase extends DrupalWebTestCase {
170 public static function getInfo() {
171 return array(
172 'name' => 'Node edit',
173 'description' => 'Create a node and test node edit functionality.',
174 'group' => 'Node',
175 );
176 }
177
178 function setUp() {
179 parent::setUp();
180
181 $web_user = $this->drupalCreateUser(array('edit own page content', 'create page content'));
182 $this->drupalLogin($web_user);
183 }
184
185 /**
186 * Check node edit functionality.
187 */
188 function testPageEdit() {
189 $langcode = FIELD_LANGUAGE_NONE;
190 $title_key = "title[$langcode][0][value]";
191 $body_key = "body[$langcode][0][value]";
192 // Create node to edit.
193 $edit = array();
194 $edit[$title_key] = $this->randomName(8);
195 $edit[$body_key] = $this->randomName(16);
196 $this->drupalPost('node/add/page', $edit, t('Save'));
197
198 // Check that the node exists in the database.
199 $node = $this->drupalGetNodeByTitle($edit[$title_key]);
200 $this->assertTrue($node, t('Node found in database.'));
201
202 // Check that "edit" link points to correct page.
203 $this->clickLink(t('Edit'));
204 $edit_url = url("node/$node->nid/edit", array('absolute' => TRUE));
205 $actual_url = $this->getURL();
206 $this->assertEqual($edit_url, $actual_url, t('On edit page.'));
207
208 // Check that the title and body fields are displayed with the correct values.
209 $this->assertLink(t('Edit'), 0, t('Edit tab found.'));
210 $this->assertFieldByName($title_key, $edit[$title_key], t('Title field displayed.'));
211 $this->assertFieldByName($body_key, $edit[$body_key], t('Body field displayed.'));
212
213 // Edit the content of the node.
214 $edit = array();
215 $edit[$title_key] = $this->randomName(8);
216 $edit[$body_key] = $this->randomName(16);
217 // Stay on the current page, without reloading.
218 $this->drupalPost(NULL, $edit, t('Save'));
219
220 // Check that the title and body fields are displayed with the updated values.
221 $this->assertText($edit[$title_key], t('Title displayed.'));
222 $this->assertText($edit[$body_key], t('Body displayed.'));
223
224 // Login as a second administrator user.
225 $second_web_user = $this->drupalCreateUser(array('administer nodes', 'edit any page content'));
226 $this->drupalLogin($second_web_user);
227 // Edit the same node, creating a new revision.
228 $this->drupalGet("node/$node->nid/edit");
229 $edit = array();
230 $edit[$title_key] = $this->randomName(8);
231 $edit[$body_key] = $this->randomName(16);
232 $edit['revision'] = TRUE;
233 $this->drupalPost(NULL, $edit, t('Save'));
234
235 // Ensure that the node revision has been created.
236 $revised_node = $this->drupalGetNodeByTitle($edit[$title_key]);
237 $this->assertNotIdentical($node->vid, $revised_node->vid, 'A new revision has been created.');
238 // Ensure that the node author is preserved when it was not changed in the
239 // edit form.
240 $this->assertIdentical($node->uid, $revised_node->uid, 'The node author has been preserved.');
241 // Ensure that the revision authors are different since the revisions were
242 // made by different users.
243 $first_node_version = node_load($node->nid, $node->vid);
244 $second_node_version = node_load($node->nid, $revised_node->vid);
245 $this->assertNotIdentical($first_node_version->revision_uid, $second_node_version->revision_uid, 'Each revision has a distinct user.');
246 }
247 }
248
249 class PagePreviewTestCase extends DrupalWebTestCase {
250 public static function getInfo() {
251 return array(
252 'name' => 'Node preview',
253 'description' => 'Test node preview functionality.',
254 'group' => 'Node',
255 );
256 }
257
258 function setUp() {
259 parent::setUp();
260
261 $web_user = $this->drupalCreateUser(array('edit own page content', 'create page content'));
262 $this->drupalLogin($web_user);
263 }
264
265 /**
266 * Check the node preview functionality.
267 */
268 function testPagePreview() {
269 $langcode = FIELD_LANGUAGE_NONE;
270 $title_key = "title[$langcode][0][value]";
271 $body_key = "body[$langcode][0][value]";
272
273 // Fill in node creation form and preview node.
274 $edit = array();
275 $edit[$title_key] = $this->randomName(8);
276 $edit[$body_key] = $this->randomName(16);
277 $this->drupalPost('node/add/page', $edit, t('Preview'));
278
279 // Check that the preview is displaying the title and body.
280 $this->assertTitle(t('Preview | Drupal'), t('Page title is preview.'));
281 $this->assertText($edit[$title_key], t('Title displayed.'));
282 $this->assertText($edit[$body_key], t('Body displayed.'));
283
284 // Check that the title and body fields are displayed with the correct values.
285 $this->assertFieldByName($title_key, $edit[$title_key], t('Title field displayed.'));
286 $this->assertFieldByName($body_key, $edit[$body_key], t('Body field displayed.'));
287 }
288
289 /**
290 * Check the node preview functionality, when using revisions.
291 */
292 function testPagePreviewWithRevisions() {
293 $langcode = FIELD_LANGUAGE_NONE;
294 $title_key = "title[$langcode][0][value]";
295 $body_key = "body[$langcode][0][value]";
296 // Force revision on page content.
297 variable_set('node_options_page', array('status', 'revision'));
298
299 // Fill in node creation form and preview node.
300 $edit = array();
301 $edit[$title_key] = $this->randomName(8);
302 $edit[$body_key] = $this->randomName(16);
303 $edit['log'] = $this->randomName(32);
304 $this->drupalPost('node/add/page', $edit, t('Preview'));
305
306 // Check that the preview is displaying the title and body.
307 $this->assertTitle(t('Preview | Drupal'), t('Page title is preview.'));
308 $this->assertText($edit[$title_key], t('Title displayed.'));
309 $this->assertText($edit[$body_key], t('Body displayed.'));
310
311 // Check that the title and body fields are displayed with the correct values.
312 $this->assertFieldByName($title_key, $edit[$title_key], t('Title field displayed.'));
313 $this->assertFieldByName($body_key, $edit[$body_key], t('Body field displayed.'));
314
315 // Check that the log field has the correct value.
316 $this->assertFieldByName('log', $edit['log'], t('Log field displayed.'));
317 }
318 }
319
320 class PageCreationTestCase extends DrupalWebTestCase {
321 public static function getInfo() {
322 return array(
323 'name' => 'Node creation',
324 'description' => 'Create a node and test saving it.',
325 'group' => 'Node',
326 );
327 }
328
329 function setUp() {
330 parent::setUp();
331
332 $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content'));
333 $this->drupalLogin($web_user);
334 }
335
336 /**
337 * Create a page node and verify its consistency in the database.
338 */
339 function testPageCreation() {
340 // Create a node.
341 $edit = array();
342 $langcode = FIELD_LANGUAGE_NONE;
343 $edit["title[$langcode][0][value]"] = $this->randomName(8);
344 $edit["body[$langcode][0][value]"] = $this->randomName(16);
345 $this->drupalPost('node/add/page', $edit, t('Save'));
346
347 // Check that the page has been created.
348 $this->assertRaw(t('!post %title has been created.', array('!post' => 'Page', '%title' => $edit["title[$langcode][0][value]"])), t('Page created.'));
349
350 // Check that the node exists in the database.
351 $node = $this->drupalGetNodeByTitle($edit["title[$langcode][0][value]"]);
352 $this->assertTrue($node, t('Node found in database.'));
353 }
354 }
355
356 class PageViewTestCase extends DrupalWebTestCase {
357 public static function getInfo() {
358 return array(
359 'name' => 'Node edit permissions',
360 'description' => 'Create a node and test edit permissions.',
361 'group' => 'Node',
362 );
363 }
364
365 /**
366 * Creates a node and then an anonymous and unpermissioned user attempt to edit the node.
367 */
368 function testPageView() {
369 // Create a node to view.
370 $node = $this->drupalCreateNode();
371 $this->assertTrue(node_load($node->nid), t('Node created.'));
372
373 // Try to edit with anonymous user.
374 $html = $this->drupalGet("node/$node->nid/edit");
375 $this->assertResponse(403);
376
377 // Create a user without permission to edit node.
378 $web_user = $this->drupalCreateUser(array('access content'));
379 $this->drupalLogin($web_user);
380
381 // Attempt to access edit page.
382 $this->drupalGet("node/$node->nid/edit");
383 $this->assertResponse(403);
384
385 // Create user with permission to edit node.
386 $web_user = $this->drupalCreateUser(array('bypass node access'));
387 $this->drupalLogin($web_user);
388
389 // Attempt to access edit page.
390 $this->drupalGet("node/$node->nid/edit");
391 $this->assertResponse(200);
392 }
393 }
394
395 class SummaryLengthTestCase extends DrupalWebTestCase {
396 public static function getInfo() {
397 return array(
398 'name' => 'Summary length',
399 'description' => 'Test summary length.',
400 'group' => 'Node',
401 );
402 }
403
404 /**
405 * Creates a node and then an anonymous and unpermissioned user attempt to edit the node.
406 */
407 function testSummaryLength() {
408 // Create a node to view.
409 $settings = array(
410 'body' => array(FIELD_LANGUAGE_NONE => array(array('value' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae arcu at leo cursus laoreet. Curabitur dui tortor, adipiscing malesuada tempor in, bibendum ac diam. Cras non tellus a libero pellentesque condimentum. What is a Drupalism? Suspendisse ac lacus libero. Ut non est vel nisl faucibus interdum nec sed leo. Pellentesque sem risus, vulputate eu semper eget, auctor in libero. Ut fermentum est vitae metus convallis scelerisque. Phasellus pellentesque rhoncus tellus, eu dignissim purus posuere id. Quisque eu fringilla ligula. Morbi ullamcorper, lorem et mattis egestas, tortor neque pretium velit, eget eleifend odio turpis eu purus. Donec vitae metus quis leo pretium tincidunt a pulvinar sem. Morbi adipiscing laoreet mauris vel placerat. Nullam elementum, nisl sit amet scelerisque malesuada, dolor nunc hendrerit quam, eu ultrices erat est in orci. Curabitur feugiat egestas nisl sed accumsan.'))),
411 'promote' => 1,
412 );
413 $node = $this->drupalCreateNode($settings);
414 $this->assertTrue(node_load($node->nid), t('Node created.'));
415
416 // Create user with permission to view the node.
417 $web_user = $this->drupalCreateUser(array('access content', 'administer content types'));
418 $this->drupalLogin($web_user);
419
420 // Attempt to access the front page.
421 $this->drupalGet("node");
422 // The node teaser when it has 600 characters in length
423 $expected = 'What is a Drupalism?';
424 $this->assertRaw($expected, t('Check that the summary is 600 characters in length'), 'Node');
425
426 // Edit the teaser lenght for 'page' content type
427 $edit = array (
428 'teaser_length' => 200,
429 );
430 $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
431 // Attempt to access the front page again and check if the summary is now only 200 characters in length.
432 $this->drupalGet("node");
433 $this->assertNoRaw($expected, t('Check that the summary is not longer than 200 characters'), 'Node');
434 }
435 }
436
437 class NodeTitleXSSTestCase extends DrupalWebTestCase {
438 public static function getInfo() {
439 return array(
440 'name' => 'Node title XSS filtering',
441 'description' => 'Create a node with dangerous tags in its title and test that they are escaped.',
442 'group' => 'Node',
443 );
444 }
445
446 function testNodeTitleXSS() {
447 // Prepare a user to do the stuff.
448 $web_user = $this->drupalCreateUser(array('create page content', 'edit any page content'));
449 $this->drupalLogin($web_user);
450
451 $xss = '<script>alert("xss")</script>';
452 $title = $xss . $this->randomName();
453 $langcode = FIELD_LANGUAGE_NONE;
454 $edit = array(
455 "title[$langcode][0][value]" => $title,
456 );
457
458 $this->drupalPost('node/add/page', $edit, t('Preview'));
459 $this->assertNoRaw($xss, t('Harmful tags are escaped when previewing a node.'));
460
461 $settings = array('title' => array(FIELD_LANGUAGE_NONE => array(array('value' => $title))));
462 $node = $this->drupalCreateNode($settings);
463
464 $this->drupalGet('node/' . $node->nid);
465 // assertTitle() decodes HTML-entities inside the <title> element.
466 $this->assertTitle($edit["title[$langcode][0][value]"] . ' | Drupal', t('Title is diplayed when viewing a node.'));
467 $this->assertNoRaw($xss, t('Harmful tags are escaped when viewing a node.'));
468
469 $this->drupalGet('node/' . $node->nid . '/edit');
470 $this->assertNoRaw($xss, t('Harmful tags are escaped when editing a node.'));
471 }
472 }
473
474 class NodeBlockTestCase extends DrupalWebTestCase {
475 public static function getInfo() {
476 return array(
477 'name' => 'Block availability',
478 'description' => 'Check if the syndicate block is available.',
479 'group' => 'Node',
480 );
481 }
482
483 function setUp() {
484 parent::setUp();
485
486 // Create and login user
487 $admin_user = $this->drupalCreateUser(array('administer blocks'));
488 $this->drupalLogin($admin_user);
489 }
490
491 function testSearchFormBlock() {
492 // Set block title to confirm that the interface is availble.
493 $this->drupalPost('admin/structure/block/manage/node/syndicate/configure', array('title' => $this->randomName(8)), t('Save block'));
494 $this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
495
496 // Set the block to a region to confirm block is availble.
497 $edit = array();
498 $edit['node_syndicate[region]'] = 'footer';
499 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
500 $this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
501 }
502 }
503
504 /**
505 * Check that the post information displays when enabled for a content type.
506 */
507 class NodePostSettingsTestCase extends DrupalWebTestCase {
508 public static function getInfo() {
509 return array(
510 'name' => 'Node post information display',
511 'description' => 'Check that the post information (submitted by Username on date) text displays appropriately.',
512 'group' => 'Node',
513 );
514 }
515
516 function setUp() {
517 parent::setUp();
518
519 $web_user = $this->drupalCreateUser(array('create page content', 'administer content types', 'access user profiles'));
520 $this->drupalLogin($web_user);
521 }
522
523 /**
524 * Set page content type to display post information and confirm its presence on a new node.
525 */
526 function testPagePostInfo() {
527
528 // Set page content type to display post information.
529 $edit = array();
530 $edit['node_submitted'] = TRUE;
531 $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
532
533 // Create a node.
534 $edit = array();
535 $langcode = FIELD_LANGUAGE_NONE;
536 $edit["title[$langcode][0][value]"] = $this->randomName(8);
537 $edit["body[$langcode][0][value]"] = $this->randomName(16);
538 $this->drupalPost('node/add/page', $edit, t('Save'));
539
540 // Check that the post information is displayed.
541 $node = $this->drupalGetNodeByTitle($edit["title[$langcode][0][value]"]);
542 $this->assertRaw('<span class="submitted">', t('Post information is displayed.'));
543 }
544
545 /**
546 * Set page content type to not display post information and confirm its absence on a new node.
547 */
548 function testPageNotPostInfo() {
549
550 // Set page content type to display post information.
551 $edit = array();
552 $edit['node_submitted'] = FALSE;
553 $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
554
555 // Create a node.
556 $edit = array();
557 $langcode = FIELD_LANGUAGE_NONE;
558 $edit["title[$langcode][0][value]"] = $this->randomName(8);
559 $edit["body[$langcode][0][value]"] = $this->randomName(16);
560 $this->drupalPost('node/add/page', $edit, t('Save'));
561
562 // Check that the post information is displayed.
563 $node = $this->drupalGetNodeByTitle($edit["title[$langcode][0][value]"]);
564 $this->assertNoRaw('<span class="submitted">', t('Post information is not displayed.'));
565 }
566 }
567
568 /**
569 * Ensure that data added to nodes by other modules appears in RSS feeds.
570 *
571 * Create a node, enable the node_test module to ensure that extra data is
572 * added to the node->content array, then verify that the data appears on the
573 * sitewide RSS feed at rss.xml.
574 */
575 class NodeRSSContentTestCase extends DrupalWebTestCase {
576 public static function getInfo() {
577 return array(
578 'name' => 'Node RSS Content',
579 'description' => 'Ensure that data added to nodes by other modules appears in RSS feeds.',
580 'group' => 'Node',
581 );
582 }
583
584 function setUp() {
585 // Enable dummy module that implements hook_node_view.
586 parent::setUp('node_test');
587 }
588
589 /**
590 * Create a new node and ensure that it includes the custom data when added
591 * to an RSS feed.
592 */
593 function testNodeRSSContent() {
594 // Create a node.
595 $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
596
597 $this->drupalGet('rss.xml');
598
599 // Check that content added in 'rss' build mode appear in RSS feed.
600 $rss_only_content = t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->nid));
601 $this->assertText($rss_only_content, t('Node content designated for RSS appear in RSS feed.'));
602
603 // Check that content added in build modes other than 'rss' doesn't
604 // appear in RSS feed.
605 $non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->nid));
606 $this->assertNoText($non_rss_content, t('Node content not designed for RSS doesn\'t appear in RSS feed.'));
607
608 // Check that extra RSS elements and namespaces are added to RSS feed.
609 $test_element = array(
610 'key' => 'testElement',
611 'value' => t('Value of testElement RSS element for node !nid.', array('!nid' => $node->nid)),
612 );
613 $test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"';
614 $this->assertRaw(format_xml_elements(array($test_element)), t('Extra RSS elements appear in RSS feed.'));
615 $this->assertRaw($test_ns, t('Extra namespaces appear in RSS feed.'));
616
617 // Check that content added in 'rss' build mode doesn't appear when
618 // viewing node.
619 $this->drupalGet("node/$node->nid");
620 $this->assertNoText($rss_only_content, t('Node content designed for RSS doesn\'t appear when viewing node.'));
621 }
622 }
623
624 /**
625 * Test case to verify basic node_access functionality.
626 * @todo Cover hook_access in a separate test class.
627 * hook_node_access_records is covered in another test class.
628 */
629 class NodeAccessUnitTest extends DrupalWebTestCase {
630 public static function getInfo() {
631 return array(
632 'name' => 'Node access',
633 'description' => 'Test node_access function',
634 'group' => 'Node',
635 );
636 }
637
638 /**
639 * Asserts node_access correctly grants or denies access.
640 */
641 function assertNodeAccess($ops, $node, $account) {
642 foreach ($ops as $op => $result) {
643 $msg = t("node_access returns @result with operation '@op'.", array('@result' => $result ? 'true' : 'false', '@op' => $op));
644 $this->assertEqual($result, node_access($op, $node, $account), $msg);
645 }
646 }
647
648 function setUp() {
649 parent::setUp();
650 // Clear permissions for authenticated users.
651 db_delete('role_permission')
652 ->condition('rid', DRUPAL_AUTHENTICATED_RID)
653 ->execute();
654 }
655
656 /**
657 * Runs basic tests for node_access function.
658 */
659 function testNodeAccess() {
660 // Ensures user without 'access content' permission can do nothing.
661 $web_user1 = $this->drupalCreateUser(array('create page content', 'edit any page content', 'delete any page content'));
662 $node1 = $this->drupalCreateNode(array('type' => 'page'));
663 $this->assertNodeAccess(array('create' => FALSE), 'page', $web_user1);
664 $this->assertNodeAccess(array('view' => FALSE, 'update' => FALSE, 'delete' => FALSE), $node1, $web_user1);
665
666 // Ensures user with 'bypass node access' permission can do everything.
667 $web_user2 = $this->drupalCreateUser(array('bypass node access'));
668 $node2 = $this->drupalCreateNode(array('type' => 'page'));
669 $this->assertNodeAccess(array('create' => TRUE), 'page', $web_user2);
670 $this->assertNodeAccess(array('view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $node2, $web_user2);
671
672 // User cannot 'view own unpublished content'.
673 $web_user3 = $this->drupalCreateUser(array('access content'));
674 $node3 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user3->uid));
675 $this->assertNodeAccess(array('view' => FALSE), $node3, $web_user3);
676
677 // User can 'view own unpublished content', but another user cannot.
678 $web_user4 = $this->drupalCreateUser(array('access content', 'view own unpublished content'));
679 $web_user5 = $this->drupalCreateUser(array('access content', 'view own unpublished content'));
680 $node4 = $this->drupalCreateNode(array('status' => 0, 'uid' => $web_user4->uid));
681 $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE), $node4, $web_user4);
682 $this->assertNodeAccess(array('view' => FALSE), $node4, $web_user5);
683
684 // Tests the default access provided for a published node.
685 $node5 = $this->drupalCreateNode();
686 $this->assertNodeAccess(array('create' => FALSE), 'page', $web_user3);
687 $this->assertNodeAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE), $node5, $web_user3);
688 }
689 }
690
691 /**
692 * Test case to verify hook_node_access_records functionality.
693 */
694 class NodeAccessRecordsUnitTest extends DrupalWebTestCase {
695 public static function getInfo() {
696 return array(
697 'name' => 'Node access records',
698 'description' => 'Test hook_node_access_records when acquiring grants.',
699 'group' => 'Node',
700 );
701 }
702
703 function setUp() {
704 // Enable dummy module that implements hook_node_grants(),
705 // hook_node_access_records(), hook_node_grants_alter() and
706 // hook_node_access_records_alter().
707 parent::setUp('node_test');
708 }
709
710 /**
711 * Create a node and test the creation of node access rules.
712 */
713 function testNodeAccessRecords() {
714 // Create an article node.
715 $node1 = $this->drupalCreateNode(array('type' => 'article'));
716 $this->assertTrue(node_load($node1->nid), t('Article node created.'));
717
718 // Check to see if grants added by node_test_node_access_records made it in.
719 $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node1->nid))->fetchAll();
720 $this->assertEqual(count($records), 1, t('Returned the correct number of rows.'));
721 $this->assertEqual($records[0]->realm, 'test_article_realm', t('Grant with article_realm acquired for node without alteration.'));
722 $this->assertEqual($records[0]->gid, 1, t('Grant with gid = 1 acquired for node without alteration.'));
723
724 // Create an unpromoted page node.
725 $node2 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0));
726 $this->assertTrue(node_load($node1->nid), t('Unpromoted page node created.'));
727
728 // Check to see if grants added by node_test_node_access_records made it in.
729 $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node2->nid))->fetchAll();
730 $this->assertEqual(count($records), 1, t('Returned the correct number of rows.'));
731 $this->assertEqual($records[0]->realm, 'test_page_realm', t('Grant with page_realm acquired for node without alteration.'));
732 $this->assertEqual($records[0]->gid, 1, t('Grant with gid = 1 acquired for node without alteration.'));
733
734 // Create an unpromoted, unpublished page node.
735 $node3 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0, 'status' => 0));
736 $this->assertTrue(node_load($node3->nid), t('Unpromoted, unpublished page node created.'));
737
738 // Check to see if grants added by node_test_node_access_records made it in.
739 $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node3->nid))->fetchAll();
740 $this->assertEqual(count($records), 1, t('Returned the correct number of rows.'));
741 $this->assertEqual($records[0]->realm, 'test_page_realm', t('Grant with page_realm acquired for node without alteration.'));
742 $this->assertEqual($records[0]->gid, 1, t('Grant with gid = 1 acquired for node without alteration.'));
743
744 // Create a promoted page node.
745 $node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 1));
746 $this->assertTrue(node_load($node4->nid), t('Promoted page node created.'));
747
748 // Check to see if grant added by node_test_node_access_records was altered
749 // by node_test_node_access_records_alter.
750 $records = db_query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', array(':nid' => $node4->nid))->fetchAll();
751 $this->assertEqual(count($records), 1, t('Returned the correct number of rows.'));
752 $this->assertEqual($records[0]->realm, 'test_alter_realm', t('Altered grant with alter_realm acquired for node.'));
753 $this->assertEqual($records[0]->gid, 2, t('Altered grant with gid = 2 acquired for node.'));
754
755 // Check to see if we can alter grants with hook_node_grants_alter().
756 $operations = array('view', 'update', 'delete');
757 // Create a user that is allowed to access content.
758 $web_user = $this->drupalCreateUser(array('access content'));
759 foreach ($operations as $op) {
760 $grants = node_test_node_grants($op, $web_user);
761 $altered_grants = drupal_alter($grants, $web_user, $op);
762 $this->assertNotEqual($grants, $altered_grants, t('Altered the %op grant for a user.', array('%op' => $op)));
763 }
764 }
765 }
766
767 /**
768 * Test case to check node save related functionality, including import-save
769 */
770 class NodeSaveTestCase extends DrupalWebTestCase {
771
772 public static function getInfo() {
773 return array(
774 'name' => 'Node save',
775 'description' => 'Test node_save() for saving content.',
776 'group' => 'Node',
777 );
778 }
779
780 function setUp() {
781 parent::setUp();
782 // Create a user that is allowed to post; we'll use this to test the submission.
783 $web_user = $this->drupalCreateUser(array('create article content'));
784 $this->drupalLogin($web_user);
785 $this->web_user = $web_user;
786 }
787
788 /**
789 * Import test, to check if custom node ids are saved properly.
790 * Workflow:
791 * - first create a piece of content
792 * - save the content
793 * - check if node exists
794 */
795 function testImport() {
796 // Node ID must be a number that is not in the database.
797 $max_nid = db_query('SELECT MAX(nid) FROM {node}')->fetchField();
798 $test_nid = $max_nid + mt_rand(1000, 1000000);
799 $title = $this->randomName(8);
800 $node = array(
801 'title' => array(FIELD_LANGUAGE_NONE => array(array('value' => $title))),
802 'body' => array(FIELD_LANGUAGE_NONE => array(array('value' => $this->randomName(32)))),
803 'uid' => $this->web_user->uid,
804 'type' => 'article',
805 'nid' => $test_nid,
806 'is_new' => TRUE,
807 );
808 $node = (object)$node;
809 node_save($node);
810 // Test the import.
811 $node_by_nid = node_load($test_nid);
812 $this->assertTrue($node_by_nid, t('Node load by node ID.'));
813
814 $node_by_title = $this->drupalGetNodeByTitle($title);
815 $this->assertTrue($node_by_title, t('Node load by node title.'));
816 }
817 }
818
819 /**
820 * Tests related to node types.
821 */
822 class NodeTypeTestCase extends DrupalWebTestCase {
823 public static function getInfo() {
824 return array(
825 'name' => 'Node types',
826 'description' => 'Ensures that node type functions work correctly.',
827 'group' => 'Node',
828 );
829 }
830
831 /**
832 * Ensure that node type functions (node_type_get_*) work correctly.
833 *
834 * Load available node types and validate the returned data.
835 */
836 function testNodeTypeGetFunctions() {
837 $node_types = node_type_get_types();
838 $node_names = node_type_get_names();
839
840 $this->assertTrue(isset($node_types['article']), t('Node type article is available.'));
841 $this->assertTrue(isset($node_types['page']), t('Node type page is available.'));
842
843 $this->assertEqual($node_types['article']->name, $node_names['article'], t('Correct node type base has been returned.'));
844
845 $this->assertEqual($node_types['article'], node_type_get_type('article'), t('Correct node type has been returned.'));
846 $this->assertEqual($node_types['article']->name, node_type_get_name('article'), t('Correct node type name has been returned.'));
847 $this->assertEqual($node_types['page']->base, node_type_get_base('page'), t('Correct node type base has been returned.'));
848 }
849
850 /**
851 * Test creating a content type.
852 */
853 function testNodeTypeCreation() {
854 $type = $this->drupalCreateContentType();
855
856 $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $type->type))->fetchField();
857 $this->assertTrue($type_exists, 'The new content type has been created in the database.');
858
859 // Login a test user.
860 $web_user = $this->drupalCreateUser(array('create ' . $type->name . ' content'));
861 $this->drupalLogin($web_user);
862
863 $this->drupalGet('node/add/' . str_replace('_', '-', $type->name));
864 $this->assertResponse(200, 'The new content type can be accessed at node/add.');
865 }
866
867 /**
868 * Test editing a node type using the UI.
869 */
870 function testNodeTypeEditing() {
871 $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types'));
872 $this->drupalLogin($web_user);
873
874 $instance = field_info_instance('node', 'body', 'page');
875 $this->assertEqual($instance['label'], 'Body', t('Body field was found.'));
876
877 // Verify that title and body fields are displayed.
878 $this->drupalGet('node/add/page');
879 $this->assertRaw('Title', t('Title field was found.'));
880 $this->assertRaw('Full text', t('Body field was found.'));
881
882 // Rename the title field and remove the body field.
883 $edit = array(
884 'title_label' => 'Foo',
885 'body_label' => '',
886 );
887 $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
888 field_info_cache_clear();
889
890 $this->assertFalse(field_info_instance('node', 'body', 'page'), t('Body field was removed.'));
891 $this->drupalGet('node/add/page');
892 $this->assertRaw('Foo', t('New title label was displayed.'));
893 $this->assertNoRaw('Title', t('Old title label was not displayed.'));
894 $this->assertNoRaw('Full text', t('Body field was not found.'));
895
896 // Add the body field again and change the name, machine name and description.
897 $edit = array(
898 'name' => 'Bar',
899 'type' => 'bar',
900 'description' => 'Lorem ipsum.',
901 'body_label' => 'Baz',
902 );
903 $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
904 field_info_cache_clear();
905
906 $instance = field_info_instance('node', 'body', 'bar');
907 $this->assertEqual($instance['label'], 'Baz', t('Body field was added.'));
908 $this->drupalGet('node/add');
909 $this->assertRaw('Bar', t('New name was displayed.'));
910 $this->assertRaw('Lorem ipsum', t('New description was displayed.'));
911 $this->clickLink('Bar');
912 $this->assertEqual(url('node/add/bar', array('absolute' => TRUE)), $this->getUrl(), t('New machine name was used in URL.'));
913 $this->assertRaw('Foo', t('Title field was found.'));
914 $this->assertRaw('Full text', t('Body field was found.'));
915 }
916 }
917
918 /**
919 * Rebuild the node_access table.
920 */
921 class NodeAccessRebuildTestCase extends DrupalWebTestCase {
922 public static function getInfo() {
923 return array(
924 'name' => 'Node access rebuild',
925 'description' => 'Ensures that node access rebuild functions work correctly.',
926 'group' => 'Node',
927 );
928 }
929
930 function setUp() {
931 parent::setUp();
932
933 $web_user = $this->drupalCreateUser(array('administer site configuration', 'access administration pages', 'access site reports'));
934 $this->drupalLogin($web_user);
935 $this->web_user = $web_user;
936 }
937
938 function testNodeAccessRebuild() {
939 $this->drupalGet('admin/reports/status');
940 $this->clickLink(t('Rebuild permissions'));
941 $this->drupalPost(NULL, array(), t('Rebuild permissions'));
942 $this->assertText(t('Content permissions have been rebuilt.'));
943 }
944 }
945
946 /**
947 * Test node administration page functionality.
948 */
949 class NodeAdminTestCase extends DrupalWebTestCase {
950 protected $admin_user;
951
952 public static function getInfo() {
953 return array(
954 'name' => 'Node administration',
955 'description' => 'Test node administration page functionality.',
956 'group' => 'Node'
957 );
958 }
959
960 function setUp() {
961 parent::setUp();
962 $this->admin_user = $this->drupalCreateUser(array('administer nodes', 'create article content', 'create page content'));
963 $this->drupalLogin($this->admin_user);
964 }
965
966 /**
967 * Create 3 nodes and test if they are listed on the node admistration page.
968 */
969 function testNodeAdmin() {
970 $this->drupalPost('admin/content', array(), t('Update'));
971 $this->assertText(t('No items selected.'), t('Clicking update with no nodes displays error message on the node administration listing.'));
972
973 $node1 = $this->drupalCreateNode(array('type' => 'article', 'status' => 1));
974 $node2 = $this->drupalCreateNode(array('type' => 'article', 'status' => 0));
975 $node3 = $this->drupalCreateNode(array('type' => 'page'));
976
977 $this->drupalGet('admin/content');
978 $this->assertText($node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Node appears on the node administration listing.'));
979
980 $this->drupalPost('admin/content', array(), t('Update'));
981 $this->assertText(t('No items selected.'), t('Clicking update with no selected nodes displays error message on the node administration listing.'));
982
983 // Filter the node listing by status.
984 $edit = array(
985 'status' => 'status-1',
986 );
987 $this->drupalPost('admin/content', $edit, t('Filter'));
988 $this->assertRaw(t('<strong>%type</strong> is <strong>%value</strong>', array('%type' => t('status'), '%value' => t('published'))), t('The node administration listing is filtered by status.'));
989 $this->assertText($node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Published node appears on the node administration listing.'));
990 $this->assertNoText($node2->title[FIELD_LANGUAGE_NONE][0]['value'], t('Unpublished node does not appear on the node administration listing.'));
991
992 // Filter the node listing by content type.
993 $edit = array(
994 'type' => 'article',
995 );
996 $this->drupalPost('admin/content', $edit, t('Refine'));
997 $this->assertRaw(t('<strong>%type</strong> is <strong>%value</strong>', array('%type' => t('status'), '%value' => t('published'))), t('The node administration listing is filtered by status.'));
998 $this->assertRaw(t('<strong>%type</strong> is <strong>%value</strong>', array('%type' => t('type'), '%value' => 'Article')), t('The node administration listing is filtered by content type.'));
999 $this->assertText($node1->title[FIELD_LANGUAGE_NONE][0]['value'], t('Article node appears on the node administration listing.'));
1000 $this->assertNoText($node3->title[FIELD_LANGUAGE_NONE][0]['value'], t('Page node does not appear on the node administration listing.'));
1001 }
1002 }
1003
1004 /**
1005 * Test node title.
1006 */
1007 class NodeTitleTestCase extends DrupalWebTestCase {
1008 protected $admin_user;
1009
1010 public static function getInfo() {
1011 return array(
1012 'name' => 'Node title',
1013 'description' => 'Test node title.',
1014 'group' => 'Node'
1015 );
1016 }
1017
1018 function setUp() {
1019 parent::setUp();
1020 $this->admin_user = $this->drupalCreateUser(array('administer nodes', 'create article content', 'create page content'));
1021 $this->drupalLogin($this->admin_user);
1022 }
1023
1024 /**
1025 * Create one node and test if the node title has the correct value.
1026 */
1027 function testNodeTitle() {
1028 // Create page content with title
1029 $settings = array(
1030 'title' => array(FIELD_LANGUAGE_NONE => array(array('value' => $this->randomName(8)))),
1031 );
1032 $node = $this->drupalCreateNode($settings);
1033
1034 // Test <title> tag.
1035 $this->drupalGet("node/$node->nid");
1036 $xpath = '//title';
1037 $this->assertEqual(current($this->xpath($xpath)), $node->title[FIELD_LANGUAGE_NONE][0]['value'] .' | Drupal', 'Page title is equal to node title.', 'Node');
1038
1039 // Test breadcrumb in comment preview.
1040 $this->drupalGet("comment/reply/$node->nid");
1041 $xpath = '//div[@class="breadcrumb"]/a[last()]';
1042 $this->assertEqual(current($this->xpath($xpath)), $node->title[FIELD_LANGUAGE_NONE][0]['value'], 'Node breadcrumb is equal to node title.', '