|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Tests for comment.module. |
|
6 */ |
|
7 |
|
8 class CommentHelperCase extends DrupalWebTestCase { |
|
9 protected $admin_user; |
|
10 protected $web_user; |
|
11 protected $node; |
|
12 |
|
13 function setUp() { |
|
14 $modules = func_get_args(); |
|
15 if (isset($modules[0]) && is_array($modules[0])) { |
|
16 $modules = $modules[0]; |
|
17 } |
|
18 $modules[] = 'comment'; |
|
19 parent::setUp($modules); |
|
20 |
|
21 // Create users and test node. |
|
22 $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks', 'administer actions', 'administer fields')); |
|
23 $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments')); |
|
24 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid)); |
|
25 } |
|
26 |
|
27 /** |
|
28 * Post comment. |
|
29 * |
|
30 * @param $node |
|
31 * Node to post comment on. |
|
32 * @param $comment |
|
33 * Comment body. |
|
34 * @param $subject |
|
35 * Comment subject. |
|
36 * @param $contact |
|
37 * Set to NULL for no contact info, TRUE to ignore success checking, and |
|
38 * array of values to set contact info. |
|
39 */ |
|
40 function postComment($node, $comment, $subject = '', $contact = NULL) { |
|
41 $langcode = LANGUAGE_NONE; |
|
42 $edit = array(); |
|
43 $edit['comment_body[' . $langcode . '][0][value]'] = $comment; |
|
44 |
|
45 $preview_mode = variable_get('comment_preview_article', DRUPAL_OPTIONAL); |
|
46 $subject_mode = variable_get('comment_subject_field_article', 1); |
|
47 |
|
48 // Must get the page before we test for fields. |
|
49 if ($node !== NULL) { |
|
50 $this->drupalGet('comment/reply/' . $node->nid); |
|
51 } |
|
52 |
|
53 if ($subject_mode == TRUE) { |
|
54 $edit['subject'] = $subject; |
|
55 } |
|
56 else { |
|
57 $this->assertNoFieldByName('subject', '', 'Subject field not found.'); |
|
58 } |
|
59 |
|
60 if ($contact !== NULL && is_array($contact)) { |
|
61 $edit += $contact; |
|
62 } |
|
63 switch ($preview_mode) { |
|
64 case DRUPAL_REQUIRED: |
|
65 // Preview required so no save button should be found. |
|
66 $this->assertNoFieldByName('op', t('Save'), 'Save button not found.'); |
|
67 $this->drupalPost(NULL, $edit, t('Preview')); |
|
68 // Don't break here so that we can test post-preview field presence and |
|
69 // function below. |
|
70 case DRUPAL_OPTIONAL: |
|
71 $this->assertFieldByName('op', t('Preview'), 'Preview button found.'); |
|
72 $this->assertFieldByName('op', t('Save'), 'Save button found.'); |
|
73 $this->drupalPost(NULL, $edit, t('Save')); |
|
74 break; |
|
75 |
|
76 case DRUPAL_DISABLED: |
|
77 $this->assertNoFieldByName('op', t('Preview'), 'Preview button not found.'); |
|
78 $this->assertFieldByName('op', t('Save'), 'Save button found.'); |
|
79 $this->drupalPost(NULL, $edit, t('Save')); |
|
80 break; |
|
81 } |
|
82 $match = array(); |
|
83 // Get comment ID |
|
84 preg_match('/#comment-([0-9]+)/', $this->getURL(), $match); |
|
85 |
|
86 // Get comment. |
|
87 if ($contact !== TRUE) { // If true then attempting to find error message. |
|
88 if ($subject) { |
|
89 $this->assertText($subject, 'Comment subject posted.'); |
|
90 } |
|
91 $this->assertText($comment, 'Comment body posted.'); |
|
92 $this->assertTrue((!empty($match) && !empty($match[1])), 'Comment id found.'); |
|
93 } |
|
94 |
|
95 if (isset($match[1])) { |
|
96 return (object) array('id' => $match[1], 'subject' => $subject, 'comment' => $comment); |
|
97 } |
|
98 } |
|
99 |
|
100 /** |
|
101 * Checks current page for specified comment. |
|
102 * |
|
103 * @param object $comment Comment object. |
|
104 * @param boolean $reply The comment is a reply to another comment. |
|
105 * @return boolean Comment found. |
|
106 */ |
|
107 function commentExists($comment, $reply = FALSE) { |
|
108 if ($comment && is_object($comment)) { |
|
109 $regex = '/' . ($reply ? '<div class="indented">(.*?)' : ''); |
|
110 $regex .= '<a id="comment-' . $comment->id . '"(.*?)'; // Comment anchor. |
|
111 $regex .= '<div(.*?)'; // Begin in comment div. |
|
112 $regex .= $comment->subject . '(.*?)'; // Match subject. |
|
113 $regex .= $comment->comment . '(.*?)'; // Match comment. |
|
114 $regex .= '/s'; |
|
115 |
|
116 return (boolean)preg_match($regex, $this->drupalGetContent()); |
|
117 } |
|
118 else { |
|
119 return FALSE; |
|
120 } |
|
121 } |
|
122 |
|
123 /** |
|
124 * Delete comment. |
|
125 * |
|
126 * @param object $comment |
|
127 * Comment to delete. |
|
128 */ |
|
129 function deleteComment($comment) { |
|
130 $this->drupalPost('comment/' . $comment->id . '/delete', array(), t('Delete')); |
|
131 $this->assertText(t('The comment and all its replies have been deleted.'), 'Comment deleted.'); |
|
132 } |
|
133 |
|
134 /** |
|
135 * Set comment subject setting. |
|
136 * |
|
137 * @param boolean $enabled |
|
138 * Subject value. |
|
139 */ |
|
140 function setCommentSubject($enabled) { |
|
141 $this->setCommentSettings('comment_subject_field', ($enabled ? '1' : '0'), 'Comment subject ' . ($enabled ? 'enabled' : 'disabled') . '.'); |
|
142 } |
|
143 |
|
144 /** |
|
145 * Set comment preview setting. |
|
146 * |
|
147 * @param int $mode |
|
148 * Preview value. |
|
149 */ |
|
150 function setCommentPreview($mode) { |
|
151 switch ($mode) { |
|
152 case DRUPAL_DISABLED: |
|
153 $mode_text = 'disabled'; |
|
154 break; |
|
155 |
|
156 case DRUPAL_OPTIONAL: |
|
157 $mode_text = 'optional'; |
|
158 break; |
|
159 |
|
160 case DRUPAL_REQUIRED: |
|
161 $mode_text = 'required'; |
|
162 break; |
|
163 } |
|
164 $this->setCommentSettings('comment_preview', $mode, format_string('Comment preview @mode_text.', array('@mode_text' => $mode_text))); |
|
165 } |
|
166 |
|
167 /** |
|
168 * Set comment form location setting. |
|
169 * |
|
170 * @param boolean $enabled |
|
171 * Form value. |
|
172 */ |
|
173 function setCommentForm($enabled) { |
|
174 $this->setCommentSettings('comment_form_location', ($enabled ? COMMENT_FORM_BELOW : COMMENT_FORM_SEPARATE_PAGE), 'Comment controls ' . ($enabled ? 'enabled' : 'disabled') . '.'); |
|
175 } |
|
176 |
|
177 /** |
|
178 * Set comment anonymous level setting. |
|
179 * |
|
180 * @param integer $level |
|
181 * Anonymous level. |
|
182 */ |
|
183 function setCommentAnonymous($level) { |
|
184 $this->setCommentSettings('comment_anonymous', $level, format_string('Anonymous commenting set to level @level.', array('@level' => $level))); |
|
185 } |
|
186 |
|
187 /** |
|
188 * Set the default number of comments per page. |
|
189 * |
|
190 * @param integer $comments |
|
191 * Comments per page value. |
|
192 */ |
|
193 function setCommentsPerPage($number) { |
|
194 $this->setCommentSettings('comment_default_per_page', $number, format_string('Number of comments per page set to @number.', array('@number' => $number))); |
|
195 } |
|
196 |
|
197 /** |
|
198 * Set comment setting for article content type. |
|
199 * |
|
200 * @param string $name |
|
201 * Name of variable. |
|
202 * @param string $value |
|
203 * Value of variable. |
|
204 * @param string $message |
|
205 * Status message to display. |
|
206 */ |
|
207 function setCommentSettings($name, $value, $message) { |
|
208 variable_set($name . '_article', $value); |
|
209 // Display status message. |
|
210 $this->pass($message); |
|
211 } |
|
212 |
|
213 /** |
|
214 * Check for contact info. |
|
215 * |
|
216 * @return boolean Contact info is available. |
|
217 */ |
|
218 function commentContactInfoAvailable() { |
|
219 return preg_match('/(input).*?(name="name").*?(input).*?(name="mail").*?(input).*?(name="homepage")/s', $this->drupalGetContent()); |
|
220 } |
|
221 |
|
222 /** |
|
223 * Perform the specified operation on the specified comment. |
|
224 * |
|
225 * @param object $comment |
|
226 * Comment to perform operation on. |
|
227 * @param string $operation |
|
228 * Operation to perform. |
|
229 * @param boolean $aproval |
|
230 * Operation is found on approval page. |
|
231 */ |
|
232 function performCommentOperation($comment, $operation, $approval = FALSE) { |
|
233 $edit = array(); |
|
234 $edit['operation'] = $operation; |
|
235 $edit['comments[' . $comment->id . ']'] = TRUE; |
|
236 $this->drupalPost('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update')); |
|
237 |
|
238 if ($operation == 'delete') { |
|
239 $this->drupalPost(NULL, array(), t('Delete comments')); |
|
240 $this->assertRaw(format_plural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation @operation was performed on comment.', array('@operation' => $operation))); |
|
241 } |
|
242 else { |
|
243 $this->assertText(t('The update has been performed.'), format_string('Operation @operation was performed on comment.', array('@operation' => $operation))); |
|
244 } |
|
245 } |
|
246 |
|
247 /** |
|
248 * Get the comment ID for an unapproved comment. |
|
249 * |
|
250 * @param string $subject |
|
251 * Comment subject to find. |
|
252 * @return integer |
|
253 * Comment id. |
|
254 */ |
|
255 function getUnapprovedComment($subject) { |
|
256 $this->drupalGet('admin/content/comment/approval'); |
|
257 preg_match('/href="(.*?)#comment-([^"]+)"(.*?)>(' . $subject . ')/', $this->drupalGetContent(), $match); |
|
258 |
|
259 return $match[2]; |
|
260 } |
|
261 } |
|
262 |
|
263 class CommentInterfaceTest extends CommentHelperCase { |
|
264 public static function getInfo() { |
|
265 return array( |
|
266 'name' => 'Comment interface', |
|
267 'description' => 'Test comment user interfaces.', |
|
268 'group' => 'Comment', |
|
269 ); |
|
270 } |
|
271 |
|
272 /** |
|
273 * Test comment interface. |
|
274 */ |
|
275 function testCommentInterface() { |
|
276 $langcode = LANGUAGE_NONE; |
|
277 // Set comments to have subject and preview disabled. |
|
278 $this->drupalLogin($this->admin_user); |
|
279 $this->setCommentPreview(DRUPAL_DISABLED); |
|
280 $this->setCommentForm(TRUE); |
|
281 $this->setCommentSubject(FALSE); |
|
282 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
283 $this->drupalLogout(); |
|
284 |
|
285 // Post comment #1 without subject or preview. |
|
286 $this->drupalLogin($this->web_user); |
|
287 $comment_text = $this->randomName(); |
|
288 $comment = $this->postComment($this->node, $comment_text); |
|
289 $comment_loaded = comment_load($comment->id); |
|
290 $this->assertTrue($this->commentExists($comment), 'Comment found.'); |
|
291 |
|
292 // Set comments to have subject and preview to required. |
|
293 $this->drupalLogout(); |
|
294 $this->drupalLogin($this->admin_user); |
|
295 $this->setCommentSubject(TRUE); |
|
296 $this->setCommentPreview(DRUPAL_REQUIRED); |
|
297 $this->drupalLogout(); |
|
298 |
|
299 // Create comment #2 that allows subject and requires preview. |
|
300 $this->drupalLogin($this->web_user); |
|
301 $subject_text = $this->randomName(); |
|
302 $comment_text = $this->randomName(); |
|
303 $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE); |
|
304 $comment_loaded = comment_load($comment->id); |
|
305 $this->assertTrue($this->commentExists($comment), 'Comment found.'); |
|
306 |
|
307 // Check comment display. |
|
308 $this->drupalGet('node/' . $this->node->nid . '/' . $comment->id); |
|
309 $this->assertText($subject_text, 'Individual comment subject found.'); |
|
310 $this->assertText($comment_text, 'Individual comment body found.'); |
|
311 |
|
312 // Set comments to have subject and preview to optional. |
|
313 $this->drupalLogout(); |
|
314 $this->drupalLogin($this->admin_user); |
|
315 $this->setCommentSubject(TRUE); |
|
316 $this->setCommentPreview(DRUPAL_OPTIONAL); |
|
317 |
|
318 // Test changing the comment author to "Anonymous". |
|
319 $this->drupalGet('comment/' . $comment->id . '/edit'); |
|
320 $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => '')); |
|
321 $comment_loaded = comment_load($comment->id); |
|
322 $this->assertTrue(empty($comment_loaded->name) && $comment_loaded->uid == 0, 'Comment author successfully changed to anonymous.'); |
|
323 |
|
324 // Test changing the comment author to an unverified user. |
|
325 $random_name = $this->randomName(); |
|
326 $this->drupalGet('comment/' . $comment->id . '/edit'); |
|
327 $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => $random_name)); |
|
328 $this->drupalGet('node/' . $this->node->nid); |
|
329 $this->assertText($random_name . ' (' . t('not verified') . ')', 'Comment author successfully changed to an unverified user.'); |
|
330 |
|
331 // Test changing the comment author to a verified user. |
|
332 $this->drupalGet('comment/' . $comment->id . '/edit'); |
|
333 $comment = $this->postComment(NULL, $comment->comment, $comment->subject, array('name' => $this->web_user->name)); |
|
334 $comment_loaded = comment_load($comment->id); |
|
335 $this->assertTrue($comment_loaded->name == $this->web_user->name && $comment_loaded->uid == $this->web_user->uid, 'Comment author successfully changed to a registered user.'); |
|
336 |
|
337 $this->drupalLogout(); |
|
338 |
|
339 // Reply to comment #2 creating comment #3 with optional preview and no |
|
340 // subject though field enabled. |
|
341 $this->drupalLogin($this->web_user); |
|
342 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
343 $this->assertText($subject_text, 'Individual comment-reply subject found.'); |
|
344 $this->assertText($comment_text, 'Individual comment-reply body found.'); |
|
345 $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); |
|
346 $reply_loaded = comment_load($reply->id); |
|
347 $this->assertTrue($this->commentExists($reply, TRUE), 'Reply found.'); |
|
348 $this->assertEqual($comment->id, $reply_loaded->pid, 'Pid of a reply to a comment is set correctly.'); |
|
349 $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.00/', $reply_loaded->thread, 'Thread of reply grows correctly.'); |
|
350 |
|
351 // Second reply to comment #3 creating comment #4. |
|
352 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
353 $this->assertText($subject_text, 'Individual comment-reply subject found.'); |
|
354 $this->assertText($comment_text, 'Individual comment-reply body found.'); |
|
355 $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
356 $reply_loaded = comment_load($reply->id); |
|
357 $this->assertTrue($this->commentExists($reply, TRUE), 'Second reply found.'); |
|
358 $this->assertEqual(rtrim($comment_loaded->thread, '/') . '.01/', $reply_loaded->thread, 'Thread of second reply grows correctly.'); |
|
359 |
|
360 // Edit reply. |
|
361 $this->drupalGet('comment/' . $reply->id . '/edit'); |
|
362 $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
363 $this->assertTrue($this->commentExists($reply, TRUE), 'Modified reply found.'); |
|
364 |
|
365 // Correct link count |
|
366 $this->drupalGet('node'); |
|
367 $this->assertRaw('4 comments', 'Link to the 4 comments exist.'); |
|
368 |
|
369 // Confirm a new comment is posted to the correct page. |
|
370 $this->setCommentsPerPage(2); |
|
371 $comment_new_page = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE); |
|
372 $this->assertTrue($this->commentExists($comment_new_page), 'Page one exists. %s'); |
|
373 $this->drupalGet('node/' . $this->node->nid, array('query' => array('page' => 1))); |
|
374 $this->assertTrue($this->commentExists($reply, TRUE), 'Page two exists. %s'); |
|
375 $this->setCommentsPerPage(50); |
|
376 |
|
377 // Attempt to post to node with comments disabled. |
|
378 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_HIDDEN)); |
|
379 $this->assertTrue($this->node, 'Article node created.'); |
|
380 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
381 $this->assertText('This discussion is closed', 'Posting to node with comments disabled'); |
|
382 $this->assertNoField('edit-comment', 'Comment body field found.'); |
|
383 |
|
384 // Attempt to post to node with read-only comments. |
|
385 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_CLOSED)); |
|
386 $this->assertTrue($this->node, 'Article node created.'); |
|
387 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
388 $this->assertText('This discussion is closed', 'Posting to node with comments read-only'); |
|
389 $this->assertNoField('edit-comment', 'Comment body field found.'); |
|
390 |
|
391 // Attempt to post to node with comments enabled (check field names etc). |
|
392 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN)); |
|
393 $this->assertTrue($this->node, 'Article node created.'); |
|
394 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
395 $this->assertNoText('This discussion is closed', 'Posting to node with comments enabled'); |
|
396 $this->assertField('edit-comment-body-' . $langcode . '-0-value', 'Comment body field found.'); |
|
397 |
|
398 // Delete comment and make sure that reply is also removed. |
|
399 $this->drupalLogout(); |
|
400 $this->drupalLogin($this->admin_user); |
|
401 $this->deleteComment($comment); |
|
402 $this->deleteComment($comment_new_page); |
|
403 |
|
404 $this->drupalGet('node/' . $this->node->nid); |
|
405 $this->assertFalse($this->commentExists($comment), 'Comment not found.'); |
|
406 $this->assertFalse($this->commentExists($reply, TRUE), 'Reply not found.'); |
|
407 |
|
408 // Enabled comment form on node page. |
|
409 $this->drupalLogin($this->admin_user); |
|
410 $this->setCommentForm(TRUE); |
|
411 $this->drupalLogout(); |
|
412 |
|
413 // Submit comment through node form. |
|
414 $this->drupalLogin($this->web_user); |
|
415 $this->drupalGet('node/' . $this->node->nid); |
|
416 $form_comment = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
417 $this->assertTrue($this->commentExists($form_comment), 'Form comment found.'); |
|
418 |
|
419 // Disable comment form on node page. |
|
420 $this->drupalLogout(); |
|
421 $this->drupalLogin($this->admin_user); |
|
422 $this->setCommentForm(FALSE); |
|
423 } |
|
424 |
|
425 /** |
|
426 * Tests new comment marker. |
|
427 */ |
|
428 public function testCommentNewCommentsIndicator() { |
|
429 // Test if the right links are displayed when no comment is present for the |
|
430 // node. |
|
431 $this->drupalLogin($this->admin_user); |
|
432 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN)); |
|
433 $this->drupalGet('node'); |
|
434 $this->assertNoLink(t('@count comments', array('@count' => 0))); |
|
435 $this->assertNoLink(t('@count new comments', array('@count' => 0))); |
|
436 $this->assertLink(t('Read more')); |
|
437 $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper')); |
|
438 $this->assertTrue(count($count) == 1, 'One child found'); |
|
439 |
|
440 // Create a new comment. This helper function may be run with different |
|
441 // comment settings so use comment_save() to avoid complex setup. |
|
442 $comment = (object) array( |
|
443 'cid' => NULL, |
|
444 'nid' => $this->node->nid, |
|
445 'node_type' => $this->node->type, |
|
446 'pid' => 0, |
|
447 'uid' => $this->loggedInUser->uid, |
|
448 'status' => COMMENT_PUBLISHED, |
|
449 'subject' => $this->randomName(), |
|
450 'hostname' => ip_address(), |
|
451 'language' => LANGUAGE_NONE, |
|
452 'comment_body' => array(LANGUAGE_NONE => array($this->randomName())), |
|
453 ); |
|
454 comment_save($comment); |
|
455 $this->drupalLogout(); |
|
456 |
|
457 // Log in with 'web user' and check comment links. |
|
458 $this->drupalLogin($this->web_user); |
|
459 $this->drupalGet('node'); |
|
460 $this->assertLink(t('1 new comment')); |
|
461 $this->clickLink(t('1 new comment')); |
|
462 $this->assertRaw('<a id="new"></a>', 'Found "new" marker.'); |
|
463 $this->assertTrue($this->xpath('//a[@id=:new]/following-sibling::a[1][@id=:comment_id]', array(':new' => 'new', ':comment_id' => 'comment-1')), 'The "new" anchor is positioned at the right comment.'); |
|
464 |
|
465 // Test if "new comment" link is correctly removed. |
|
466 $this->drupalGet('node'); |
|
467 $this->assertLink(t('1 comment')); |
|
468 $this->assertLink(t('Read more')); |
|
469 $this->assertNoLink(t('1 new comment')); |
|
470 $this->assertNoLink(t('@count new comments', array('@count' => 0))); |
|
471 $count = $this->xpath('//div[@id=:id]/div[@class=:class]/ul/li', array(':id' => 'node-' . $this->node->nid, ':class' => 'link-wrapper')); |
|
472 $this->assertTrue(count($count) == 2, print_r($count, TRUE)); |
|
473 } |
|
474 |
|
475 /** |
|
476 * Tests CSS classes on comments. |
|
477 */ |
|
478 function testCommentClasses() { |
|
479 // Create all permutations for comments, users, and nodes. |
|
480 $parameters = array( |
|
481 'node_uid' => array(0, $this->web_user->uid), |
|
482 'comment_uid' => array(0, $this->web_user->uid, $this->admin_user->uid), |
|
483 'comment_status' => array(COMMENT_PUBLISHED, COMMENT_NOT_PUBLISHED), |
|
484 'user' => array('anonymous', 'authenticated', 'admin'), |
|
485 ); |
|
486 $permutations = $this->generatePermutations($parameters); |
|
487 |
|
488 foreach ($permutations as $case) { |
|
489 // Create a new node. |
|
490 $node = $this->drupalCreateNode(array('type' => 'article', 'uid' => $case['node_uid'])); |
|
491 |
|
492 // Add a comment. |
|
493 $comment = (object) array( |
|
494 'cid' => NULL, |
|
495 'nid' => $node->nid, |
|
496 'pid' => 0, |
|
497 'uid' => $case['comment_uid'], |
|
498 'status' => $case['comment_status'], |
|
499 'subject' => $this->randomName(), |
|
500 'language' => LANGUAGE_NONE, |
|
501 'comment_body' => array(LANGUAGE_NONE => array($this->randomName())), |
|
502 ); |
|
503 comment_save($comment); |
|
504 |
|
505 // Adjust the current/viewing user. |
|
506 switch ($case['user']) { |
|
507 case 'anonymous': |
|
508 $this->drupalLogout(); |
|
509 $case['user_uid'] = 0; |
|
510 break; |
|
511 |
|
512 case 'authenticated': |
|
513 $this->drupalLogin($this->web_user); |
|
514 $case['user_uid'] = $this->web_user->uid; |
|
515 break; |
|
516 |
|
517 case 'admin': |
|
518 $this->drupalLogin($this->admin_user); |
|
519 $case['user_uid'] = $this->admin_user->uid; |
|
520 break; |
|
521 } |
|
522 // Request the node with the comment. |
|
523 $this->drupalGet('node/' . $node->nid); |
|
524 |
|
525 // Verify classes if the comment is visible for the current user. |
|
526 if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') { |
|
527 // Verify the comment-by-anonymous class. |
|
528 $comments = $this->xpath('//*[contains(@class, "comment-by-anonymous")]'); |
|
529 if ($case['comment_uid'] == 0) { |
|
530 $this->assertTrue(count($comments) == 1, 'comment-by-anonymous class found.'); |
|
531 } |
|
532 else { |
|
533 $this->assertFalse(count($comments), 'comment-by-anonymous class not found.'); |
|
534 } |
|
535 |
|
536 // Verify the comment-by-node-author class. |
|
537 $comments = $this->xpath('//*[contains(@class, "comment-by-node-author")]'); |
|
538 if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['node_uid']) { |
|
539 $this->assertTrue(count($comments) == 1, 'comment-by-node-author class found.'); |
|
540 } |
|
541 else { |
|
542 $this->assertFalse(count($comments), 'comment-by-node-author class not found.'); |
|
543 } |
|
544 |
|
545 // Verify the comment-by-viewer class. |
|
546 $comments = $this->xpath('//*[contains(@class, "comment-by-viewer")]'); |
|
547 if ($case['comment_uid'] > 0 && $case['comment_uid'] == $case['user_uid']) { |
|
548 $this->assertTrue(count($comments) == 1, 'comment-by-viewer class found.'); |
|
549 } |
|
550 else { |
|
551 $this->assertFalse(count($comments), 'comment-by-viewer class not found.'); |
|
552 } |
|
553 } |
|
554 |
|
555 // Verify the comment-unpublished class. |
|
556 $comments = $this->xpath('//*[contains(@class, "comment-unpublished")]'); |
|
557 if ($case['comment_status'] == COMMENT_NOT_PUBLISHED && $case['user'] == 'admin') { |
|
558 $this->assertTrue(count($comments) == 1, 'comment-unpublished class found.'); |
|
559 } |
|
560 else { |
|
561 $this->assertFalse(count($comments), 'comment-unpublished class not found.'); |
|
562 } |
|
563 |
|
564 // Verify the comment-new class. |
|
565 if ($case['comment_status'] == COMMENT_PUBLISHED || $case['user'] == 'admin') { |
|
566 $comments = $this->xpath('//*[contains(@class, "comment-new")]'); |
|
567 if ($case['user'] != 'anonymous') { |
|
568 $this->assertTrue(count($comments) == 1, 'comment-new class found.'); |
|
569 |
|
570 // Request the node again. The comment-new class should disappear. |
|
571 $this->drupalGet('node/' . $node->nid); |
|
572 $comments = $this->xpath('//*[contains(@class, "comment-new")]'); |
|
573 $this->assertFalse(count($comments), 'comment-new class not found.'); |
|
574 } |
|
575 else { |
|
576 $this->assertFalse(count($comments), 'comment-new class not found.'); |
|
577 } |
|
578 } |
|
579 } |
|
580 } |
|
581 |
|
582 /** |
|
583 * Tests the node comment statistics. |
|
584 */ |
|
585 function testCommentNodeCommentStatistics() { |
|
586 $langcode = LANGUAGE_NONE; |
|
587 // Set comments to have subject and preview disabled. |
|
588 $this->drupalLogin($this->admin_user); |
|
589 $this->setCommentPreview(DRUPAL_DISABLED); |
|
590 $this->setCommentForm(TRUE); |
|
591 $this->setCommentSubject(FALSE); |
|
592 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
593 $this->drupalLogout(); |
|
594 |
|
595 // Creates a second user to post comments. |
|
596 $this->web_user2 = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments')); |
|
597 |
|
598 // Checks the initial values of node comment statistics with no comment. |
|
599 $node = node_load($this->node->nid); |
|
600 $this->assertEqual($node->last_comment_timestamp, $this->node->created, 'The initial value of node last_comment_timestamp is the node created date.'); |
|
601 $this->assertEqual($node->last_comment_name, NULL, 'The initial value of node last_comment_name is NULL.'); |
|
602 $this->assertEqual($node->last_comment_uid, $this->web_user->uid, 'The initial value of node last_comment_uid is the node uid.'); |
|
603 $this->assertEqual($node->comment_count, 0, 'The initial value of node comment_count is zero.'); |
|
604 |
|
605 // Post comment #1 as web_user2. |
|
606 $this->drupalLogin($this->web_user2); |
|
607 $comment_text = $this->randomName(); |
|
608 $comment = $this->postComment($this->node, $comment_text); |
|
609 $comment_loaded = comment_load($comment->id); |
|
610 |
|
611 // Checks the new values of node comment statistics with comment #1. |
|
612 // The node needs to be reloaded with a node_load_multiple cache reset. |
|
613 $node = node_load($this->node->nid, NULL, TRUE); |
|
614 $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is NULL.'); |
|
615 $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is the comment #1 uid.'); |
|
616 $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is 1.'); |
|
617 |
|
618 // Prepare for anonymous comment submission (comment approval enabled). |
|
619 variable_set('user_register', USER_REGISTER_VISITORS); |
|
620 $this->drupalLogin($this->admin_user); |
|
621 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
622 'access comments' => TRUE, |
|
623 'post comments' => TRUE, |
|
624 'skip comment approval' => FALSE, |
|
625 )); |
|
626 // Ensure that the poster can leave some contact info. |
|
627 $this->setCommentAnonymous('1'); |
|
628 $this->drupalLogout(); |
|
629 |
|
630 // Post comment #2 as anonymous (comment approval enabled). |
|
631 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
632 $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', TRUE); |
|
633 $comment_unpublished_loaded = comment_load($anonymous_comment->id); |
|
634 |
|
635 // Checks the new values of node comment statistics with comment #2 and |
|
636 // ensure they haven't changed since the comment has not been moderated. |
|
637 // The node needs to be reloaded with a node_load_multiple cache reset. |
|
638 $node = node_load($this->node->nid, NULL, TRUE); |
|
639 $this->assertEqual($node->last_comment_name, NULL, 'The value of node last_comment_name is still NULL.'); |
|
640 $this->assertEqual($node->last_comment_uid, $this->web_user2->uid, 'The value of node last_comment_uid is still the comment #1 uid.'); |
|
641 $this->assertEqual($node->comment_count, 1, 'The value of node comment_count is still 1.'); |
|
642 |
|
643 // Prepare for anonymous comment submission (no approval required). |
|
644 $this->drupalLogin($this->admin_user); |
|
645 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
646 'access comments' => TRUE, |
|
647 'post comments' => TRUE, |
|
648 'skip comment approval' => TRUE, |
|
649 )); |
|
650 $this->drupalLogout(); |
|
651 |
|
652 // Post comment #3 as anonymous. |
|
653 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
654 $anonymous_comment = $this->postComment($this->node, $this->randomName(), '', array('name' => $this->randomName())); |
|
655 $comment_loaded = comment_load($anonymous_comment->id); |
|
656 |
|
657 // Checks the new values of node comment statistics with comment #3. |
|
658 // The node needs to be reloaded with a node_load_multiple cache reset. |
|
659 $node = node_load($this->node->nid, NULL, TRUE); |
|
660 $this->assertEqual($node->last_comment_name, $comment_loaded->name, 'The value of node last_comment_name is the name of the anonymous user.'); |
|
661 $this->assertEqual($node->last_comment_uid, 0, 'The value of node last_comment_uid is zero.'); |
|
662 $this->assertEqual($node->comment_count, 2, 'The value of node comment_count is 2.'); |
|
663 } |
|
664 |
|
665 /** |
|
666 * Tests comment links. |
|
667 * |
|
668 * The output of comment links depends on various environment conditions: |
|
669 * - Various Comment module configuration settings, user registration |
|
670 * settings, and user access permissions. |
|
671 * - Whether the user is authenticated or not, and whether any comments exist. |
|
672 * |
|
673 * To account for all possible cases, this test creates permutations of all |
|
674 * possible conditions and tests the expected appearance of comment links in |
|
675 * each environment. |
|
676 */ |
|
677 function testCommentLinks() { |
|
678 // Bartik theme alters comment links, so use a different theme. |
|
679 theme_enable(array('garland')); |
|
680 variable_set('theme_default', 'garland'); |
|
681 |
|
682 // Remove additional user permissions from $this->web_user added by setUp(), |
|
683 // since this test is limited to anonymous and authenticated roles only. |
|
684 user_role_delete(key($this->web_user->roles)); |
|
685 |
|
686 // Matrix of possible environmental conditions and configuration settings. |
|
687 // See setEnvironment() for details. |
|
688 $conditions = array( |
|
689 'authenticated' => array(FALSE, TRUE), |
|
690 'comment count' => array(FALSE, TRUE), |
|
691 'access comments' => array(0, 1), |
|
692 'post comments' => array(0, 1), |
|
693 'form' => array(COMMENT_FORM_BELOW, COMMENT_FORM_SEPARATE_PAGE), |
|
694 // USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL is irrelevant for this |
|
695 // test; there is only a difference between open and closed registration. |
|
696 'user_register' => array(USER_REGISTER_VISITORS, USER_REGISTER_ADMINISTRATORS_ONLY), |
|
697 // @todo Complete test coverage for: |
|
698 //'comments' => array(COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, COMMENT_NODE_HIDDEN), |
|
699 //// COMMENT_ANONYMOUS_MUST_CONTACT is irrelevant for this test. |
|
700 //'contact ' => array(COMMENT_ANONYMOUS_MAY_CONTACT, COMMENT_ANONYMOUS_MAYNOT_CONTACT), |
|
701 ); |
|
702 |
|
703 $environments = $this->generatePermutations($conditions); |
|
704 foreach ($environments as $info) { |
|
705 $this->assertCommentLinks($info); |
|
706 } |
|
707 } |
|
708 |
|
709 /** |
|
710 * Re-configures the environment, module settings, and user permissions. |
|
711 * |
|
712 * @param $info |
|
713 * An associative array describing the environment to setup: |
|
714 * - Environment conditions: |
|
715 * - authenticated: Boolean whether to test with $this->web_user or |
|
716 * anonymous. |
|
717 * - comment count: Boolean whether to test with a new/unread comment on |
|
718 * $this->node or no comments. |
|
719 * - Configuration settings: |
|
720 * - form: COMMENT_FORM_BELOW or COMMENT_FORM_SEPARATE_PAGE. |
|
721 * - user_register: USER_REGISTER_ADMINISTRATORS_ONLY or |
|
722 * USER_REGISTER_VISITORS. |
|
723 * - contact: COMMENT_ANONYMOUS_MAY_CONTACT or |
|
724 * COMMENT_ANONYMOUS_MAYNOT_CONTACT. |
|
725 * - comments: COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, or |
|
726 * COMMENT_NODE_HIDDEN. |
|
727 * - User permissions: |
|
728 * These are granted or revoked for the user, according to the |
|
729 * 'authenticated' flag above. Pass 0 or 1 as parameter values. See |
|
730 * user_role_change_permissions(). |
|
731 * - access comments |
|
732 * - post comments |
|
733 * - skip comment approval |
|
734 * - edit own comments |
|
735 */ |
|
736 function setEnvironment(array $info) { |
|
737 static $current; |
|
738 |
|
739 // Apply defaults to initial environment. |
|
740 if (!isset($current)) { |
|
741 $current = array( |
|
742 'authenticated' => FALSE, |
|
743 'comment count' => FALSE, |
|
744 'form' => COMMENT_FORM_BELOW, |
|
745 'user_register' => USER_REGISTER_VISITORS, |
|
746 'contact' => COMMENT_ANONYMOUS_MAY_CONTACT, |
|
747 'comments' => COMMENT_NODE_OPEN, |
|
748 'access comments' => 0, |
|
749 'post comments' => 0, |
|
750 // Enabled by default, because it's irrelevant for this test. |
|
751 'skip comment approval' => 1, |
|
752 'edit own comments' => 0, |
|
753 ); |
|
754 } |
|
755 // Complete new environment with current environment. |
|
756 $info = array_merge($current, $info); |
|
757 |
|
758 // Change environment conditions. |
|
759 if ($current['authenticated'] != $info['authenticated']) { |
|
760 if ($this->loggedInUser) { |
|
761 $this->drupalLogout(); |
|
762 } |
|
763 else { |
|
764 $this->drupalLogin($this->web_user); |
|
765 } |
|
766 } |
|
767 if ($current['comment count'] != $info['comment count']) { |
|
768 if ($info['comment count']) { |
|
769 // Create a comment via CRUD API functionality, since |
|
770 // $this->postComment() relies on actual user permissions. |
|
771 $comment = (object) array( |
|
772 'cid' => NULL, |
|
773 'nid' => $this->node->nid, |
|
774 'node_type' => $this->node->type, |
|
775 'pid' => 0, |
|
776 'uid' => 0, |
|
777 'status' => COMMENT_PUBLISHED, |
|
778 'subject' => $this->randomName(), |
|
779 'hostname' => ip_address(), |
|
780 'language' => LANGUAGE_NONE, |
|
781 'comment_body' => array(LANGUAGE_NONE => array($this->randomName())), |
|
782 ); |
|
783 comment_save($comment); |
|
784 $this->comment = $comment; |
|
785 |
|
786 // comment_num_new() relies on node_last_viewed(), so ensure that no one |
|
787 // has seen the node of this comment. |
|
788 db_delete('history')->condition('nid', $this->node->nid)->execute(); |
|
789 } |
|
790 else { |
|
791 $cids = db_query("SELECT cid FROM {comment}")->fetchCol(); |
|
792 comment_delete_multiple($cids); |
|
793 unset($this->comment); |
|
794 } |
|
795 } |
|
796 |
|
797 // Change comment settings. |
|
798 variable_set('comment_form_location_' . $this->node->type, $info['form']); |
|
799 variable_set('comment_anonymous_' . $this->node->type, $info['contact']); |
|
800 if ($this->node->comment != $info['comments']) { |
|
801 $this->node->comment = $info['comments']; |
|
802 node_save($this->node); |
|
803 } |
|
804 |
|
805 // Change user settings. |
|
806 variable_set('user_register', $info['user_register']); |
|
807 |
|
808 // Change user permissions. |
|
809 $rid = ($this->loggedInUser ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID); |
|
810 $perms = array_intersect_key($info, array('access comments' => 1, 'post comments' => 1, 'skip comment approval' => 1, 'edit own comments' => 1)); |
|
811 user_role_change_permissions($rid, $perms); |
|
812 |
|
813 // Output verbose debugging information. |
|
814 // @see DrupalTestCase::error() |
|
815 $t_form = array( |
|
816 COMMENT_FORM_BELOW => 'below', |
|
817 COMMENT_FORM_SEPARATE_PAGE => 'separate page', |
|
818 ); |
|
819 $t_contact = array( |
|
820 COMMENT_ANONYMOUS_MAY_CONTACT => 'optional', |
|
821 COMMENT_ANONYMOUS_MAYNOT_CONTACT => 'disabled', |
|
822 COMMENT_ANONYMOUS_MUST_CONTACT => 'required', |
|
823 ); |
|
824 $t_comments = array( |
|
825 COMMENT_NODE_OPEN => 'open', |
|
826 COMMENT_NODE_CLOSED => 'closed', |
|
827 COMMENT_NODE_HIDDEN => 'hidden', |
|
828 ); |
|
829 $verbose = $info; |
|
830 $verbose['form'] = $t_form[$info['form']]; |
|
831 $verbose['contact'] = $t_contact[$info['contact']]; |
|
832 $verbose['comments'] = $t_comments[$info['comments']]; |
|
833 $message = t('Changed environment:<pre>@verbose</pre>', array( |
|
834 '@verbose' => var_export($verbose, TRUE), |
|
835 )); |
|
836 $this->assert('debug', $message, 'Debug'); |
|
837 |
|
838 // Update current environment. |
|
839 $current = $info; |
|
840 |
|
841 return $info; |
|
842 } |
|
843 |
|
844 /** |
|
845 * Asserts that comment links appear according to the passed environment setup. |
|
846 * |
|
847 * @param $info |
|
848 * An associative array describing the environment to pass to |
|
849 * setEnvironment(). |
|
850 */ |
|
851 function assertCommentLinks(array $info) { |
|
852 $info = $this->setEnvironment($info); |
|
853 |
|
854 $nid = $this->node->nid; |
|
855 |
|
856 foreach (array('', "node/$nid") as $path) { |
|
857 $this->drupalGet($path); |
|
858 |
|
859 // User is allowed to view comments. |
|
860 if ($info['access comments']) { |
|
861 if ($path == '') { |
|
862 // In teaser view, a link containing the comment count is always |
|
863 // expected. |
|
864 if ($info['comment count']) { |
|
865 $this->assertLink(t('1 comment')); |
|
866 |
|
867 // For logged in users, a link containing the amount of new/unread |
|
868 // comments is expected. |
|
869 // See important note about comment_num_new() below. |
|
870 if ($this->loggedInUser && isset($this->comment) && !isset($this->comment->seen)) { |
|
871 $this->assertLink(t('1 new comment')); |
|
872 $this->comment->seen = TRUE; |
|
873 } |
|
874 } |
|
875 } |
|
876 } |
|
877 else { |
|
878 $this->assertNoLink(t('1 comment')); |
|
879 $this->assertNoLink(t('1 new comment')); |
|
880 } |
|
881 // comment_num_new() is based on node views, so comments are marked as |
|
882 // read when a node is viewed, regardless of whether we have access to |
|
883 // comments. |
|
884 if ($path == "node/$nid" && $this->loggedInUser && isset($this->comment)) { |
|
885 $this->comment->seen = TRUE; |
|
886 } |
|
887 |
|
888 // User is not allowed to post comments. |
|
889 if (!$info['post comments']) { |
|
890 $this->assertNoLink('Add new comment'); |
|
891 |
|
892 // Anonymous users should see a note to log in or register in case |
|
893 // authenticated users are allowed to post comments. |
|
894 // @see theme_comment_post_forbidden() |
|
895 if (!$this->loggedInUser) { |
|
896 if (user_access('post comments', $this->web_user)) { |
|
897 // The note depends on whether users are actually able to register. |
|
898 if ($info['user_register']) { |
|
899 $this->assertText('Log in or register to post comments'); |
|
900 } |
|
901 else { |
|
902 $this->assertText('Log in to post comments'); |
|
903 } |
|
904 } |
|
905 else { |
|
906 $this->assertNoText('Log in or register to post comments'); |
|
907 $this->assertNoText('Log in to post comments'); |
|
908 } |
|
909 } |
|
910 } |
|
911 // User is allowed to post comments. |
|
912 else { |
|
913 $this->assertNoText('Log in or register to post comments'); |
|
914 |
|
915 // "Add new comment" is always expected, except when there are no |
|
916 // comments or if the user cannot see them. |
|
917 if ($path == "node/$nid" && $info['form'] == COMMENT_FORM_BELOW && (!$info['comment count'] || !$info['access comments'])) { |
|
918 $this->assertNoLink('Add new comment'); |
|
919 } |
|
920 else { |
|
921 $this->assertLink('Add new comment'); |
|
922 } |
|
923 |
|
924 // Also verify that the comment form appears according to the configured |
|
925 // location. |
|
926 if ($path == "node/$nid") { |
|
927 $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form')); |
|
928 if ($info['form'] == COMMENT_FORM_BELOW) { |
|
929 $this->assertTrue(count($elements), 'Comment form found below.'); |
|
930 } |
|
931 else { |
|
932 $this->assertFalse(count($elements), 'Comment form not found below.'); |
|
933 } |
|
934 } |
|
935 } |
|
936 } |
|
937 } |
|
938 } |
|
939 |
|
940 /** |
|
941 * Test previewing comments. |
|
942 */ |
|
943 class CommentPreviewTest extends CommentHelperCase { |
|
944 public static function getInfo() { |
|
945 return array( |
|
946 'name' => 'Comment preview', |
|
947 'description' => 'Test comment preview.', |
|
948 'group' => 'Comment', |
|
949 ); |
|
950 } |
|
951 |
|
952 /** |
|
953 * Test comment preview. |
|
954 */ |
|
955 function testCommentPreview() { |
|
956 $langcode = LANGUAGE_NONE; |
|
957 |
|
958 // As admin user, configure comment settings. |
|
959 $this->drupalLogin($this->admin_user); |
|
960 $this->setCommentPreview(DRUPAL_OPTIONAL); |
|
961 $this->setCommentForm(TRUE); |
|
962 $this->setCommentSubject(TRUE); |
|
963 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
964 $this->drupalLogout(); |
|
965 |
|
966 // Login as web user and add a signature and a user picture. |
|
967 $this->drupalLogin($this->web_user); |
|
968 variable_set('user_signatures', 1); |
|
969 variable_set('user_pictures', 1); |
|
970 $test_signature = $this->randomName(); |
|
971 $edit['signature[value]'] = '<a href="http://example.com/">' . $test_signature. '</a>'; |
|
972 $edit['signature[format]'] = 'filtered_html'; |
|
973 $image = current($this->drupalGetTestFiles('image')); |
|
974 $edit['files[picture_upload]'] = drupal_realpath($image->uri); |
|
975 $this->drupalPost('user/' . $this->web_user->uid . '/edit', $edit, t('Save')); |
|
976 |
|
977 // As the web user, fill in the comment form and preview the comment. |
|
978 $edit = array(); |
|
979 $edit['subject'] = $this->randomName(8); |
|
980 $edit['comment_body[' . $langcode . '][0][value]'] = $this->randomName(16); |
|
981 $this->drupalPost('node/' . $this->node->nid, $edit, t('Preview')); |
|
982 |
|
983 // Check that the preview is displaying the title and body. |
|
984 $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".'); |
|
985 $this->assertText($edit['subject'], 'Subject displayed.'); |
|
986 $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], 'Comment displayed.'); |
|
987 |
|
988 // Check that the title and body fields are displayed with the correct values. |
|
989 $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.'); |
|
990 $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.'); |
|
991 |
|
992 // Check that the signature is displaying with the correct text format. |
|
993 $this->assertLink($test_signature); |
|
994 |
|
995 // Check that the user picture is displayed. |
|
996 $this->assertFieldByXPath("//div[contains(@class, 'comment-preview')]//div[contains(@class, 'user-picture')]//img", NULL, 'User picture displayed.'); |
|
997 } |
|
998 |
|
999 /** |
|
1000 * Test comment edit, preview, and save. |
|
1001 */ |
|
1002 function testCommentEditPreviewSave() { |
|
1003 $langcode = LANGUAGE_NONE; |
|
1004 $web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'skip comment approval')); |
|
1005 $this->drupalLogin($this->admin_user); |
|
1006 $this->setCommentPreview(DRUPAL_OPTIONAL); |
|
1007 $this->setCommentForm(TRUE); |
|
1008 $this->setCommentSubject(TRUE); |
|
1009 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
1010 |
|
1011 $edit = array(); |
|
1012 $edit['subject'] = $this->randomName(8); |
|
1013 $edit['comment_body[' . $langcode . '][0][value]'] = $this->randomName(16); |
|
1014 $edit['name'] = $web_user->name; |
|
1015 $edit['date'] = '2008-03-02 17:23 +0300'; |
|
1016 $raw_date = strtotime($edit['date']); |
|
1017 $expected_text_date = format_date($raw_date); |
|
1018 $expected_form_date = format_date($raw_date, 'custom', 'Y-m-d H:i O'); |
|
1019 $comment = $this->postComment($this->node, $edit['subject'], $edit['comment_body[' . $langcode . '][0][value]'], TRUE); |
|
1020 $this->drupalPost('comment/' . $comment->id . '/edit', $edit, t('Preview')); |
|
1021 |
|
1022 // Check that the preview is displaying the subject, comment, author and date correctly. |
|
1023 $this->assertTitle(t('Preview comment | Drupal'), 'Page title is "Preview comment".'); |
|
1024 $this->assertText($edit['subject'], 'Subject displayed.'); |
|
1025 $this->assertText($edit['comment_body[' . $langcode . '][0][value]'], 'Comment displayed.'); |
|
1026 $this->assertText($edit['name'], 'Author displayed.'); |
|
1027 $this->assertText($expected_text_date, 'Date displayed.'); |
|
1028 |
|
1029 // Check that the subject, comment, author and date fields are displayed with the correct values. |
|
1030 $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.'); |
|
1031 $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.'); |
|
1032 $this->assertFieldByName('name', $edit['name'], 'Author field displayed.'); |
|
1033 $this->assertFieldByName('date', $edit['date'], 'Date field displayed.'); |
|
1034 |
|
1035 // Check that saving a comment produces a success message. |
|
1036 $this->drupalPost('comment/' . $comment->id . '/edit', $edit, t('Save')); |
|
1037 $this->assertText(t('Your comment has been posted.'), 'Comment posted.'); |
|
1038 |
|
1039 // Check that the comment fields are correct after loading the saved comment. |
|
1040 $this->drupalGet('comment/' . $comment->id . '/edit'); |
|
1041 $this->assertFieldByName('subject', $edit['subject'], 'Subject field displayed.'); |
|
1042 $this->assertFieldByName('comment_body[' . $langcode . '][0][value]', $edit['comment_body[' . $langcode . '][0][value]'], 'Comment field displayed.'); |
|
1043 $this->assertFieldByName('name', $edit['name'], 'Author field displayed.'); |
|
1044 $this->assertFieldByName('date', $expected_form_date, 'Date field displayed.'); |
|
1045 |
|
1046 // Submit the form using the displayed values. |
|
1047 $displayed = array(); |
|
1048 $displayed['subject'] = (string) current($this->xpath("//input[@id='edit-subject']/@value")); |
|
1049 $displayed['comment_body[' . $langcode . '][0][value]'] = (string) current($this->xpath("//textarea[@id='edit-comment-body-" . $langcode . "-0-value']")); |
|
1050 $displayed['name'] = (string) current($this->xpath("//input[@id='edit-name']/@value")); |
|
1051 $displayed['date'] = (string) current($this->xpath("//input[@id='edit-date']/@value")); |
|
1052 $this->drupalPost('comment/' . $comment->id . '/edit', $displayed, t('Save')); |
|
1053 |
|
1054 // Check that the saved comment is still correct. |
|
1055 $comment_loaded = comment_load($comment->id); |
|
1056 $this->assertEqual($comment_loaded->subject, $edit['subject'], 'Subject loaded.'); |
|
1057 $this->assertEqual($comment_loaded->comment_body[$langcode][0]['value'], $edit['comment_body[' . $langcode . '][0][value]'], 'Comment body loaded.'); |
|
1058 $this->assertEqual($comment_loaded->name, $edit['name'], 'Name loaded.'); |
|
1059 $this->assertEqual($comment_loaded->created, $raw_date, 'Date loaded.'); |
|
1060 |
|
1061 } |
|
1062 |
|
1063 } |
|
1064 |
|
1065 class CommentAnonymous extends CommentHelperCase { |
|
1066 public static function getInfo() { |
|
1067 return array( |
|
1068 'name' => 'Anonymous comments', |
|
1069 'description' => 'Test anonymous comments.', |
|
1070 'group' => 'Comment', |
|
1071 ); |
|
1072 } |
|
1073 |
|
1074 function setUp() { |
|
1075 parent::setUp(); |
|
1076 variable_set('user_register', USER_REGISTER_VISITORS); |
|
1077 } |
|
1078 |
|
1079 /** |
|
1080 * Test anonymous comment functionality. |
|
1081 */ |
|
1082 function testAnonymous() { |
|
1083 $this->drupalLogin($this->admin_user); |
|
1084 // Enabled anonymous user comments. |
|
1085 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1086 'access comments' => TRUE, |
|
1087 'post comments' => TRUE, |
|
1088 'skip comment approval' => TRUE, |
|
1089 )); |
|
1090 $this->setCommentAnonymous('0'); // Ensure that doesn't require contact info. |
|
1091 $this->drupalLogout(); |
|
1092 |
|
1093 // Post anonymous comment without contact info. |
|
1094 $anonymous_comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1095 $this->assertTrue($this->commentExists($anonymous_comment1), 'Anonymous comment without contact info found.'); |
|
1096 |
|
1097 // Allow contact info. |
|
1098 $this->drupalLogin($this->admin_user); |
|
1099 $this->setCommentAnonymous('1'); |
|
1100 |
|
1101 // Attempt to edit anonymous comment. |
|
1102 $this->drupalGet('comment/' . $anonymous_comment1->id . '/edit'); |
|
1103 $edited_comment = $this->postComment(NULL, $this->randomName(), $this->randomName()); |
|
1104 $this->assertTrue($this->commentExists($edited_comment, FALSE), 'Modified reply found.'); |
|
1105 $this->drupalLogout(); |
|
1106 |
|
1107 // Post anonymous comment with contact info (optional). |
|
1108 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
1109 $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.'); |
|
1110 |
|
1111 $anonymous_comment2 = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1112 $this->assertTrue($this->commentExists($anonymous_comment2), 'Anonymous comment with contact info (optional) found.'); |
|
1113 |
|
1114 // Ensure anonymous users cannot post in the name of registered users. |
|
1115 $langcode = LANGUAGE_NONE; |
|
1116 $edit = array( |
|
1117 'name' => $this->admin_user->name, |
|
1118 'mail' => $this->randomName() . '@example.com', |
|
1119 'subject' => $this->randomName(), |
|
1120 "comment_body[$langcode][0][value]" => $this->randomName(), |
|
1121 ); |
|
1122 $this->drupalPost('comment/reply/' . $this->node->nid, $edit, t('Save')); |
|
1123 $this->assertText(t('The name you used belongs to a registered user.')); |
|
1124 |
|
1125 // Require contact info. |
|
1126 $this->drupalLogin($this->admin_user); |
|
1127 $this->setCommentAnonymous('2'); |
|
1128 $this->drupalLogout(); |
|
1129 |
|
1130 // Try to post comment with contact info (required). |
|
1131 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
1132 $this->assertTrue($this->commentContactInfoAvailable(), 'Contact information available.'); |
|
1133 |
|
1134 $anonymous_comment3 = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE); |
|
1135 // Name should have 'Anonymous' for value by default. |
|
1136 $this->assertText(t('E-mail field is required.'), 'E-mail required.'); |
|
1137 $this->assertFalse($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) not found.'); |
|
1138 |
|
1139 // Post comment with contact info (required). |
|
1140 $author_name = $this->randomName(); |
|
1141 $author_mail = $this->randomName() . '@example.com'; |
|
1142 $anonymous_comment3 = $this->postComment($this->node, $this->randomName(), $this->randomName(), array('name' => $author_name, 'mail' => $author_mail)); |
|
1143 $this->assertTrue($this->commentExists($anonymous_comment3), 'Anonymous comment with contact info (required) found.'); |
|
1144 |
|
1145 // Make sure the user data appears correctly when editing the comment. |
|
1146 $this->drupalLogin($this->admin_user); |
|
1147 $this->drupalGet('comment/' . $anonymous_comment3->id . '/edit'); |
|
1148 $this->assertRaw($author_name, "The anonymous user's name is correct when editing the comment."); |
|
1149 $this->assertRaw($author_mail, "The anonymous user's e-mail address is correct when editing the comment."); |
|
1150 |
|
1151 // Unpublish comment. |
|
1152 $this->performCommentOperation($anonymous_comment3, 'unpublish'); |
|
1153 |
|
1154 $this->drupalGet('admin/content/comment/approval'); |
|
1155 $this->assertRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was unpublished.'); |
|
1156 |
|
1157 // Publish comment. |
|
1158 $this->performCommentOperation($anonymous_comment3, 'publish', TRUE); |
|
1159 |
|
1160 $this->drupalGet('admin/content/comment'); |
|
1161 $this->assertRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was published.'); |
|
1162 |
|
1163 // Delete comment. |
|
1164 $this->performCommentOperation($anonymous_comment3, 'delete'); |
|
1165 |
|
1166 $this->drupalGet('admin/content/comment'); |
|
1167 $this->assertNoRaw('comments[' . $anonymous_comment3->id . ']', 'Comment was deleted.'); |
|
1168 $this->drupalLogout(); |
|
1169 |
|
1170 // Reset. |
|
1171 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1172 'access comments' => FALSE, |
|
1173 'post comments' => FALSE, |
|
1174 'skip comment approval' => FALSE, |
|
1175 )); |
|
1176 |
|
1177 // Attempt to view comments while disallowed. |
|
1178 // NOTE: if authenticated user has permission to post comments, then a |
|
1179 // "Login or register to post comments" type link may be shown. |
|
1180 $this->drupalGet('node/' . $this->node->nid); |
|
1181 $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); |
|
1182 $this->assertNoLink('Add new comment', 'Link to add comment was found.'); |
|
1183 |
|
1184 // Attempt to view node-comment form while disallowed. |
|
1185 $this->drupalGet('comment/reply/' . $this->node->nid); |
|
1186 $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.'); |
|
1187 $this->assertNoFieldByName('subject', '', 'Subject field not found.'); |
|
1188 $this->assertNoFieldByName("comment_body[$langcode][0][value]", '', 'Comment field not found.'); |
|
1189 |
|
1190 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1191 'access comments' => TRUE, |
|
1192 'post comments' => FALSE, |
|
1193 'skip comment approval' => FALSE, |
|
1194 )); |
|
1195 $this->drupalGet('node/' . $this->node->nid); |
|
1196 $this->assertPattern('@<h2[^>]*>Comments</h2>@', 'Comments were displayed.'); |
|
1197 $this->assertLink('Log in', 1, 'Link to log in was found.'); |
|
1198 $this->assertLink('register', 1, 'Link to register was found.'); |
|
1199 |
|
1200 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1201 'access comments' => FALSE, |
|
1202 'post comments' => TRUE, |
|
1203 'skip comment approval' => TRUE, |
|
1204 )); |
|
1205 $this->drupalGet('node/' . $this->node->nid); |
|
1206 $this->assertNoPattern('@<h2[^>]*>Comments</h2>@', 'Comments were not displayed.'); |
|
1207 $this->assertFieldByName('subject', '', 'Subject field found.'); |
|
1208 $this->assertFieldByName("comment_body[$langcode][0][value]", '', 'Comment field found.'); |
|
1209 |
|
1210 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $anonymous_comment3->id); |
|
1211 $this->assertText('You are not authorized to view comments', 'Error attempting to post reply.'); |
|
1212 $this->assertNoText($author_name, 'Comment not displayed.'); |
|
1213 } |
|
1214 } |
|
1215 |
|
1216 /** |
|
1217 * Verify pagination of comments. |
|
1218 */ |
|
1219 class CommentPagerTest extends CommentHelperCase { |
|
1220 |
|
1221 public static function getInfo() { |
|
1222 return array( |
|
1223 'name' => 'Comment paging settings', |
|
1224 'description' => 'Test paging of comments and their settings.', |
|
1225 'group' => 'Comment', |
|
1226 ); |
|
1227 } |
|
1228 |
|
1229 /** |
|
1230 * Confirm comment paging works correctly with flat and threaded comments. |
|
1231 */ |
|
1232 function testCommentPaging() { |
|
1233 $this->drupalLogin($this->admin_user); |
|
1234 |
|
1235 // Set comment variables. |
|
1236 $this->setCommentForm(TRUE); |
|
1237 $this->setCommentSubject(TRUE); |
|
1238 $this->setCommentPreview(DRUPAL_DISABLED); |
|
1239 |
|
1240 // Create a node and three comments. |
|
1241 $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); |
|
1242 $comments = array(); |
|
1243 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1244 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1245 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1246 |
|
1247 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.'); |
|
1248 |
|
1249 // Set comments to one per page so that we are able to test paging without |
|
1250 // needing to insert large numbers of comments. |
|
1251 $this->setCommentsPerPage(1); |
|
1252 |
|
1253 // Check the first page of the node, and confirm the correct comments are |
|
1254 // shown. |
|
1255 $this->drupalGet('node/' . $node->nid); |
|
1256 $this->assertRaw(t('next'), 'Paging links found.'); |
|
1257 $this->assertTrue($this->commentExists($comments[0]), 'Comment 1 appears on page 1.'); |
|
1258 $this->assertFalse($this->commentExists($comments[1]), 'Comment 2 does not appear on page 1.'); |
|
1259 $this->assertFalse($this->commentExists($comments[2]), 'Comment 3 does not appear on page 1.'); |
|
1260 |
|
1261 // Check the second page. |
|
1262 $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 1))); |
|
1263 $this->assertTrue($this->commentExists($comments[1]), 'Comment 2 appears on page 2.'); |
|
1264 $this->assertFalse($this->commentExists($comments[0]), 'Comment 1 does not appear on page 2.'); |
|
1265 $this->assertFalse($this->commentExists($comments[2]), 'Comment 3 does not appear on page 2.'); |
|
1266 |
|
1267 // Check the third page. |
|
1268 $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 2))); |
|
1269 $this->assertTrue($this->commentExists($comments[2]), 'Comment 3 appears on page 3.'); |
|
1270 $this->assertFalse($this->commentExists($comments[0]), 'Comment 1 does not appear on page 3.'); |
|
1271 $this->assertFalse($this->commentExists($comments[1]), 'Comment 2 does not appear on page 3.'); |
|
1272 |
|
1273 // Post a reply to the oldest comment and test again. |
|
1274 $replies = array(); |
|
1275 $oldest_comment = reset($comments); |
|
1276 $this->drupalGet('comment/reply/' . $node->nid . '/' . $oldest_comment->id); |
|
1277 $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1278 |
|
1279 $this->setCommentsPerPage(2); |
|
1280 // We are still in flat view - the replies should not be on the first page, |
|
1281 // even though they are replies to the oldest comment. |
|
1282 $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0))); |
|
1283 $this->assertFalse($this->commentExists($reply, TRUE), 'In flat mode, reply does not appear on page 1.'); |
|
1284 |
|
1285 // If we switch to threaded mode, the replies on the oldest comment |
|
1286 // should be bumped to the first page and comment 6 should be bumped |
|
1287 // to the second page. |
|
1288 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.'); |
|
1289 $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0))); |
|
1290 $this->assertTrue($this->commentExists($reply, TRUE), 'In threaded mode, reply appears on page 1.'); |
|
1291 $this->assertFalse($this->commentExists($comments[1]), 'In threaded mode, comment 2 has been bumped off of page 1.'); |
|
1292 |
|
1293 // If (# replies > # comments per page) in threaded expanded view, |
|
1294 // the overage should be bumped. |
|
1295 $reply2 = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1296 $this->drupalGet('node/' . $node->nid, array('query' => array('page' => 0))); |
|
1297 $this->assertFalse($this->commentExists($reply2, TRUE), 'In threaded mode where # replies > # comments per page, the newest reply does not appear on page 1.'); |
|
1298 |
|
1299 $this->drupalLogout(); |
|
1300 } |
|
1301 |
|
1302 /** |
|
1303 * Test comment ordering and threading. |
|
1304 */ |
|
1305 function testCommentOrderingThreading() { |
|
1306 $this->drupalLogin($this->admin_user); |
|
1307 |
|
1308 // Set comment variables. |
|
1309 $this->setCommentForm(TRUE); |
|
1310 $this->setCommentSubject(TRUE); |
|
1311 $this->setCommentPreview(DRUPAL_DISABLED); |
|
1312 |
|
1313 // Display all the comments on the same page. |
|
1314 $this->setCommentsPerPage(1000); |
|
1315 |
|
1316 // Create a node and three comments. |
|
1317 $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); |
|
1318 $comments = array(); |
|
1319 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1320 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1321 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1322 |
|
1323 // Post a reply to the second comment. |
|
1324 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[1]->id); |
|
1325 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1326 |
|
1327 // Post a reply to the first comment. |
|
1328 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[0]->id); |
|
1329 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1330 |
|
1331 // Post a reply to the last comment. |
|
1332 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[2]->id); |
|
1333 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1334 |
|
1335 // Post a reply to the second comment. |
|
1336 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[3]->id); |
|
1337 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1338 |
|
1339 // At this point, the comment tree is: |
|
1340 // - 0 |
|
1341 // - 4 |
|
1342 // - 1 |
|
1343 // - 3 |
|
1344 // - 6 |
|
1345 // - 2 |
|
1346 // - 5 |
|
1347 |
|
1348 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.'); |
|
1349 |
|
1350 $expected_order = array( |
|
1351 0, |
|
1352 1, |
|
1353 2, |
|
1354 3, |
|
1355 4, |
|
1356 5, |
|
1357 6, |
|
1358 ); |
|
1359 $this->drupalGet('node/' . $node->nid); |
|
1360 $this->assertCommentOrder($comments, $expected_order); |
|
1361 |
|
1362 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.'); |
|
1363 |
|
1364 $expected_order = array( |
|
1365 0, |
|
1366 4, |
|
1367 1, |
|
1368 3, |
|
1369 6, |
|
1370 2, |
|
1371 5, |
|
1372 ); |
|
1373 $this->drupalGet('node/' . $node->nid); |
|
1374 $this->assertCommentOrder($comments, $expected_order); |
|
1375 } |
|
1376 |
|
1377 /** |
|
1378 * Helper function: assert that the comments are displayed in the correct order. |
|
1379 * |
|
1380 * @param $comments |
|
1381 * And array of comments. |
|
1382 * @param $expected_order |
|
1383 * An array of keys from $comments describing the expected order. |
|
1384 */ |
|
1385 function assertCommentOrder(array $comments, array $expected_order) { |
|
1386 $expected_cids = array(); |
|
1387 |
|
1388 // First, rekey the expected order by cid. |
|
1389 foreach ($expected_order as $key) { |
|
1390 $expected_cids[] = $comments[$key]->id; |
|
1391 } |
|
1392 |
|
1393 $comment_anchors = $this->xpath('//a[starts-with(@id,"comment-")]'); |
|
1394 $result_order = array(); |
|
1395 foreach ($comment_anchors as $anchor) { |
|
1396 $result_order[] = substr($anchor['id'], 8); |
|
1397 } |
|
1398 |
|
1399 return $this->assertIdentical($expected_cids, $result_order, format_string('Comment order: expected @expected, returned @returned.', array('@expected' => implode(',', $expected_cids), '@returned' => implode(',', $result_order)))); |
|
1400 } |
|
1401 |
|
1402 /** |
|
1403 * Test comment_new_page_count(). |
|
1404 */ |
|
1405 function testCommentNewPageIndicator() { |
|
1406 $this->drupalLogin($this->admin_user); |
|
1407 |
|
1408 // Set comment variables. |
|
1409 $this->setCommentForm(TRUE); |
|
1410 $this->setCommentSubject(TRUE); |
|
1411 $this->setCommentPreview(DRUPAL_DISABLED); |
|
1412 |
|
1413 // Set comments to one per page so that we are able to test paging without |
|
1414 // needing to insert large numbers of comments. |
|
1415 $this->setCommentsPerPage(1); |
|
1416 |
|
1417 // Create a node and three comments. |
|
1418 $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); |
|
1419 $comments = array(); |
|
1420 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1421 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1422 $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1423 |
|
1424 // Post a reply to the second comment. |
|
1425 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[1]->id); |
|
1426 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1427 |
|
1428 // Post a reply to the first comment. |
|
1429 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[0]->id); |
|
1430 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1431 |
|
1432 // Post a reply to the last comment. |
|
1433 $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[2]->id); |
|
1434 $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
1435 |
|
1436 // At this point, the comment tree is: |
|
1437 // - 0 |
|
1438 // - 4 |
|
1439 // - 1 |
|
1440 // - 3 |
|
1441 // - 2 |
|
1442 // - 5 |
|
1443 |
|
1444 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, 'Comment paging changed.'); |
|
1445 |
|
1446 $expected_pages = array( |
|
1447 1 => 5, // Page of comment 5 |
|
1448 2 => 4, // Page of comment 4 |
|
1449 3 => 3, // Page of comment 3 |
|
1450 4 => 2, // Page of comment 2 |
|
1451 5 => 1, // Page of comment 1 |
|
1452 6 => 0, // Page of comment 0 |
|
1453 ); |
|
1454 |
|
1455 $node = node_load($node->nid); |
|
1456 foreach ($expected_pages as $new_replies => $expected_page) { |
|
1457 $returned = comment_new_page_count($node->comment_count, $new_replies, $node); |
|
1458 $returned_page = is_array($returned) ? $returned['page'] : 0; |
|
1459 $this->assertIdentical($expected_page, $returned_page, format_string('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page))); |
|
1460 } |
|
1461 |
|
1462 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Switched to threaded mode.'); |
|
1463 |
|
1464 $expected_pages = array( |
|
1465 1 => 5, // Page of comment 5 |
|
1466 2 => 1, // Page of comment 4 |
|
1467 3 => 1, // Page of comment 4 |
|
1468 4 => 1, // Page of comment 4 |
|
1469 5 => 1, // Page of comment 4 |
|
1470 6 => 0, // Page of comment 0 |
|
1471 ); |
|
1472 |
|
1473 $node = node_load($node->nid); |
|
1474 foreach ($expected_pages as $new_replies => $expected_page) { |
|
1475 $returned = comment_new_page_count($node->comment_count, $new_replies, $node); |
|
1476 $returned_page = is_array($returned) ? $returned['page'] : 0; |
|
1477 $this->assertEqual($expected_page, $returned_page, format_string('Threaded mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page))); |
|
1478 } |
|
1479 } |
|
1480 } |
|
1481 |
|
1482 /** |
|
1483 * Tests comments with node access. |
|
1484 * |
|
1485 * See http://drupal.org/node/886752 -- verify there is no PostgreSQL error when |
|
1486 * viewing a node with threaded comments (a comment and a reply), if a node |
|
1487 * access module is in use. |
|
1488 */ |
|
1489 class CommentNodeAccessTest extends CommentHelperCase { |
|
1490 public static function getInfo() { |
|
1491 return array( |
|
1492 'name' => 'Comment node access', |
|
1493 'description' => 'Test comment viewing with node access.', |
|
1494 'group' => 'Comment', |
|
1495 ); |
|
1496 } |
|
1497 |
|
1498 function setUp() { |
|
1499 parent::setUp('search', 'node_access_test'); |
|
1500 node_access_rebuild(); |
|
1501 |
|
1502 // Create users and test node. |
|
1503 $this->admin_user = $this->drupalCreateUser(array('administer content types', 'administer comments', 'administer blocks')); |
|
1504 $this->web_user = $this->drupalCreateUser(array('access comments', 'post comments', 'create article content', 'edit own comments', 'node test view')); |
|
1505 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid)); |
|
1506 } |
|
1507 |
|
1508 /** |
|
1509 * Test that threaded comments can be viewed. |
|
1510 */ |
|
1511 function testThreadedCommentView() { |
|
1512 $langcode = LANGUAGE_NONE; |
|
1513 // Set comments to have subject required and preview disabled. |
|
1514 $this->drupalLogin($this->admin_user); |
|
1515 $this->setCommentPreview(DRUPAL_DISABLED); |
|
1516 $this->setCommentForm(TRUE); |
|
1517 $this->setCommentSubject(TRUE); |
|
1518 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
1519 $this->drupalLogout(); |
|
1520 |
|
1521 // Post comment. |
|
1522 $this->drupalLogin($this->web_user); |
|
1523 $comment_text = $this->randomName(); |
|
1524 $comment_subject = $this->randomName(); |
|
1525 $comment = $this->postComment($this->node, $comment_text, $comment_subject); |
|
1526 $comment_loaded = comment_load($comment->id); |
|
1527 $this->assertTrue($this->commentExists($comment), 'Comment found.'); |
|
1528 |
|
1529 // Check comment display. |
|
1530 $this->drupalGet('node/' . $this->node->nid . '/' . $comment->id); |
|
1531 $this->assertText($comment_subject, 'Individual comment subject found.'); |
|
1532 $this->assertText($comment_text, 'Individual comment body found.'); |
|
1533 |
|
1534 // Reply to comment, creating second comment. |
|
1535 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
1536 $reply_text = $this->randomName(); |
|
1537 $reply_subject = $this->randomName(); |
|
1538 $reply = $this->postComment(NULL, $reply_text, $reply_subject, TRUE); |
|
1539 $reply_loaded = comment_load($reply->id); |
|
1540 $this->assertTrue($this->commentExists($reply, TRUE), 'Reply found.'); |
|
1541 |
|
1542 // Go to the node page and verify comment and reply are visible. |
|
1543 $this->drupalGet('node/' . $this->node->nid); |
|
1544 $this->assertText($comment_text); |
|
1545 $this->assertText($comment_subject); |
|
1546 $this->assertText($reply_text); |
|
1547 $this->assertText($reply_subject); |
|
1548 } |
|
1549 } |
|
1550 |
|
1551 class CommentApprovalTest extends CommentHelperCase { |
|
1552 public static function getInfo() { |
|
1553 return array( |
|
1554 'name' => 'Comment approval', |
|
1555 'description' => 'Test comment approval functionality.', |
|
1556 'group' => 'Comment', |
|
1557 ); |
|
1558 } |
|
1559 |
|
1560 /** |
|
1561 * Test comment approval functionality through admin/content/comment. |
|
1562 */ |
|
1563 function testApprovalAdminInterface() { |
|
1564 // Set anonymous comments to require approval. |
|
1565 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1566 'access comments' => TRUE, |
|
1567 'post comments' => TRUE, |
|
1568 'skip comment approval' => FALSE, |
|
1569 )); |
|
1570 $this->drupalLogin($this->admin_user); |
|
1571 $this->setCommentAnonymous('0'); // Ensure that doesn't require contact info. |
|
1572 |
|
1573 // Test that the comments page loads correctly when there are no comments |
|
1574 $this->drupalGet('admin/content/comment'); |
|
1575 $this->assertText(t('No comments available.')); |
|
1576 |
|
1577 $this->drupalLogout(); |
|
1578 |
|
1579 // Post anonymous comment without contact info. |
|
1580 $subject = $this->randomName(); |
|
1581 $body = $this->randomName(); |
|
1582 $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message. |
|
1583 $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.'); |
|
1584 |
|
1585 // Get unapproved comment id. |
|
1586 $this->drupalLogin($this->admin_user); |
|
1587 $anonymous_comment4 = $this->getUnapprovedComment($subject); |
|
1588 $anonymous_comment4 = (object) array('id' => $anonymous_comment4, 'subject' => $subject, 'comment' => $body); |
|
1589 $this->drupalLogout(); |
|
1590 |
|
1591 $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.'); |
|
1592 |
|
1593 // Approve comment. |
|
1594 $this->drupalLogin($this->admin_user); |
|
1595 $this->performCommentOperation($anonymous_comment4, 'publish', TRUE); |
|
1596 $this->drupalLogout(); |
|
1597 |
|
1598 $this->drupalGet('node/' . $this->node->nid); |
|
1599 $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.'); |
|
1600 |
|
1601 // Post 2 anonymous comments without contact info. |
|
1602 $comments[] = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE); |
|
1603 $comments[] = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE); |
|
1604 |
|
1605 // Publish multiple comments in one operation. |
|
1606 $this->drupalLogin($this->admin_user); |
|
1607 $this->drupalGet('admin/content/comment/approval'); |
|
1608 $this->assertText(t('Unapproved comments (@count)', array('@count' => 2)), 'Two unapproved comments waiting for approval.'); |
|
1609 $edit = array( |
|
1610 "comments[{$comments[0]->id}]" => 1, |
|
1611 "comments[{$comments[1]->id}]" => 1, |
|
1612 ); |
|
1613 $this->drupalPost(NULL, $edit, t('Update')); |
|
1614 $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), 'All comments were approved.'); |
|
1615 |
|
1616 // Delete multiple comments in one operation. |
|
1617 $edit = array( |
|
1618 'operation' => 'delete', |
|
1619 "comments[{$comments[0]->id}]" => 1, |
|
1620 "comments[{$comments[1]->id}]" => 1, |
|
1621 "comments[{$anonymous_comment4->id}]" => 1, |
|
1622 ); |
|
1623 $this->drupalPost(NULL, $edit, t('Update')); |
|
1624 $this->assertText(t('Are you sure you want to delete these comments and all their children?'), 'Confirmation required.'); |
|
1625 $this->drupalPost(NULL, $edit, t('Delete comments')); |
|
1626 $this->assertText(t('No comments available.'), 'All comments were deleted.'); |
|
1627 } |
|
1628 |
|
1629 /** |
|
1630 * Test comment approval functionality through node interface. |
|
1631 */ |
|
1632 function testApprovalNodeInterface() { |
|
1633 // Set anonymous comments to require approval. |
|
1634 user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array( |
|
1635 'access comments' => TRUE, |
|
1636 'post comments' => TRUE, |
|
1637 'skip comment approval' => FALSE, |
|
1638 )); |
|
1639 $this->drupalLogin($this->admin_user); |
|
1640 $this->setCommentAnonymous('0'); // Ensure that doesn't require contact info. |
|
1641 $this->drupalLogout(); |
|
1642 |
|
1643 // Post anonymous comment without contact info. |
|
1644 $subject = $this->randomName(); |
|
1645 $body = $this->randomName(); |
|
1646 $this->postComment($this->node, $body, $subject, TRUE); // Set $contact to true so that it won't check for id and message. |
|
1647 $this->assertText(t('Your comment has been queued for review by site administrators and will be published after approval.'), 'Comment requires approval.'); |
|
1648 |
|
1649 // Get unapproved comment id. |
|
1650 $this->drupalLogin($this->admin_user); |
|
1651 $anonymous_comment4 = $this->getUnapprovedComment($subject); |
|
1652 $anonymous_comment4 = (object) array('id' => $anonymous_comment4, 'subject' => $subject, 'comment' => $body); |
|
1653 $this->drupalLogout(); |
|
1654 |
|
1655 $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.'); |
|
1656 |
|
1657 // Approve comment. |
|
1658 $this->drupalLogin($this->admin_user); |
|
1659 $this->drupalGet('comment/1/approve'); |
|
1660 $this->assertResponse(403, 'Forged comment approval was denied.'); |
|
1661 $this->drupalGet('comment/1/approve', array('query' => array('token' => 'forged'))); |
|
1662 $this->assertResponse(403, 'Forged comment approval was denied.'); |
|
1663 $this->drupalGet('node/' . $this->node->nid); |
|
1664 $this->clickLink(t('approve')); |
|
1665 $this->drupalLogout(); |
|
1666 |
|
1667 $this->drupalGet('node/' . $this->node->nid); |
|
1668 $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.'); |
|
1669 } |
|
1670 } |
|
1671 |
|
1672 /** |
|
1673 * Functional tests for the comment module blocks. |
|
1674 */ |
|
1675 class CommentBlockFunctionalTest extends CommentHelperCase { |
|
1676 public static function getInfo() { |
|
1677 return array( |
|
1678 'name' => 'Comment blocks', |
|
1679 'description' => 'Test comment block functionality.', |
|
1680 'group' => 'Comment', |
|
1681 ); |
|
1682 } |
|
1683 |
|
1684 /** |
|
1685 * Test the recent comments block. |
|
1686 */ |
|
1687 function testRecentCommentBlock() { |
|
1688 $this->drupalLogin($this->admin_user); |
|
1689 |
|
1690 // Set the block to a region to confirm block is available. |
|
1691 $edit = array( |
|
1692 'blocks[comment_recent][region]' => 'sidebar_first', |
|
1693 ); |
|
1694 $this->drupalPost('admin/structure/block', $edit, t('Save blocks')); |
|
1695 $this->assertText(t('The block settings have been updated.'), 'Block saved to first sidebar region.'); |
|
1696 |
|
1697 // Set block title and variables. |
|
1698 $block = array( |
|
1699 'title' => $this->randomName(), |
|
1700 'comment_block_count' => 2, |
|
1701 ); |
|
1702 $this->drupalPost('admin/structure/block/manage/comment/recent/configure', $block, t('Save block')); |
|
1703 $this->assertText(t('The block configuration has been saved.'), 'Block saved.'); |
|
1704 |
|
1705 // Add some test comments, one without a subject. |
|
1706 $comment1 = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1707 $comment2 = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1708 $comment3 = $this->postComment($this->node, $this->randomName()); |
|
1709 |
|
1710 // Test that a user without the 'access comments' permission cannot see the |
|
1711 // block. |
|
1712 $this->drupalLogout(); |
|
1713 user_role_revoke_permissions(DRUPAL_ANONYMOUS_RID, array('access comments')); |
|
1714 $this->drupalGet(''); |
|
1715 $this->assertNoText($block['title'], 'Block was not found.'); |
|
1716 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access comments')); |
|
1717 |
|
1718 // Test that a user with the 'access comments' permission can see the |
|
1719 // block. |
|
1720 $this->drupalLogin($this->web_user); |
|
1721 $this->drupalGet(''); |
|
1722 $this->assertText($block['title'], 'Block was found.'); |
|
1723 |
|
1724 // Test the only the 2 latest comments are shown and in the proper order. |
|
1725 $this->assertNoText($comment1->subject, 'Comment not found in block.'); |
|
1726 $this->assertText($comment2->subject, 'Comment found in block.'); |
|
1727 $this->assertText($comment3->comment, 'Comment found in block.'); |
|
1728 $this->assertTrue(strpos($this->drupalGetContent(), $comment3->comment) < strpos($this->drupalGetContent(), $comment2->subject), 'Comments were ordered correctly in block.'); |
|
1729 |
|
1730 // Set the number of recent comments to show to 10. |
|
1731 $this->drupalLogout(); |
|
1732 $this->drupalLogin($this->admin_user); |
|
1733 $block = array( |
|
1734 'comment_block_count' => 10, |
|
1735 ); |
|
1736 $this->drupalPost('admin/structure/block/manage/comment/recent/configure', $block, t('Save block')); |
|
1737 $this->assertText(t('The block configuration has been saved.'), 'Block saved.'); |
|
1738 |
|
1739 // Post an additional comment. |
|
1740 $comment4 = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1741 |
|
1742 // Test that all four comments are shown. |
|
1743 $this->assertText($comment1->subject, 'Comment found in block.'); |
|
1744 $this->assertText($comment2->subject, 'Comment found in block.'); |
|
1745 $this->assertText($comment3->comment, 'Comment found in block.'); |
|
1746 $this->assertText($comment4->subject, 'Comment found in block.'); |
|
1747 |
|
1748 // Test that links to comments work when comments are across pages. |
|
1749 $this->setCommentsPerPage(1); |
|
1750 $this->drupalGet(''); |
|
1751 $this->clickLink($comment1->subject); |
|
1752 $this->assertText($comment1->subject, 'Comment link goes to correct page.'); |
|
1753 $this->drupalGet(''); |
|
1754 $this->clickLink($comment2->subject); |
|
1755 $this->assertText($comment2->subject, 'Comment link goes to correct page.'); |
|
1756 $this->clickLink($comment4->subject); |
|
1757 $this->assertText($comment4->subject, 'Comment link goes to correct page.'); |
|
1758 // Check that when viewing a comment page from a link to the comment, that |
|
1759 // rel="canonical" is added to the head of the document. |
|
1760 $this->assertRaw('<link rel="canonical"', 'Canonical URL was found in the HTML head'); |
|
1761 } |
|
1762 } |
|
1763 |
|
1764 /** |
|
1765 * Unit tests for comment module integration with RSS feeds. |
|
1766 */ |
|
1767 class CommentRSSUnitTest extends CommentHelperCase { |
|
1768 public static function getInfo() { |
|
1769 return array( |
|
1770 'name' => 'Comment RSS', |
|
1771 'description' => 'Test comments as part of an RSS feed.', |
|
1772 'group' => 'Comment', |
|
1773 ); |
|
1774 } |
|
1775 |
|
1776 /** |
|
1777 * Test comments as part of an RSS feed. |
|
1778 */ |
|
1779 function testCommentRSS() { |
|
1780 // Find comment in RSS feed. |
|
1781 $this->drupalLogin($this->web_user); |
|
1782 $comment = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
1783 $this->drupalGet('rss.xml'); |
|
1784 $raw = '<comments>' . url('node/' . $this->node->nid, array('fragment' => 'comments', 'absolute' => TRUE)) . '</comments>'; |
|
1785 $this->assertRaw($raw, 'Comments as part of RSS feed.'); |
|
1786 |
|
1787 // Hide comments from RSS feed and check presence. |
|
1788 $this->node->comment = COMMENT_NODE_HIDDEN; |
|
1789 node_save($this->node); |
|
1790 $this->drupalGet('rss.xml'); |
|
1791 $this->assertNoRaw($raw, 'Hidden comments is not a part of RSS feed.'); |
|
1792 } |
|
1793 } |
|
1794 |
|
1795 |
|
1796 /** |
|
1797 * Test to make sure comment content is rebuilt. |
|
1798 */ |
|
1799 class CommentContentRebuild extends CommentHelperCase { |
|
1800 public static function getInfo() { |
|
1801 return array( |
|
1802 'name' => 'Comment Rebuild', |
|
1803 'description' => 'Test to make sure the comment content is rebuilt.', |
|
1804 'group' => 'Comment', |
|
1805 ); |
|
1806 } |
|
1807 |
|
1808 /** |
|
1809 * Test to ensure that the comment's content array is rebuilt for every |
|
1810 * call to comment_view(). |
|
1811 */ |
|
1812 function testCommentRebuild() { |
|
1813 // Update the comment settings so preview isn't required. |
|
1814 $this->drupalLogin($this->admin_user); |
|
1815 $this->setCommentSubject(TRUE); |
|
1816 $this->setCommentPreview(DRUPAL_OPTIONAL); |
|
1817 $this->drupalLogout(); |
|
1818 |
|
1819 // Log in as the web user and add the comment. |
|
1820 $this->drupalLogin($this->web_user); |
|
1821 $subject_text = $this->randomName(); |
|
1822 $comment_text = $this->randomName(); |
|
1823 $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE); |
|
1824 $comment_loaded = comment_load($comment->id); |
|
1825 $this->assertTrue($this->commentExists($comment), 'Comment found.'); |
|
1826 |
|
1827 // Add the property to the content array and then see if it still exists on build. |
|
1828 $comment_loaded->content['test_property'] = array('#value' => $this->randomString()); |
|
1829 $built_content = comment_view($comment_loaded, $this->node); |
|
1830 |
|
1831 // This means that the content was rebuilt as the added test property no longer exists. |
|
1832 $this->assertFalse(isset($built_content['test_property']), 'Comment content was emptied before being built.'); |
|
1833 } |
|
1834 } |
|
1835 |
|
1836 /** |
|
1837 * Test comment token replacement in strings. |
|
1838 */ |
|
1839 class CommentTokenReplaceTestCase extends CommentHelperCase { |
|
1840 public static function getInfo() { |
|
1841 return array( |
|
1842 'name' => 'Comment token replacement', |
|
1843 'description' => 'Generates text using placeholders for dummy content to check comment token replacement.', |
|
1844 'group' => 'Comment', |
|
1845 ); |
|
1846 } |
|
1847 |
|
1848 /** |
|
1849 * Creates a comment, then tests the tokens generated from it. |
|
1850 */ |
|
1851 function testCommentTokenReplacement() { |
|
1852 global $language; |
|
1853 $url_options = array( |
|
1854 'absolute' => TRUE, |
|
1855 'language' => $language, |
|
1856 ); |
|
1857 |
|
1858 $this->drupalLogin($this->admin_user); |
|
1859 |
|
1860 // Set comment variables. |
|
1861 $this->setCommentSubject(TRUE); |
|
1862 |
|
1863 // Create a node and a comment. |
|
1864 $node = $this->drupalCreateNode(array('type' => 'article')); |
|
1865 $parent_comment = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); |
|
1866 |
|
1867 // Post a reply to the comment. |
|
1868 $this->drupalGet('comment/reply/' . $node->nid . '/' . $parent_comment->id); |
|
1869 $child_comment = $this->postComment(NULL, $this->randomName(), $this->randomName()); |
|
1870 $comment = comment_load($child_comment->id); |
|
1871 $comment->homepage = 'http://example.org/'; |
|
1872 |
|
1873 // Add HTML to ensure that sanitation of some fields tested directly. |
|
1874 $comment->subject = '<blink>Blinking Comment</blink>'; |
|
1875 $instance = field_info_instance('comment', 'body', 'comment_body'); |
|
1876 |
|
1877 // Generate and test sanitized tokens. |
|
1878 $tests = array(); |
|
1879 $tests['[comment:cid]'] = $comment->cid; |
|
1880 $tests['[comment:hostname]'] = check_plain($comment->hostname); |
|
1881 $tests['[comment:name]'] = filter_xss($comment->name); |
|
1882 $tests['[comment:mail]'] = check_plain($this->admin_user->mail); |
|
1883 $tests['[comment:homepage]'] = check_url($comment->homepage); |
|
1884 $tests['[comment:title]'] = filter_xss($comment->subject); |
|
1885 $tests['[comment:body]'] = _text_sanitize($instance, LANGUAGE_NONE, $comment->comment_body[LANGUAGE_NONE][0], 'value'); |
|
1886 $tests['[comment:url]'] = url('comment/' . $comment->cid, $url_options + array('fragment' => 'comment-' . $comment->cid)); |
|
1887 $tests['[comment:edit-url]'] = url('comment/' . $comment->cid . '/edit', $url_options); |
|
1888 $tests['[comment:created:since]'] = format_interval(REQUEST_TIME - $comment->created, 2, $language->language); |
|
1889 $tests['[comment:changed:since]'] = format_interval(REQUEST_TIME - $comment->changed, 2, $language->language); |
|
1890 $tests['[comment:parent:cid]'] = $comment->pid; |
|
1891 $tests['[comment:parent:title]'] = check_plain($parent_comment->subject); |
|
1892 $tests['[comment:node:nid]'] = $comment->nid; |
|
1893 $tests['[comment:node:title]'] = check_plain($node->title); |
|
1894 $tests['[comment:author:uid]'] = $comment->uid; |
|
1895 $tests['[comment:author:name]'] = check_plain($this->admin_user->name); |
|
1896 |
|
1897 // Test to make sure that we generated something for each token. |
|
1898 $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.'); |
|
1899 |
|
1900 foreach ($tests as $input => $expected) { |
|
1901 $output = token_replace($input, array('comment' => $comment), array('language' => $language)); |
|
1902 $this->assertEqual($output, $expected, format_string('Sanitized comment token %token replaced.', array('%token' => $input))); |
|
1903 } |
|
1904 |
|
1905 // Generate and test unsanitized tokens. |
|
1906 $tests['[comment:hostname]'] = $comment->hostname; |
|
1907 $tests['[comment:name]'] = $comment->name; |
|
1908 $tests['[comment:mail]'] = $this->admin_user->mail; |
|
1909 $tests['[comment:homepage]'] = $comment->homepage; |
|
1910 $tests['[comment:title]'] = $comment->subject; |
|
1911 $tests['[comment:body]'] = $comment->comment_body[LANGUAGE_NONE][0]['value']; |
|
1912 $tests['[comment:parent:title]'] = $parent_comment->subject; |
|
1913 $tests['[comment:node:title]'] = $node->title; |
|
1914 $tests['[comment:author:name]'] = $this->admin_user->name; |
|
1915 |
|
1916 foreach ($tests as $input => $expected) { |
|
1917 $output = token_replace($input, array('comment' => $comment), array('language' => $language, 'sanitize' => FALSE)); |
|
1918 $this->assertEqual($output, $expected, format_string('Unsanitized comment token %token replaced.', array('%token' => $input))); |
|
1919 } |
|
1920 |
|
1921 // Load node so comment_count gets computed. |
|
1922 $node = node_load($node->nid); |
|
1923 |
|
1924 // Generate comment tokens for the node (it has 2 comments, both new). |
|
1925 $tests = array(); |
|
1926 $tests['[node:comment-count]'] = 2; |
|
1927 $tests['[node:comment-count-new]'] = 2; |
|
1928 |
|
1929 foreach ($tests as $input => $expected) { |
|
1930 $output = token_replace($input, array('node' => $node), array('language' => $language)); |
|
1931 $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input))); |
|
1932 } |
|
1933 } |
|
1934 } |
|
1935 |
|
1936 /** |
|
1937 * Test actions provided by the comment module. |
|
1938 */ |
|
1939 class CommentActionsTestCase extends CommentHelperCase { |
|
1940 public static function getInfo() { |
|
1941 return array( |
|
1942 'name' => 'Comment actions', |
|
1943 'description' => 'Test actions provided by the comment module.', |
|
1944 'group' => 'Comment', |
|
1945 ); |
|
1946 } |
|
1947 |
|
1948 /** |
|
1949 * Test comment publish and unpublish actions. |
|
1950 */ |
|
1951 function testCommentPublishUnpublishActions() { |
|
1952 $this->drupalLogin($this->web_user); |
|
1953 $comment_text = $this->randomName(); |
|
1954 $subject = $this->randomName(); |
|
1955 $comment = $this->postComment($this->node, $comment_text, $subject); |
|
1956 $comment = comment_load($comment->id); |
|
1957 |
|
1958 // Unpublish a comment (direct form: doesn't actually save the comment). |
|
1959 comment_unpublish_action($comment); |
|
1960 $this->assertEqual($comment->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished'); |
|
1961 $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), 'Found watchdog message'); |
|
1962 $this->clearWatchdog(); |
|
1963 |
|
1964 // Unpublish a comment (indirect form: modify the comment in the database). |
|
1965 comment_unpublish_action(NULL, array('cid' => $comment->cid)); |
|
1966 $this->assertEqual(comment_load($comment->cid)->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished'); |
|
1967 $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $subject), 'Found watchdog message'); |
|
1968 |
|
1969 // Publish a comment (direct form: doesn't actually save the comment). |
|
1970 comment_publish_action($comment); |
|
1971 $this->assertEqual($comment->status, COMMENT_PUBLISHED, 'Comment was published'); |
|
1972 $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), 'Found watchdog message'); |
|
1973 $this->clearWatchdog(); |
|
1974 |
|
1975 // Publish a comment (indirect form: modify the comment in the database). |
|
1976 comment_publish_action(NULL, array('cid' => $comment->cid)); |
|
1977 $this->assertEqual(comment_load($comment->cid)->status, COMMENT_PUBLISHED, 'Comment was published'); |
|
1978 $this->assertWatchdogMessage('Published comment %subject.', array('%subject' => $subject), 'Found watchdog message'); |
|
1979 $this->clearWatchdog(); |
|
1980 } |
|
1981 |
|
1982 /** |
|
1983 * Tests the unpublish comment by keyword action. |
|
1984 */ |
|
1985 public function testCommentUnpublishByKeyword() { |
|
1986 $this->drupalLogin($this->admin_user); |
|
1987 $callback = 'comment_unpublish_by_keyword_action'; |
|
1988 $hash = drupal_hash_base64($callback); |
|
1989 $comment_text = $keywords = $this->randomName(); |
|
1990 $edit = array( |
|
1991 'actions_label' => $callback, |
|
1992 'keywords' => $keywords, |
|
1993 ); |
|
1994 |
|
1995 $this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save')); |
|
1996 |
|
1997 $action = db_query("SELECT aid, type, callback, parameters, label FROM {actions} WHERE callback = :callback", array(':callback' => $callback))->fetchObject(); |
|
1998 |
|
1999 $this->assertTrue($action, 'The action could be loaded.'); |
|
2000 |
|
2001 $comment = $this->postComment($this->node, $comment_text, $this->randomName()); |
|
2002 |
|
2003 // Load the full comment so that status is available. |
|
2004 $comment = comment_load($comment->id); |
|
2005 |
|
2006 $this->assertTrue($comment->status == COMMENT_PUBLISHED, 'The comment status was set to published.'); |
|
2007 |
|
2008 comment_unpublish_by_keyword_action($comment, array('keywords' => array($keywords))); |
|
2009 |
|
2010 // We need to make sure that the comment has been saved with status |
|
2011 // unpublished. |
|
2012 $this->assertEqual(comment_load($comment->cid)->status, COMMENT_NOT_PUBLISHED, 'Comment was unpublished.'); |
|
2013 $this->assertWatchdogMessage('Unpublished comment %subject.', array('%subject' => $comment->subject), 'Found watchdog message.'); |
|
2014 $this->clearWatchdog(); |
|
2015 } |
|
2016 |
|
2017 /** |
|
2018 * Verify that a watchdog message has been entered. |
|
2019 * |
|
2020 * @param $watchdog_message |
|
2021 * The watchdog message. |
|
2022 * @param $variables |
|
2023 * The array of variables passed to watchdog(). |
|
2024 * @param $message |
|
2025 * The assertion message. |
|
2026 */ |
|
2027 function assertWatchdogMessage($watchdog_message, $variables, $message) { |
|
2028 $status = (bool) db_query_range("SELECT 1 FROM {watchdog} WHERE message = :message AND variables = :variables", 0, 1, array(':message' => $watchdog_message, ':variables' => serialize($variables)))->fetchField(); |
|
2029 return $this->assert($status, format_string('@message', array('@message' => $message))); |
|
2030 } |
|
2031 |
|
2032 /** |
|
2033 * Helper function: clear the watchdog. |
|
2034 */ |
|
2035 function clearWatchdog() { |
|
2036 db_truncate('watchdog')->execute(); |
|
2037 } |
|
2038 } |
|
2039 |
|
2040 /** |
|
2041 * Test fields on comments. |
|
2042 */ |
|
2043 class CommentFieldsTest extends CommentHelperCase { |
|
2044 public static function getInfo() { |
|
2045 return array( |
|
2046 'name' => 'Comment fields', |
|
2047 'description' => 'Tests fields on comments.', |
|
2048 'group' => 'Comment', |
|
2049 ); |
|
2050 } |
|
2051 |
|
2052 /** |
|
2053 * Tests that the default 'comment_body' field is correctly added. |
|
2054 */ |
|
2055 function testCommentDefaultFields() { |
|
2056 // Do not make assumptions on default node types created by the test |
|
2057 // installation profile, and create our own. |
|
2058 $this->drupalCreateContentType(array('type' => 'test_node_type')); |
|
2059 |
|
2060 // Check that the 'comment_body' field is present on all comment bundles. |
|
2061 $instances = field_info_instances('comment'); |
|
2062 foreach (node_type_get_types() as $type_name => $info) { |
|
2063 $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name))); |
|
2064 |
|
2065 // Delete the instance along the way. |
|
2066 field_delete_instance($instances['comment_node_' . $type_name]['comment_body']); |
|
2067 } |
|
2068 |
|
2069 // Check that the 'comment_body' field is deleted. |
|
2070 $field = field_info_field('comment_body'); |
|
2071 $this->assertTrue(empty($field), 'The comment_body field was deleted'); |
|
2072 |
|
2073 // Create a new content type. |
|
2074 $type_name = 'test_node_type_2'; |
|
2075 $this->drupalCreateContentType(array('type' => $type_name)); |
|
2076 |
|
2077 // Check that the 'comment_body' field exists and has an instance on the |
|
2078 // new comment bundle. |
|
2079 $field = field_info_field('comment_body'); |
|
2080 $this->assertTrue($field, 'The comment_body field exists'); |
|
2081 $instances = field_info_instances('comment'); |
|
2082 $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name))); |
|
2083 } |
|
2084 |
|
2085 /** |
|
2086 * Test that comment module works when enabled after a content module. |
|
2087 */ |
|
2088 function testCommentEnable() { |
|
2089 // Create a user to do module administration. |
|
2090 $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer modules')); |
|
2091 $this->drupalLogin($this->admin_user); |
|
2092 |
|
2093 // Disable the comment module. |
|
2094 $edit = array(); |
|
2095 $edit['modules[Core][comment][enable]'] = FALSE; |
|
2096 $this->drupalPost('admin/modules', $edit, t('Save configuration')); |
|
2097 $this->resetAll(); |
|
2098 $this->assertFalse(module_exists('comment'), 'Comment module disabled.'); |
|
2099 |
|
2100 // Enable core content type modules (blog, book, and poll). |
|
2101 $edit = array(); |
|
2102 $edit['modules[Core][blog][enable]'] = 'blog'; |
|
2103 $edit['modules[Core][book][enable]'] = 'book'; |
|
2104 $edit['modules[Core][poll][enable]'] = 'poll'; |
|
2105 $this->drupalPost('admin/modules', $edit, t('Save configuration')); |
|
2106 $this->resetAll(); |
|
2107 |
|
2108 // Now enable the comment module. |
|
2109 $edit = array(); |
|
2110 $edit['modules[Core][comment][enable]'] = 'comment'; |
|
2111 $this->drupalPost('admin/modules', $edit, t('Save configuration')); |
|
2112 $this->resetAll(); |
|
2113 $this->assertTrue(module_exists('comment'), 'Comment module enabled.'); |
|
2114 |
|
2115 // Create nodes of each type. |
|
2116 $blog_node = $this->drupalCreateNode(array('type' => 'blog')); |
|
2117 $book_node = $this->drupalCreateNode(array('type' => 'book')); |
|
2118 $poll_node = $this->drupalCreateNode(array('type' => 'poll', 'active' => 1, 'runtime' => 0, 'choice' => array(array('chtext' => '')))); |
|
2119 |
|
2120 $this->drupalLogout(); |
|
2121 |
|
2122 // Try to post a comment on each node. A failure will be triggered if the |
|
2123 // comment body is missing on one of these forms, due to postComment() |
|
2124 // asserting that the body is actually posted correctly. |
|
2125 $this->web_user = $this->drupalCreateUser(array('access content', 'access comments', 'post comments', 'skip comment approval')); |
|
2126 $this->drupalLogin($this->web_user); |
|
2127 $this->postComment($blog_node, $this->randomName(), $this->randomName()); |
|
2128 $this->postComment($book_node, $this->randomName(), $this->randomName()); |
|
2129 $this->postComment($poll_node, $this->randomName(), $this->randomName()); |
|
2130 } |
|
2131 |
|
2132 /** |
|
2133 * Test that comment module works correctly with plain text format. |
|
2134 */ |
|
2135 function testCommentFormat() { |
|
2136 // Disable text processing for comments. |
|
2137 $this->drupalLogin($this->admin_user); |
|
2138 $edit = array('instance[settings][text_processing]' => 0); |
|
2139 $this->drupalPost('admin/structure/types/manage/article/comment/fields/comment_body', $edit, t('Save settings')); |
|
2140 |
|
2141 // Post a comment without an explicit subject. |
|
2142 $this->drupalLogin($this->web_user); |
|
2143 $edit = array('comment_body[und][0][value]' => $this->randomName(8)); |
|
2144 $this->drupalPost('node/' . $this->node->nid, $edit, t('Save')); |
|
2145 } |
|
2146 } |
|
2147 |
|
2148 /** |
|
2149 * Tests comment threading. |
|
2150 */ |
|
2151 class CommentThreadingTestCase extends CommentHelperCase { |
|
2152 public static function getInfo() { |
|
2153 return array( |
|
2154 'name' => 'Comment Threading', |
|
2155 'description' => 'Test to make sure the comment number increments properly.', |
|
2156 'group' => 'Comment', |
|
2157 ); |
|
2158 } |
|
2159 |
|
2160 /** |
|
2161 * Tests the comment threading. |
|
2162 */ |
|
2163 function testCommentThreading() { |
|
2164 $langcode = LANGUAGE_NONE; |
|
2165 // Set comments to have a subject with preview disabled. |
|
2166 $this->drupalLogin($this->admin_user); |
|
2167 $this->setCommentPreview(DRUPAL_DISABLED); |
|
2168 $this->setCommentForm(TRUE); |
|
2169 $this->setCommentSubject(TRUE); |
|
2170 $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, 'Comment paging changed.'); |
|
2171 $this->drupalLogout(); |
|
2172 |
|
2173 // Create a node. |
|
2174 $this->drupalLogin($this->web_user); |
|
2175 $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->web_user->uid)); |
|
2176 |
|
2177 // Post comment #1. |
|
2178 $this->drupalLogin($this->web_user); |
|
2179 $subject_text = $this->randomName(); |
|
2180 $comment_text = $this->randomName(); |
|
2181 $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE); |
|
2182 $comment_loaded = comment_load($comment->id); |
|
2183 $this->assertTrue($this->commentExists($comment), 'Comment #1. Comment found.'); |
|
2184 $this->assertEqual($comment_loaded->thread, '01/'); |
|
2185 |
|
2186 // Reply to comment #1 creating comment #2. |
|
2187 $this->drupalLogin($this->web_user); |
|
2188 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
2189 $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); |
|
2190 $reply_loaded = comment_load($reply->id); |
|
2191 $this->assertTrue($this->commentExists($reply, TRUE), 'Comment #2. Reply found.'); |
|
2192 $this->assertEqual($reply_loaded->thread, '01.00/'); |
|
2193 |
|
2194 // Reply to comment #2 creating comment #3. |
|
2195 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $reply->id); |
|
2196 $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
2197 $reply_loaded = comment_load($reply->id); |
|
2198 $this->assertTrue($this->commentExists($reply, TRUE), 'Comment #3. Second reply found.'); |
|
2199 $this->assertEqual($reply_loaded->thread, '01.00.00/'); |
|
2200 |
|
2201 // Reply to comment #1 creating comment #4. |
|
2202 $this->drupalLogin($this->web_user); |
|
2203 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
2204 $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); |
|
2205 $reply_loaded = comment_load($reply->id); |
|
2206 $this->assertTrue($this->commentExists($comment), 'Comment #4. Third reply found.'); |
|
2207 $this->assertEqual($reply_loaded->thread, '01.01/'); |
|
2208 |
|
2209 // Post comment #2 overall comment #5. |
|
2210 $this->drupalLogin($this->web_user); |
|
2211 $subject_text = $this->randomName(); |
|
2212 $comment_text = $this->randomName(); |
|
2213 $comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE); |
|
2214 $comment_loaded = comment_load($comment->id); |
|
2215 $this->assertTrue($this->commentExists($comment), 'Comment #5. Second comment found.'); |
|
2216 $this->assertEqual($comment_loaded->thread, '02/'); |
|
2217 |
|
2218 // Reply to comment #5 creating comment #6. |
|
2219 $this->drupalLogin($this->web_user); |
|
2220 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
2221 $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); |
|
2222 $reply_loaded = comment_load($reply->id); |
|
2223 $this->assertTrue($this->commentExists($reply, TRUE), 'Comment #6. Reply found.'); |
|
2224 $this->assertEqual($reply_loaded->thread, '02.00/'); |
|
2225 |
|
2226 // Reply to comment #6 creating comment #7. |
|
2227 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $reply->id); |
|
2228 $reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); |
|
2229 $reply_loaded = comment_load($reply->id); |
|
2230 $this->assertTrue($this->commentExists($reply, TRUE), 'Comment #7. Second reply found.'); |
|
2231 $this->assertEqual($reply_loaded->thread, '02.00.00/'); |
|
2232 |
|
2233 // Reply to comment #5 creating comment #8. |
|
2234 $this->drupalLogin($this->web_user); |
|
2235 $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); |
|
2236 $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); |
|
2237 $reply_loaded = comment_load($reply->id); |
|
2238 $this->assertTrue($this->commentExists($comment), 'Comment #8. Third reply found.'); |
|
2239 $this->assertEqual($reply_loaded->thread, '02.01/'); |
|
2240 } |
|
2241 } |
|
2242 |
|
2243 /** |
|
2244 * Tests that comments behave correctly when the node is changed. |
|
2245 */ |
|
2246 class CommentNodeChangesTestCase extends CommentHelperCase { |
|
2247 |
|
2248 public static function getInfo() { |
|
2249 return array( |
|
2250 'name' => 'Comment deletion on node changes', |
|
2251 'description' => 'Tests that comments behave correctly when the node is changed.', |
|
2252 'group' => 'Comment', |
|
2253 ); |
|
2254 } |
|
2255 |
|
2256 /** |
|
2257 * Tests that comments are deleted with the node. |
|
2258 */ |
|
2259 function testNodeDeletion() { |
|
2260 $this->drupalLogin($this->web_user); |
|
2261 $comment = $this->postComment($this->node, $this->randomName(), $this->randomName()); |
|
2262 $this->assertTrue(comment_load($comment->id), 'The comment could be loaded.'); |
|
2263 node_delete($this->node->nid); |
|
2264 $this->assertFalse(comment_load($comment->id), 'The comment could not be loaded after the node was deleted.'); |
|
2265 } |
|
2266 } |