MDL-52126 forum: Correct over-escaping of html-based emails
[moodle.git] / mod / forum / tests / mail_test.php
CommitLineData
a7a84903
AN
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * The forum module mail generation tests.
19 *
20 * @package mod_forum
21 * @category external
22 * @copyright 2013 Andrew Nicols
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29
30class mod_forum_mail_testcase extends advanced_testcase {
31
32 protected $helper;
33
34 public function setUp() {
59075a43
AN
35 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
36 // tests using these functions.
37 \mod_forum\subscriptions::reset_forum_cache();
a54702b2 38 \mod_forum\subscriptions::reset_discussion_cache();
59075a43 39
a7a84903
AN
40 global $CFG;
41 require_once($CFG->dirroot . '/mod/forum/lib.php');
42
43 $helper = new stdClass();
44
45 // Messaging is not compatible with transactions...
46 $this->preventResetByRollback();
47
48 // Catch all messages.
49 $helper->messagesink = $this->redirectMessages();
50 $helper->mailsink = $this->redirectEmails();
51
52 // Confirm that we have an empty message sink so far.
53 $messages = $helper->messagesink->get_messages();
54 $this->assertEquals(0, count($messages));
55
56 $messages = $helper->mailsink->get_messages();
57 $this->assertEquals(0, count($messages));
58
555837c5
AN
59 // Forcibly reduce the maxeditingtime to a second in the past to
60 // ensure that messages are sent out.
61 $CFG->maxeditingtime = -1;
a7a84903 62
a7a84903
AN
63 $this->helper = $helper;
64 }
65
66 public function tearDown() {
59075a43
AN
67 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
68 // tests using these functions.
69 \mod_forum\subscriptions::reset_forum_cache();
70
a7a84903
AN
71 $this->helper->messagesink->clear();
72 $this->helper->messagesink->close();
73
74 $this->helper->mailsink->clear();
75 $this->helper->mailsink->close();
76 }
77
e7f0b4d3
AN
78 /**
79 * Perform message inbound setup for the mod_forum reply handler.
80 */
81 protected function helper_spoof_message_inbound_setup() {
82 global $CFG, $DB;
83 // Setup the default Inbound Message mailbox settings.
84 $CFG->messageinbound_domain = 'example.com';
85 $CFG->messageinbound_enabled = true;
86
87 // Must be no longer than 15 characters.
88 $CFG->messageinbound_mailbox = 'moodlemoodle123';
89
90 $record = $DB->get_record('messageinbound_handlers', array('classname' => '\mod_forum\message\inbound\reply_handler'));
91 $record->enabled = true;
92 $record->id = $DB->update_record('messageinbound_handlers', $record);
93 }
94
a7a84903
AN
95 /**
96 * Helper to create the required number of users in the specified
97 * course.
98 * Users are enrolled as students.
99 *
100 * @param stdClass $course The course object
101 * @param integer $count The number of users to create
102 * @return array The users created
103 */
104 protected function helper_create_users($course, $count) {
105 $users = array();
106
107 for ($i = 0; $i < $count; $i++) {
108 $user = $this->getDataGenerator()->create_user();
109 $this->getDataGenerator()->enrol_user($user->id, $course->id);
110 $users[] = $user;
111 }
112
113 return $users;
114 }
115
116 /**
117 * Create a new discussion and post within the specified forum, as the
118 * specified author.
119 *
120 * @param stdClass $forum The forum to post in
121 * @param stdClass $author The author to post as
28c0c4af 122 * @param array $fields any other fields in discussion (name, message, messageformat, ...)
a7a84903
AN
123 * @param array An array containing the discussion object, and the post object
124 */
28c0c4af 125 protected function helper_post_to_forum($forum, $author, $fields = array()) {
555837c5 126 global $DB;
a7a84903
AN
127 $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
128
129 // Create a discussion in the forum, and then add a post to that discussion.
28c0c4af 130 $record = (object)$fields;
a7a84903
AN
131 $record->course = $forum->course;
132 $record->userid = $author->id;
133 $record->forum = $forum->id;
134 $discussion = $generator->create_discussion($record);
135
555837c5
AN
136 // Retrieve the post which was created by create_discussion.
137 $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
a7a84903
AN
138
139 return array($discussion, $post);
140 }
141
7122e154
AN
142 /**
143 * Update the post time for the specified post by $factor.
144 *
145 * @param stdClass $post The post to update
146 * @param int $factor The amount to update by
147 */
148 protected function helper_update_post_time($post, $factor) {
149 global $DB;
150
151 // Update the post to have a created in the past.
152 $DB->set_field('forum_posts', 'created', $post->created + $factor, array('id' => $post->id));
153 }
154
155 /**
156 * Update the subscription time for the specified user/discussion by $factor.
157 *
158 * @param stdClass $user The user to update
159 * @param stdClass $discussion The discussion to update for this user
160 * @param int $factor The amount to update by
161 */
162 protected function helper_update_subscription_time($user, $discussion, $factor) {
163 global $DB;
164
165 $sub = $DB->get_record('forum_discussion_subs', array('userid' => $user->id, 'discussion' => $discussion->id));
166
167 // Update the subscription to have a preference in the past.
168 $DB->set_field('forum_discussion_subs', 'preference', $sub->preference + $factor, array('id' => $sub->id));
169 }
170
171 /**
172 * Create a new post within an existing discussion, as the specified author.
173 *
174 * @param stdClass $forum The forum to post in
175 * @param stdClass $discussion The discussion to post in
176 * @param stdClass $author The author to post as
177 * @return stdClass The forum post
178 */
179 protected function helper_post_to_discussion($forum, $discussion, $author) {
180 global $DB;
181
182 $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
183
184 // Add a post to the discussion.
185 $record = new stdClass();
186 $record->course = $forum->course;
187 $record->userid = $author->id;
188 $record->forum = $forum->id;
189 $record->discussion = $discussion->id;
190 $record->mailnow = 1;
191
192 $post = $generator->create_post($record);
193
194 return $post;
195 }
196
a7a84903
AN
197 /**
198 * Run the forum cron, and check that the specified post was sent the
199 * specified number of times.
200 *
201 * @param stdClass $post The forum post object
202 * @param integer $expected The number of times that the post should have been sent
203 * @return array An array of the messages caught by the message sink
204 */
205 protected function helper_run_cron_check_count($post, $expected) {
eb451c79 206
a7a84903
AN
207 // Clear the sinks before running cron.
208 $this->helper->messagesink->clear();
209 $this->helper->mailsink->clear();
210
211 // Cron daily uses mtrace, turn on buffering to silence output.
212 $this->expectOutputRegex("/{$expected} users were sent post {$post->id}, '{$post->subject}'/");
213 forum_cron();
214
215 // Now check the results in the message sink.
216 $messages = $this->helper->messagesink->get_messages();
217
218 // There should be the expected number of messages.
219 $this->assertEquals($expected, count($messages));
220
221 return $messages;
222 }
223
eb451c79
AN
224 /**
225 * Run the forum cron, and check that the specified posts were sent the
226 * specified number of times.
227 *
228 * @param stdClass $post The forum post object
229 * @param integer $expected The number of times that the post should have been sent
230 * @return array An array of the messages caught by the message sink
231 */
232 protected function helper_run_cron_check_counts($posts, $expected) {
233
234 // Clear the sinks before running cron.
235 $this->helper->messagesink->clear();
236 $this->helper->mailsink->clear();
237
238 // Cron daily uses mtrace, turn on buffering to silence output.
239 foreach ($posts as $post) {
240 $this->expectOutputRegex("/{$post['count']} users were sent post {$post['id']}, '{$post['subject']}'/");
241 }
242 forum_cron();
243
244 // Now check the results in the message sink.
245 $messages = $this->helper->messagesink->get_messages();
246
247 // There should be the expected number of messages.
248 $this->assertEquals($expected, count($messages));
249
250 return $messages;
251 }
252
a7a84903
AN
253 public function test_forced_subscription() {
254 $this->resetAfterTest(true);
255
256 // Create a course, with a forum.
257 $course = $this->getDataGenerator()->create_course();
258
259 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
260 $forum = $this->getDataGenerator()->create_module('forum', $options);
261
262 // Create two users enrolled in the course as students.
263 list($author, $recipient) = $this->helper_create_users($course, 2);
264
265 // Post a discussion to the forum.
266 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
267
268 // We expect both users to receive this post.
269 $expected = 2;
270
271 // Run cron and check that the expected number of users received the notification.
272 $messages = $this->helper_run_cron_check_count($post, $expected);
273
274 $seenauthor = false;
275 $seenrecipient = false;
276 foreach ($messages as $message) {
277 // They should both be from our user.
278 $this->assertEquals($author->id, $message->useridfrom);
279
280 if ($message->useridto == $author->id) {
281 $seenauthor = true;
282 } else if ($message->useridto = $recipient->id) {
283 $seenrecipient = true;
284 }
285 }
286
287 // Check we saw messages for both users.
288 $this->assertTrue($seenauthor);
289 $this->assertTrue($seenrecipient);
290 }
291
292 public function test_subscription_disabled() {
293 global $DB;
294
295 $this->resetAfterTest(true);
296
297 // Create a course, with a forum.
298 $course = $this->getDataGenerator()->create_course();
299
300 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE);
301 $forum = $this->getDataGenerator()->create_module('forum', $options);
302
303 // Create two users enrolled in the course as students.
304 list($author, $recipient) = $this->helper_create_users($course, 2);
305
306 // Post a discussion to the forum.
307 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
308
309 // We expect both users to receive this post.
310 $expected = 0;
311
312 // Run cron and check that the expected number of users received the notification.
313 $messages = $this->helper_run_cron_check_count($post, $expected);
314
315 // A user with the manageactivities capability within the course can subscribe.
316 $expected = 1;
317 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
318 assign_capability('moodle/course:manageactivities', CAP_ALLOW, $roleids['student'], context_course::instance($course->id));
7122e154 319 \mod_forum\subscriptions::subscribe_user($recipient->id, $forum);
a7a84903
AN
320
321 $this->assertEquals($expected, $DB->count_records('forum_subscriptions', array(
7122e154 322 'userid' => $recipient->id,
a7a84903
AN
323 'forum' => $forum->id,
324 )));
325
326 // Run cron and check that the expected number of users received the notification.
7122e154 327 list($discussion, $post) = $this->helper_post_to_forum($forum, $recipient);
a7a84903
AN
328 $messages = $this->helper_run_cron_check_count($post, $expected);
329
330 // Unsubscribe the user again.
7122e154 331 \mod_forum\subscriptions::unsubscribe_user($recipient->id, $forum);
a7a84903
AN
332
333 $expected = 0;
334 $this->assertEquals($expected, $DB->count_records('forum_subscriptions', array(
7122e154 335 'userid' => $recipient->id,
a7a84903
AN
336 'forum' => $forum->id,
337 )));
338
339 // Run cron and check that the expected number of users received the notification.
340 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
341 $messages = $this->helper_run_cron_check_count($post, $expected);
342
7122e154
AN
343 // Subscribe the user to the discussion.
344 \mod_forum\subscriptions::subscribe_user_to_discussion($recipient->id, $discussion);
345 $this->helper_update_subscription_time($recipient, $discussion, -60);
346
347 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
348 $this->helper_update_post_time($reply, -30);
349
350 $messages = $this->helper_run_cron_check_count($reply, $expected);
a7a84903
AN
351 }
352
353 public function test_automatic() {
354 $this->resetAfterTest(true);
355
356 // Create a course, with a forum.
357 $course = $this->getDataGenerator()->create_course();
358
359 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
360 $forum = $this->getDataGenerator()->create_module('forum', $options);
361
362 // Create two users enrolled in the course as students.
363 list($author, $recipient) = $this->helper_create_users($course, 2);
364
365 // Post a discussion to the forum.
366 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
367
368 // We expect both users to receive this post.
369 $expected = 2;
370
371 // Run cron and check that the expected number of users received the notification.
372 $messages = $this->helper_run_cron_check_count($post, $expected);
373
374 $seenauthor = false;
375 $seenrecipient = false;
376 foreach ($messages as $message) {
377 // They should both be from our user.
378 $this->assertEquals($author->id, $message->useridfrom);
379
380 if ($message->useridto == $author->id) {
381 $seenauthor = true;
382 } else if ($message->useridto = $recipient->id) {
383 $seenrecipient = true;
384 }
385 }
386
387 // Check we saw messages for both users.
388 $this->assertTrue($seenauthor);
389 $this->assertTrue($seenrecipient);
390 }
391
392 public function test_optional() {
393 $this->resetAfterTest(true);
394
395 // Create a course, with a forum.
396 $course = $this->getDataGenerator()->create_course();
397
398 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
399 $forum = $this->getDataGenerator()->create_module('forum', $options);
400
401 // Create two users enrolled in the course as students.
402 list($author, $recipient) = $this->helper_create_users($course, 2);
403
404 // Post a discussion to the forum.
405 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
406
407 // We expect both users to receive this post.
408 $expected = 0;
409
410 // Run cron and check that the expected number of users received the notification.
411 $messages = $this->helper_run_cron_check_count($post, $expected);
412 }
413
414 public function test_automatic_with_unsubscribed_user() {
415 $this->resetAfterTest(true);
416
417 // Create a course, with a forum.
418 $course = $this->getDataGenerator()->create_course();
419
420 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
421 $forum = $this->getDataGenerator()->create_module('forum', $options);
422
423 // Create two users enrolled in the course as students.
424 list($author, $recipient) = $this->helper_create_users($course, 2);
425
426 // Unsubscribe the 'author' user from the forum.
59075a43 427 \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
a7a84903
AN
428
429 // Post a discussion to the forum.
430 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
431
432 // We expect only one user to receive this post.
433 $expected = 1;
434
435 // Run cron and check that the expected number of users received the notification.
436 $messages = $this->helper_run_cron_check_count($post, $expected);
437
438 $seenauthor = false;
439 $seenrecipient = false;
440 foreach ($messages as $message) {
441 // They should both be from our user.
442 $this->assertEquals($author->id, $message->useridfrom);
443
444 if ($message->useridto == $author->id) {
445 $seenauthor = true;
446 } else if ($message->useridto = $recipient->id) {
447 $seenrecipient = true;
448 }
449 }
450
451 // Check we only saw one user.
452 $this->assertFalse($seenauthor);
453 $this->assertTrue($seenrecipient);
454 }
455
456 public function test_optional_with_subscribed_user() {
457 $this->resetAfterTest(true);
458
459 // Create a course, with a forum.
460 $course = $this->getDataGenerator()->create_course();
461
462 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
463 $forum = $this->getDataGenerator()->create_module('forum', $options);
464
465 // Create two users enrolled in the course as students.
466 list($author, $recipient) = $this->helper_create_users($course, 2);
467
468 // Subscribe the 'recipient' user from the forum.
59075a43 469 \mod_forum\subscriptions::subscribe_user($recipient->id, $forum);
a7a84903
AN
470
471 // Post a discussion to the forum.
472 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
473
474 // We expect only one user to receive this post.
475 $expected = 1;
476
477 // Run cron and check that the expected number of users received the notification.
478 $messages = $this->helper_run_cron_check_count($post, $expected);
479
480 $seenauthor = false;
481 $seenrecipient = false;
482 foreach ($messages as $message) {
483 // They should both be from our user.
484 $this->assertEquals($author->id, $message->useridfrom);
485
486 if ($message->useridto == $author->id) {
487 $seenauthor = true;
488 } else if ($message->useridto = $recipient->id) {
489 $seenrecipient = true;
490 }
491 }
492
493 // Check we only saw one user.
494 $this->assertFalse($seenauthor);
495 $this->assertTrue($seenrecipient);
496 }
497
49566c8a
AN
498 public function test_automatic_with_unsubscribed_discussion() {
499 $this->resetAfterTest(true);
500
501 // Create a course, with a forum.
502 $course = $this->getDataGenerator()->create_course();
503
504 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
505 $forum = $this->getDataGenerator()->create_module('forum', $options);
506
507 // Create two users enrolled in the course as students.
508 list($author, $recipient) = $this->helper_create_users($course, 2);
509
510 // Post a discussion to the forum.
511 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
512
513 // Unsubscribe the 'author' user from the discussion.
514 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
515
eb451c79
AN
516 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
517 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($recipient->id, $forum, $discussion->id));
518
49566c8a
AN
519 // We expect only one user to receive this post.
520 $expected = 1;
521
522 // Run cron and check that the expected number of users received the notification.
523 $messages = $this->helper_run_cron_check_count($post, $expected);
524
525 $seenauthor = false;
526 $seenrecipient = false;
527 foreach ($messages as $message) {
528 // They should both be from our user.
529 $this->assertEquals($author->id, $message->useridfrom);
530
531 if ($message->useridto == $author->id) {
532 $seenauthor = true;
533 } else if ($message->useridto = $recipient->id) {
534 $seenrecipient = true;
535 }
536 }
537
538 // Check we only saw one user.
539 $this->assertFalse($seenauthor);
540 $this->assertTrue($seenrecipient);
541 }
542
543 public function test_optional_with_subscribed_discussion() {
544 $this->resetAfterTest(true);
545
546 // Create a course, with a forum.
547 $course = $this->getDataGenerator()->create_course();
548
549 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
550 $forum = $this->getDataGenerator()->create_module('forum', $options);
551
552 // Create two users enrolled in the course as students.
553 list($author, $recipient) = $this->helper_create_users($course, 2);
554
555 // Post a discussion to the forum.
556 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
7122e154 557 $this->helper_update_post_time($post, -90);
49566c8a
AN
558
559 // Subscribe the 'recipient' user to the discussion.
560 \mod_forum\subscriptions::subscribe_user_to_discussion($recipient->id, $discussion);
7122e154
AN
561 $this->helper_update_subscription_time($recipient, $discussion, -60);
562
563 // Initially we don't expect any user to receive this post as you cannot subscribe to a discussion until after
564 // you have read it.
565 $expected = 0;
566
567 // Run cron and check that the expected number of users received the notification.
568 $messages = $this->helper_run_cron_check_count($post, $expected);
569
570 // Have a user reply to the discussion.
571 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
572 $this->helper_update_post_time($reply, -30);
49566c8a
AN
573
574 // We expect only one user to receive this post.
575 $expected = 1;
576
577 // Run cron and check that the expected number of users received the notification.
7122e154 578 $messages = $this->helper_run_cron_check_count($reply, $expected);
49566c8a
AN
579
580 $seenauthor = false;
581 $seenrecipient = false;
582 foreach ($messages as $message) {
583 // They should both be from our user.
584 $this->assertEquals($author->id, $message->useridfrom);
585
586 if ($message->useridto == $author->id) {
587 $seenauthor = true;
588 } else if ($message->useridto = $recipient->id) {
589 $seenrecipient = true;
590 }
591 }
592
593 // Check we only saw one user.
594 $this->assertFalse($seenauthor);
595 $this->assertTrue($seenrecipient);
596 }
597
598 public function test_automatic_with_subscribed_discussion_in_unsubscribed_forum() {
599 $this->resetAfterTest(true);
600
601 // Create a course, with a forum.
602 $course = $this->getDataGenerator()->create_course();
603
604 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
605 $forum = $this->getDataGenerator()->create_module('forum', $options);
606
607 // Create two users enrolled in the course as students.
608 list($author, $recipient) = $this->helper_create_users($course, 2);
609
610 // Post a discussion to the forum.
611 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
7122e154 612 $this->helper_update_post_time($post, -90);
49566c8a 613
7122e154 614 // Unsubscribe the 'author' user from the forum.
49566c8a
AN
615 \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
616
617 // Then re-subscribe them to the discussion.
618 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
7122e154 619 $this->helper_update_subscription_time($author, $discussion, -60);
49566c8a 620
7122e154
AN
621 // We expect just the user subscribed to the forum to receive this post at the moment as the discussion
622 // subscription time is after the post time.
623 $expected = 1;
49566c8a
AN
624
625 // Run cron and check that the expected number of users received the notification.
626 $messages = $this->helper_run_cron_check_count($post, $expected);
627
628 $seenauthor = false;
629 $seenrecipient = false;
630 foreach ($messages as $message) {
631 // They should both be from our user.
632 $this->assertEquals($author->id, $message->useridfrom);
633
634 if ($message->useridto == $author->id) {
635 $seenauthor = true;
636 } else if ($message->useridto = $recipient->id) {
637 $seenrecipient = true;
638 }
639 }
640
641 // Check we only saw one user.
7122e154
AN
642 $this->assertFalse($seenauthor);
643 $this->assertTrue($seenrecipient);
644
645 // Now post a reply to the original post.
646 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
647 $this->helper_update_post_time($reply, -30);
648
649 // We expect two users to receive this post.
650 $expected = 2;
651
652 // Run cron and check that the expected number of users received the notification.
653 $messages = $this->helper_run_cron_check_count($reply, $expected);
654
655 $seenauthor = false;
656 $seenrecipient = false;
657 foreach ($messages as $message) {
658 // They should both be from our user.
659 $this->assertEquals($author->id, $message->useridfrom);
660
661 if ($message->useridto == $author->id) {
662 $seenauthor = true;
663 } else if ($message->useridto = $recipient->id) {
664 $seenrecipient = true;
665 }
666 }
667
668 // Check we saw both users.
49566c8a
AN
669 $this->assertTrue($seenauthor);
670 $this->assertTrue($seenrecipient);
671 }
672
673 public function test_optional_with_unsubscribed_discussion_in_subscribed_forum() {
674 $this->resetAfterTest(true);
675
676 // Create a course, with a forum.
677 $course = $this->getDataGenerator()->create_course();
678
679 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
680 $forum = $this->getDataGenerator()->create_module('forum', $options);
681
682 // Create two users enrolled in the course as students.
683 list($author, $recipient) = $this->helper_create_users($course, 2);
684
685 // Post a discussion to the forum.
686 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
687
688 // Unsubscribe the 'recipient' user from the discussion.
689 \mod_forum\subscriptions::subscribe_user($recipient->id, $forum);
690
691 // Then unsubscribe them from the discussion.
692 \mod_forum\subscriptions::unsubscribe_user_from_discussion($recipient->id, $discussion);
693
694 // We don't expect any users to receive this post.
695 $expected = 0;
696
697 // Run cron and check that the expected number of users received the notification.
698 $messages = $this->helper_run_cron_check_count($post, $expected);
699 }
eb451c79
AN
700
701 /**
702 * Test that a user unsubscribed from a forum who has subscribed to a discussion, only receives posts made after
703 * they subscribed to the discussion.
704 */
705 public function test_forum_discussion_subscription_forum_unsubscribed_discussion_subscribed_after_post() {
706 $this->resetAfterTest(true);
eb451c79
AN
707
708 // Create a course, with a forum.
709 $course = $this->getDataGenerator()->create_course();
710
711 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
712 $forum = $this->getDataGenerator()->create_module('forum', $options);
713
714 $expectedmessages = array();
715
716 // Create a user enrolled in the course as a student.
717 list($author) = $this->helper_create_users($course, 1);
718
719 // Post a discussion to the forum.
720 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
7122e154 721 $this->helper_update_post_time($post, -90);
eb451c79
AN
722
723 $expectedmessages[] = array(
724 'id' => $post->id,
725 'subject' => $post->subject,
726 'count' => 0,
727 );
728
729 // Then subscribe the user to the discussion.
730 $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
7122e154 731 $this->helper_update_subscription_time($author, $discussion, -60);
eb451c79
AN
732
733 // Then post a reply to the first discussion.
7122e154
AN
734 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
735 $this->helper_update_post_time($reply, -30);
eb451c79
AN
736
737 $expectedmessages[] = array(
738 'id' => $reply->id,
739 'subject' => $reply->subject,
740 'count' => 1,
741 );
742
eb451c79
AN
743 $expectedcount = 1;
744
745 // Run cron and check that the expected number of users received the notification.
746 $messages = $this->helper_run_cron_check_counts($expectedmessages, $expectedcount);
eb451c79 747 }
e7f0b4d3
AN
748
749 public function test_forum_message_inbound_multiple_posts() {
750 $this->resetAfterTest(true);
751
752 // Create a course, with a forum.
753 $course = $this->getDataGenerator()->create_course();
754 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
755 $forum = $this->getDataGenerator()->create_module('forum', $options);
756
757 // Create a user enrolled in the course as a student.
758 list($author) = $this->helper_create_users($course, 1);
759
760 $expectedmessages = array();
761
762 // Post a discussion to the forum.
763 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
764 $this->helper_update_post_time($post, -90);
765
766 $expectedmessages[] = array(
767 'id' => $post->id,
768 'subject' => $post->subject,
769 'count' => 0,
770 );
771
772 // Then post a reply to the first discussion.
773 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
774 $this->helper_update_post_time($reply, -60);
775
776 $expectedmessages[] = array(
777 'id' => $reply->id,
778 'subject' => $reply->subject,
779 'count' => 1,
780 );
781
782 $expectedcount = 2;
783
784 // Ensure that messageinbound is enabled and configured for the forum handler.
785 $this->helper_spoof_message_inbound_setup();
786
787 $author->emailstop = '0';
788 set_user_preference('message_provider_mod_forum_posts_loggedoff', 'email', $author);
789 set_user_preference('message_provider_mod_forum_posts_loggedin', 'email', $author);
790
791 // Run cron and check that the expected number of users received the notification.
792 // Clear the mailsink, and close the messagesink.
793 $this->helper->mailsink->clear();
794 $this->helper->messagesink->close();
795
796 // Cron daily uses mtrace, turn on buffering to silence output.
797 foreach ($expectedmessages as $post) {
798 $this->expectOutputRegex("/{$post['count']} users were sent post {$post['id']}, '{$post['subject']}'/");
799 }
800
801 forum_cron();
802 $messages = $this->helper->mailsink->get_messages();
803
804 // There should be the expected number of messages.
805 $this->assertEquals($expectedcount, count($messages));
806
807 foreach ($messages as $message) {
808 $this->assertRegExp('/Reply-To: moodlemoodle123\+[^@]*@example.com/', $message->header);
809 }
810 }
28c0c4af
MG
811
812 public function test_long_subject() {
813 $this->resetAfterTest(true);
814
815 // Create a course, with a forum.
816 $course = $this->getDataGenerator()->create_course();
817
818 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
819 $forum = $this->getDataGenerator()->create_module('forum', $options);
820
821 // Create a user enrolled in the course as student.
822 list($author) = $this->helper_create_users($course, 1);
823
824 // Post a discussion to the forum.
825 $subject = 'This is the very long forum post subject that somebody was very kind of leaving, it is intended to check if long subject comes in mail correctly. Thank you.';
826 $a = (object)array('courseshortname' => $course->shortname, 'forumname' => $forum->name, 'subject' => $subject);
827 $expectedsubject = get_string('postmailsubject', 'forum', $a);
828 list($discussion, $post) = $this->helper_post_to_forum($forum, $author, array('name' => $subject));
829
830 // Run cron and check that the expected number of users received the notification.
831 $messages = $this->helper_run_cron_check_count($post, 1);
832 $message = reset($messages);
833 $this->assertEquals($author->id, $message->useridfrom);
834 $this->assertEquals($expectedsubject, $message->subject);
835 }
a7a84903 836}