2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * The forum module mail generation tests.
22 * @copyright 2013 Andrew Nicols
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
29 require_once($CFG->dirroot
. '/mod/forum/lib.php');
30 require_once(__DIR__
. '/cron_trait.php');
31 require_once(__DIR__
. '/generator_trait.php');
33 class mod_forum_mail_testcase
extends advanced_testcase
{
34 // Make use of the cron tester trait.
35 use mod_forum_tests_cron_trait
;
37 // Make use of the test generator trait.
38 use mod_forum_tests_generator_trait
;
41 * @var \phpunit_message_sink
43 protected $messagesink;
46 * @var \phpunit_mailer_sink
50 public function setUp() {
53 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
54 // tests using these functions.
55 \mod_forum\subscriptions
::reset_forum_cache();
56 \mod_forum\subscriptions
::reset_discussion_cache();
58 // Messaging is not compatible with transactions...
59 $this->preventResetByRollback();
61 // Catch all messages.
62 $this->messagesink
= $this->redirectMessages();
63 $this->mailsink
= $this->redirectEmails();
65 // Forcibly reduce the maxeditingtime to a second in the past to
66 // ensure that messages are sent out.
67 $CFG->maxeditingtime
= -1;
70 public function tearDown() {
71 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
72 // tests using these functions.
73 \mod_forum\subscriptions
::reset_forum_cache();
75 $this->messagesink
->clear();
76 $this->messagesink
->close();
77 unset($this->messagesink
);
79 $this->mailsink
->clear();
80 $this->mailsink
->close();
81 unset($this->mailsink
);
85 * Perform message inbound setup for the mod_forum reply handler.
87 protected function helper_spoof_message_inbound_setup() {
89 // Setup the default Inbound Message mailbox settings.
90 $CFG->messageinbound_domain
= 'example.com';
91 $CFG->messageinbound_enabled
= true;
93 // Must be no longer than 15 characters.
94 $CFG->messageinbound_mailbox
= 'moodlemoodle123';
96 $record = $DB->get_record('messageinbound_handlers', array('classname' => '\mod_forum\message\inbound\reply_handler'));
97 $record->enabled
= true;
98 $record->id
= $DB->update_record('messageinbound_handlers', $record);
101 public function test_cron_message_includes_courseid() {
102 $this->resetAfterTest(true);
104 // Create a course, with a forum.
105 $course = $this->getDataGenerator()->create_course();
107 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
108 $forum = $this->getDataGenerator()->create_module('forum', $options);
110 // Create two users enrolled in the course as students.
111 list($author, $recipient) = $this->helper_create_users($course, 2);
113 // Post a discussion to the forum.
114 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
117 'author' => (object) [
118 'userid' => $author->id
,
121 'recipient' => (object) [
122 'userid' => $recipient->id
,
126 $this->queue_tasks_and_assert($expect);
128 $this->messagesink
->close();
129 $this->eventsink
= $this->redirectEvents();
130 $this->send_notifications_and_assert($author, [$post]);
131 $events = $this->eventsink
->get_events();
132 $event = reset($events);
134 $this->assertEquals($course->id
, $event->other
['courseid']);
136 $this->send_notifications_and_assert($recipient, [$post]);
139 public function test_forced_subscription() {
141 $this->resetAfterTest(true);
143 // Create a course, with a forum.
144 $course = $this->getDataGenerator()->create_course();
146 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
147 $forum = $this->getDataGenerator()->create_module('forum', $options);
149 // Create users enrolled in the course as students.
150 list($author, $recipient, $unconfirmed, $deleted) = $this->helper_create_users($course, 4);
152 // Make the third user unconfirmed (thence inactive) to make sure it does not break the notifications.
153 $DB->set_field('user', 'confirmed', 0, ['id' => $unconfirmed->id
]);
155 // Mark the fourth user as deleted to make sure it does not break the notifications.
156 $DB->set_field('user', 'deleted', 1, ['id' => $deleted->id
]);
158 // Post a discussion to the forum.
159 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
163 'userid' => $author->id
,
167 'userid' => $recipient->id
,
171 'userid' => $unconfirmed->id
,
175 'userid' => $deleted->id
,
179 $this->queue_tasks_and_assert($expect);
181 $this->send_notifications_and_assert($author, [$post]);
182 $this->send_notifications_and_assert($recipient, [$post]);
183 $this->send_notifications_and_assert($unconfirmed, []);
184 $this->send_notifications_and_assert($deleted, []);
188 * Ensure that for a forum with subscription disabled that standard users will not receive posts.
190 public function test_subscription_disabled_standard_users() {
193 $this->resetAfterTest(true);
195 // Create a course, with a forum.
196 $course = $this->getDataGenerator()->create_course();
198 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE
);
199 $forum = $this->getDataGenerator()->create_module('forum', $options);
201 // Create two users enrolled in the course as students.
202 list($author, $recipient) = $this->helper_create_users($course, 2);
204 // Post a discussion to the forum.
205 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
207 // Run cron and check that the expected number of users received the notification.
210 'userid' => $author->id
,
214 'userid' => $recipient->id
,
218 $this->queue_tasks_and_assert($expect);
220 $this->send_notifications_and_assert($author, []);
221 $this->send_notifications_and_assert($recipient, []);
225 * Ensure that for a forum with subscription disabled that a user subscribed to the forum will receive the post.
227 public function test_subscription_disabled_user_subscribed_forum() {
230 $this->resetAfterTest(true);
232 // Create a course, with a forum.
233 $course = $this->getDataGenerator()->create_course();
235 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE
);
236 $forum = $this->getDataGenerator()->create_module('forum', $options);
238 // Create two users enrolled in the course as students.
239 list($author, $recipient) = $this->helper_create_users($course, 2);
241 // A user with the manageactivities capability within the course can subscribe.
242 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
243 assign_capability('moodle/course:manageactivities', CAP_ALLOW
, $roleids['student'], context_course
::instance($course->id
));
245 // Suscribe the recipient only.
246 \mod_forum\subscriptions
::subscribe_user($recipient->id
, $forum);
248 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
249 'userid' => $recipient->id
,
250 'forum' => $forum->id
,
253 // Post a discussion to the forum.
254 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
256 // Run cron and check that the expected number of users received the notification.
258 'author' => (object) [
259 'userid' => $author->id
,
261 'recipient' => (object) [
262 'userid' => $recipient->id
,
266 $this->queue_tasks_and_assert($expect);
268 $this->send_notifications_and_assert($author, []);
269 $this->send_notifications_and_assert($recipient, [$post]);
273 * Ensure that for a forum with subscription disabled that a user subscribed to the discussion will receive the
276 public function test_subscription_disabled_user_subscribed_discussion() {
279 $this->resetAfterTest(true);
281 // Create a course, with a forum.
282 $course = $this->getDataGenerator()->create_course();
284 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE
);
285 $forum = $this->getDataGenerator()->create_module('forum', $options);
287 // Create two users enrolled in the course as students.
288 list($author, $recipient) = $this->helper_create_users($course, 2);
290 // A user with the manageactivities capability within the course can subscribe.
291 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
292 assign_capability('moodle/course:manageactivities', CAP_ALLOW
, $roleids['student'], context_course
::instance($course->id
));
294 // Run cron and check that the expected number of users received the notification.
295 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
297 // Subscribe the user to the discussion.
298 \mod_forum\subscriptions
::subscribe_user_to_discussion($recipient->id
, $discussion);
299 $this->helper_update_subscription_time($recipient, $discussion, -60);
301 // Run cron and check that the expected number of users received the notification.
303 'author' => (object) [
304 'userid' => $author->id
,
306 'recipient' => (object) [
307 'userid' => $recipient->id
,
311 $this->queue_tasks_and_assert($expect);
313 $this->send_notifications_and_assert($author, []);
314 $this->send_notifications_and_assert($recipient, [$post]);
318 * Ensure that for a forum with automatic subscription that users receive posts.
320 public function test_automatic() {
321 $this->resetAfterTest(true);
323 // Create a course, with a forum.
324 $course = $this->getDataGenerator()->create_course();
326 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
327 $forum = $this->getDataGenerator()->create_module('forum', $options);
329 // Create two users enrolled in the course as students.
330 list($author, $recipient) = $this->helper_create_users($course, 2);
332 // Post a discussion to the forum.
333 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
337 'userid' => $author->id
,
341 'userid' => $recipient->id
,
345 $this->queue_tasks_and_assert($expect);
347 $this->send_notifications_and_assert($author, [$post]);
348 $this->send_notifications_and_assert($recipient, [$post]);
352 * Ensure that private replies are not sent to users with an automatic subscription unless they are an expected
355 public function test_automatic_with_private_reply() {
356 $this->resetAfterTest(true);
358 // Create a course, with a forum.
359 $course = $this->getDataGenerator()->create_course();
360 $forum = $this->getDataGenerator()->create_module('forum', [
361 'course' => $course->id
,
362 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
,
365 [$student, $otherstudent] = $this->helper_create_users($course, 2, 'student');
366 [$teacher, $otherteacher] = $this->helper_create_users($course, 2, 'teacher');
368 [$discussion, $post] = $this->helper_post_to_forum($forum, $student);
369 $reply = $this->helper_post_to_discussion($forum, $discussion, $teacher, [
370 'privatereplyto' => $student->id
,
373 // The private reply is queued to all messages as reply visibility may change between queueing, and sending.
376 'userid' => $student->id
,
380 'userid' => $otherstudent->id
,
384 'userid' => $teacher->id
,
388 'userid' => $otherteacher->id
,
392 $this->queue_tasks_and_assert($expect);
394 // The actual messages sent will respect private replies.
395 $this->send_notifications_and_assert($student, [$post, $reply]);
396 $this->send_notifications_and_assert($teacher, [$post, $reply]);
397 $this->send_notifications_and_assert($otherteacher, [$post, $reply]);
398 $this->send_notifications_and_assert($otherstudent, [$post]);
401 public function test_optional() {
402 $this->resetAfterTest(true);
404 // Create a course, with a forum.
405 $course = $this->getDataGenerator()->create_course();
407 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
408 $forum = $this->getDataGenerator()->create_module('forum', $options);
410 // Create two users enrolled in the course as students.
411 list($author, $recipient) = $this->helper_create_users($course, 2);
413 // Post a discussion to the forum.
414 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
418 'userid' => $author->id
,
422 'userid' => $recipient->id
,
426 $this->queue_tasks_and_assert($expect);
428 $this->send_notifications_and_assert($author, []);
429 $this->send_notifications_and_assert($recipient, []);
432 public function test_automatic_with_unsubscribed_user() {
433 $this->resetAfterTest(true);
435 // Create a course, with a forum.
436 $course = $this->getDataGenerator()->create_course();
438 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
439 $forum = $this->getDataGenerator()->create_module('forum', $options);
441 // Create two users enrolled in the course as students.
442 list($author, $recipient) = $this->helper_create_users($course, 2);
444 // Unsubscribe the 'author' user from the forum.
445 \mod_forum\subscriptions
::unsubscribe_user($author->id
, $forum);
447 // Post a discussion to the forum.
448 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
452 'userid' => $author->id
,
456 'userid' => $recipient->id
,
460 $this->queue_tasks_and_assert($expect);
462 $this->send_notifications_and_assert($author, []);
463 $this->send_notifications_and_assert($recipient, [$post]);
466 public function test_optional_with_subscribed_user() {
467 $this->resetAfterTest(true);
469 // Create a course, with a forum.
470 $course = $this->getDataGenerator()->create_course();
472 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
473 $forum = $this->getDataGenerator()->create_module('forum', $options);
475 // Create two users enrolled in the course as students.
476 list($author, $recipient) = $this->helper_create_users($course, 2);
478 // Subscribe the 'recipient' user from the forum.
479 \mod_forum\subscriptions
::subscribe_user($recipient->id
, $forum);
481 // Post a discussion to the forum.
482 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
486 'userid' => $author->id
,
490 'userid' => $recipient->id
,
494 $this->queue_tasks_and_assert($expect);
496 $this->send_notifications_and_assert($author, []);
497 $this->send_notifications_and_assert($recipient, [$post]);
500 public function test_automatic_with_unsubscribed_discussion() {
501 $this->resetAfterTest(true);
503 // Create a course, with a forum.
504 $course = $this->getDataGenerator()->create_course();
506 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
507 $forum = $this->getDataGenerator()->create_module('forum', $options);
509 // Create two users enrolled in the course as students.
510 list($author, $recipient) = $this->helper_create_users($course, 2);
512 // Post a discussion to the forum.
513 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
515 // Unsubscribe the 'author' user from the discussion.
516 \mod_forum\subscriptions
::unsubscribe_user_from_discussion($author->id
, $discussion);
518 $this->assertFalse(\mod_forum\subscriptions
::is_subscribed($author->id
, $forum, $discussion->id
));
519 $this->assertTrue(\mod_forum\subscriptions
::is_subscribed($recipient->id
, $forum, $discussion->id
));
523 'userid' => $author->id
,
527 'userid' => $recipient->id
,
531 $this->queue_tasks_and_assert($expect);
533 $this->send_notifications_and_assert($author, []);
534 $this->send_notifications_and_assert($recipient, [$post]);
537 public function test_optional_with_subscribed_discussion() {
538 $this->resetAfterTest(true);
540 // Create a course, with a forum.
541 $course = $this->getDataGenerator()->create_course();
543 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
544 $forum = $this->getDataGenerator()->create_module('forum', $options);
546 // Create two users enrolled in the course as students.
547 list($author, $recipient) = $this->helper_create_users($course, 2);
549 // Post a discussion to the forum.
550 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
551 $this->helper_update_post_time($post, -90);
553 // Subscribe the 'recipient' user to the discussion.
554 \mod_forum\subscriptions
::subscribe_user_to_discussion($recipient->id
, $discussion);
555 $this->helper_update_subscription_time($recipient, $discussion, -60);
557 // Initially we don't expect any user to receive this post as you cannot subscribe to a discussion until after
561 'userid' => $author->id
,
565 'userid' => $recipient->id
,
569 $this->queue_tasks_and_assert($expect);
571 $this->send_notifications_and_assert($author, []);
572 $this->send_notifications_and_assert($recipient, []);
574 // Have a user reply to the discussion.
575 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
576 $this->helper_update_post_time($reply, -30);
578 // We expect only one user to receive this post.
581 'userid' => $author->id
,
585 'userid' => $recipient->id
,
589 $this->queue_tasks_and_assert($expect);
591 $this->send_notifications_and_assert($author, []);
592 $this->send_notifications_and_assert($recipient, [$reply]);
595 public function test_optional_with_subscribed_discussion_and_post() {
596 $this->resetAfterTest(true);
598 // Create a course, with a forum.
599 $course = $this->getDataGenerator()->create_course();
601 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
602 $forum = $this->getDataGenerator()->create_module('forum', $options);
604 // Create two users enrolled in the course as students.
605 list($author, $recipient) = $this->helper_create_users($course, 2);
607 // Post a discussion to the forum.
608 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
609 $this->helper_update_post_time($post, -90);
611 // Have a user reply to the discussion before we subscribed.
612 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
613 $this->helper_update_post_time($reply, -75);
615 // Subscribe the 'recipient' user to the discussion.
616 \mod_forum\subscriptions
::subscribe_user_to_discussion($recipient->id
, $discussion);
617 $this->helper_update_subscription_time($recipient, $discussion, -60);
619 // Have a user reply to the discussion.
620 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
621 $this->helper_update_post_time($reply, -30);
623 // We expect only one user to receive this post.
624 // The original post won't be received as it was written before the user subscribed.
627 'userid' => $author->id
,
631 'userid' => $recipient->id
,
635 $this->queue_tasks_and_assert($expect);
637 $this->send_notifications_and_assert($author, []);
638 $this->send_notifications_and_assert($recipient, [$reply]);
641 public function test_automatic_with_subscribed_discussion_in_unsubscribed_forum() {
642 $this->resetAfterTest(true);
644 // Create a course, with a forum.
645 $course = $this->getDataGenerator()->create_course();
647 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
648 $forum = $this->getDataGenerator()->create_module('forum', $options);
650 // Create two users enrolled in the course as students.
651 list($author, $recipient) = $this->helper_create_users($course, 2);
653 // Post a discussion to the forum.
654 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
655 $this->helper_update_post_time($post, -90);
657 // Unsubscribe the 'author' user from the forum.
658 \mod_forum\subscriptions
::unsubscribe_user($author->id
, $forum);
660 // Then re-subscribe them to the discussion.
661 \mod_forum\subscriptions
::subscribe_user_to_discussion($author->id
, $discussion);
662 $this->helper_update_subscription_time($author, $discussion, -60);
666 'userid' => $author->id
,
670 'userid' => $recipient->id
,
674 $this->queue_tasks_and_assert($expect);
676 $this->send_notifications_and_assert($author, []);
677 $this->send_notifications_and_assert($recipient, [$post]);
679 // Now post a reply to the original post.
680 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
681 $this->helper_update_post_time($reply, -30);
685 'userid' => $author->id
,
689 'userid' => $recipient->id
,
693 $this->queue_tasks_and_assert($expect);
695 $this->send_notifications_and_assert($author, [$reply]);
696 $this->send_notifications_and_assert($recipient, [$reply]);
699 public function test_optional_with_unsubscribed_discussion_in_subscribed_forum() {
700 $this->resetAfterTest(true);
702 // Create a course, with a forum.
703 $course = $this->getDataGenerator()->create_course();
705 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
706 $forum = $this->getDataGenerator()->create_module('forum', $options);
708 // Create two users enrolled in the course as students.
709 list($author, $recipient) = $this->helper_create_users($course, 2);
711 // Post a discussion to the forum.
712 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
714 // Unsubscribe the 'recipient' user from the discussion.
715 \mod_forum\subscriptions
::subscribe_user($recipient->id
, $forum);
717 // Then unsubscribe them from the discussion.
718 \mod_forum\subscriptions
::unsubscribe_user_from_discussion($recipient->id
, $discussion);
720 // We don't expect any users to receive this post.
723 'userid' => $author->id
,
727 'userid' => $recipient->id
,
731 $this->queue_tasks_and_assert($expect);
733 $this->send_notifications_and_assert($author, []);
734 $this->send_notifications_and_assert($recipient, []);
738 * Test that a user unsubscribed from a forum who has subscribed to a discussion, only receives posts made after
739 * they subscribed to the discussion.
741 public function test_forum_discussion_subscription_forum_unsubscribed_discussion_subscribed_after_post() {
742 $this->resetAfterTest(true);
744 // Create a course, with a forum.
745 $course = $this->getDataGenerator()->create_course();
747 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
748 $forum = $this->getDataGenerator()->create_module('forum', $options);
750 $expectedmessages = array();
752 // Create a user enrolled in the course as a student.
753 list($author) = $this->helper_create_users($course, 1);
755 // Post a discussion to the forum.
756 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
757 $this->helper_update_post_time($post, -90);
759 $expectedmessages[] = array(
761 'subject' => $post->subject
,
765 // Then subscribe the user to the discussion.
766 $this->assertTrue(\mod_forum\subscriptions
::subscribe_user_to_discussion($author->id
, $discussion));
767 $this->helper_update_subscription_time($author, $discussion, -60);
769 // Then post a reply to the first discussion.
770 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
771 $this->helper_update_post_time($reply, -30);
775 'userid' => $author->id
,
779 $this->queue_tasks_and_assert($expect);
781 $this->send_notifications_and_assert($author, [$reply]);
784 public function test_subscription_by_inactive_users() {
786 $this->resetAfterTest(true);
788 $course = $this->getDataGenerator()->create_course();
790 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE
);
791 $forum = $this->getDataGenerator()->create_module('forum', $options);
793 // Create two users enrolled in the course as students.
794 list($author, $u1, $u2, $u3) = $this->helper_create_users($course, 4);
796 // Subscribe the three users to the forum.
797 \mod_forum\subscriptions
::subscribe_user($u1->id
, $forum);
798 \mod_forum\subscriptions
::subscribe_user($u2->id
, $forum);
799 \mod_forum\subscriptions
::subscribe_user($u3->id
, $forum);
801 // Make the first user inactive - suspended.
802 $DB->set_field('user', 'suspended', 1, ['id' => $u1->id
]);
804 // Make the second user inactive - unable to log in.
805 $DB->set_field('user', 'auth', 'nologin', ['id' => $u2->id
]);
807 // Post a discussion to the forum.
808 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
825 $this->queue_tasks_and_assert($expect);
826 $this->send_notifications_and_assert($u1, []);
827 $this->send_notifications_and_assert($u2, []);
828 $this->send_notifications_and_assert($u3, [$post]);
831 public function test_forum_message_inbound_multiple_posts() {
832 $this->resetAfterTest(true);
834 // Create a course, with a forum.
835 $course = $this->getDataGenerator()->create_course();
836 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
837 $forum = $this->getDataGenerator()->create_module('forum', $options);
839 // Create a user enrolled in the course as a student.
840 list($author) = $this->helper_create_users($course, 1);
842 $expectedmessages = array();
844 // Post a discussion to the forum.
845 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
846 $this->helper_update_post_time($post, -90);
848 $expectedmessages[] = (object) [
850 'subject' => $post->subject
,
854 // Then post a reply to the first discussion.
855 $reply = $this->helper_post_to_discussion($forum, $discussion, $author);
856 $this->helper_update_post_time($reply, -60);
858 $expectedmessages[] = (object) [
860 'subject' => $reply->subject
,
864 // Ensure that messageinbound is enabled and configured for the forum handler.
865 $this->helper_spoof_message_inbound_setup();
867 $author->emailstop
= '0';
868 set_user_preference('message_provider_mod_forum_posts_loggedoff', 'email', $author);
869 set_user_preference('message_provider_mod_forum_posts_loggedin', 'email', $author);
871 // Run cron and check that the expected number of users received the notification.
872 // Clear the mailsink, and close the messagesink.
873 $this->mailsink
->clear();
874 $this->messagesink
->close();
877 'author' => (object) [
878 'userid' => $author->id
,
879 'messages' => count($expectedmessages),
882 $this->queue_tasks_and_assert($expect);
884 $this->send_notifications_and_assert($author, $expectedmessages);
885 $messages = $this->mailsink
->get_messages();
887 // There should be the expected number of messages.
888 $this->assertEquals(2, count($messages));
890 foreach ($messages as $message) {
891 $this->assertRegExp('/Reply-To: moodlemoodle123\+[^@]*@example.com/', $message->header
);
895 public function test_long_subject() {
896 $this->resetAfterTest(true);
898 // Create a course, with a forum.
899 $course = $this->getDataGenerator()->create_course();
901 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
902 $forum = $this->getDataGenerator()->create_module('forum', $options);
904 // Create a user enrolled in the course as student.
905 list($author) = $this->helper_create_users($course, 1);
907 // Post a discussion to the forum.
908 $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.';
909 $a = (object)array('courseshortname' => $course->shortname
, 'forumname' => $forum->name
, 'subject' => $subject);
910 $expectedsubject = get_string('postmailsubject', 'forum', $a);
911 list($discussion, $post) = $this->helper_post_to_forum($forum, $author, array('name' => $subject));
913 // Run cron and check that the expected number of users received the notification.
915 'author' => (object) [
916 'userid' => $author->id
,
920 $this->queue_tasks_and_assert($expect);
922 $this->send_notifications_and_assert($author, [$post]);
923 $messages = $this->messagesink
->get_messages();
924 $message = reset($messages);
925 $this->assertEquals($author->id
, $message->useridfrom
);
926 $this->assertEquals($expectedsubject, $message->subject
);
930 * Test inital email and reply email subjects
932 public function test_subjects() {
933 $this->resetAfterTest(true);
935 $course = $this->getDataGenerator()->create_course();
937 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
938 $forum = $this->getDataGenerator()->create_module('forum', $options);
940 list($author) = $this->helper_create_users($course, 1);
941 list($commenter) = $this->helper_create_users($course, 1);
943 $strre = get_string('re', 'forum');
945 // New posts should not have Re: in the subject.
946 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
948 'author' => (object) [
949 'userid' => $author->id
,
952 'commenter' => (object) [
953 'userid' => $commenter->id
,
957 $this->queue_tasks_and_assert($expect);
959 $this->send_notifications_and_assert($author, [$post]);
960 $this->send_notifications_and_assert($commenter, [$post]);
961 $messages = $this->messagesink
->get_messages();
962 $this->assertNotContains($strre, $messages[0]->subject
);
963 $this->messagesink
->clear();
965 // Replies should have Re: in the subject.
966 $reply = $this->helper_post_to_discussion($forum, $discussion, $commenter);
969 'author' => (object) [
970 'userid' => $author->id
,
973 'commenter' => (object) [
974 'userid' => $commenter->id
,
978 $this->queue_tasks_and_assert($expect);
980 $this->send_notifications_and_assert($commenter, [$reply]);
981 $this->send_notifications_and_assert($author, [$reply]);
982 $messages = $this->messagesink
->get_messages();
983 $this->assertContains($strre, $messages[0]->subject
);
984 $this->assertContains($strre, $messages[1]->subject
);
988 * dataProvider for test_forum_post_email_templates().
990 public function forum_post_email_templates_provider() {
991 // Base information, we'll build variations based on it.
993 'user' => array('firstname' => 'Love', 'lastname' => 'Moodle', 'mailformat' => 0, 'maildigest' => 0),
994 'course' => array('shortname' => '101', 'fullname' => 'Moodle 101'),
997 'name' => 'Moodle Forum',
998 'forumposts' => array(
1000 'name' => 'Hello Moodle',
1001 'message' => 'Welcome to Moodle',
1002 'messageformat' => FORMAT_MOODLE
,
1003 'attachments' => array(
1005 'filename' => 'example.txt',
1006 'filecontents' => 'Basic information about the course'
1013 'expectations' => array(
1015 'subject' => '.*101.*Hello',
1016 'contents' => array(
1018 '~&(amp|lt|gt|quot|\#039);(?!course)',
1019 'Attachment example.txt:' . PHP_EOL
.
1020 'https://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt' . PHP_EOL
,
1021 'Hello Moodle', 'Moodle Forum', 'Welcome.*Moodle', 'Love Moodle', '1\d1'
1027 // Build the text cases.
1028 $textcases = array('Text mail without ampersands, quotes or lt/gt' => array('data' => $base));
1030 // Single and double quotes everywhere.
1032 $newcase['user']['lastname'] = 'Moodle\'"';
1033 $newcase['course']['shortname'] = '101\'"';
1034 $newcase['forums'][0]['name'] = 'Moodle Forum\'"';
1035 $newcase['forums'][0]['forumposts'][0]['name'] = 'Hello Moodle\'"';
1036 $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle\'"';
1037 $newcase['expectations'][0]['contents'] = array(
1038 'Attachment example.txt:', '~{\$a', '~&(quot|\#039);', 'Love Moodle\'', '101\'', 'Moodle Forum\'"',
1039 'Hello Moodle\'"', 'Welcome to Moodle\'"');
1040 $textcases['Text mail with quotes everywhere'] = array('data' => $newcase);
1042 // Lt and gt everywhere. This case is completely borked because format_string()
1043 // strips tags with $CFG->formatstringstriptags and also escapes < and > (correct
1044 // for web presentation but not for text email). See MDL-19829.
1046 $newcase['user']['lastname'] = 'Moodle>';
1047 $newcase['course']['shortname'] = '101>';
1048 $newcase['forums'][0]['name'] = 'Moodle Forum>';
1049 $newcase['forums'][0]['forumposts'][0]['name'] = 'Hello Moodle>';
1050 $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle>';
1051 $newcase['expectations'][0]['contents'] = array(
1052 'Attachment example.txt:', '~{\$a', '~&gt;', 'Love Moodle>', '101>', 'Moodle Forum>',
1053 'Hello Moodle>', 'Welcome to Moodle>');
1054 $textcases['Text mail with gt and lt everywhere'] = array('data' => $newcase);
1056 // Ampersands everywhere. This case is completely borked because format_string()
1057 // escapes ampersands (correct for web presentation but not for text email). See MDL-19829.
1059 $newcase['user']['lastname'] = 'Moodle&';
1060 $newcase['course']['shortname'] = '101&';
1061 $newcase['forums'][0]['name'] = 'Moodle Forum&';
1062 $newcase['forums'][0]['forumposts'][0]['name'] = 'Hello Moodle&';
1063 $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle&';
1064 $newcase['expectations'][0]['contents'] = array(
1065 'Attachment example.txt:', '~{\$a', '~&amp;', 'Love Moodle&', '101&', 'Moodle Forum&',
1066 'Hello Moodle&', 'Welcome to Moodle&');
1067 $textcases['Text mail with ampersands everywhere'] = array('data' => $newcase);
1069 // Text+image message i.e. @@PLUGINFILE@@ token handling.
1071 $newcase['forums'][0]['forumposts'][0]['name'] = 'Text and image';
1072 $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle, '
1073 .'@@PLUGINFILE@@/Screen%20Shot%202016-03-22%20at%205.54.36%20AM%20%281%29.png !';
1074 $newcase['expectations'][0]['subject'] = '.*101.*Text and image';
1075 $newcase['expectations'][0]['contents'] = array(
1077 '~&(amp|lt|gt|quot|\#039);(?!course)',
1078 'Attachment example.txt:' . PHP_EOL
.
1079 'https://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt' . PHP_EOL
,
1080 'Text and image', 'Moodle Forum',
1081 'Welcome to Moodle, *' . PHP_EOL
. '.*'
1082 .'https://www.example.com/moodle/pluginfile.php/\d+/mod_forum/post/\d+/'
1083 .'Screen%20Shot%202016-03-22%20at%205\.54\.36%20AM%20%281%29\.png *' . PHP_EOL
. '.*!',
1084 'Love Moodle', '1\d1');
1085 $textcases['Text mail with text+image message i.e. @@PLUGINFILE@@ token handling'] = array('data' => $newcase);
1087 // Now the html cases.
1088 $htmlcases = array();
1090 // New base for html cases, no quotes, lts, gts or ampersands.
1092 $htmlbase['user']['mailformat'] = 1;
1093 $htmlbase['expectations'][0]['contents'] = array(
1095 '~&(amp|lt|gt|quot|\#039);(?!course)',
1096 '<div class="attachments">( *\n *)?<a href',
1097 '<div class="subject">\n.*Hello Moodle', '>Moodle Forum', '>Welcome.*Moodle', '>Love Moodle', '>1\d1');
1098 $htmlcases['HTML mail without ampersands, quotes or lt/gt'] = array('data' => $htmlbase);
1100 // Single and double quotes, lt and gt, ampersands everywhere.
1101 $newcase = $htmlbase;
1102 $newcase['user']['lastname'] = 'Moodle\'">&';
1103 $newcase['course']['shortname'] = '101\'">&';
1104 $newcase['forums'][0]['name'] = 'Moodle Forum\'">&';
1105 $newcase['forums'][0]['forumposts'][0]['name'] = 'Hello Moodle\'">&';
1106 $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle\'">&';
1107 $newcase['expectations'][0]['contents'] = array(
1109 '~&(amp|lt|gt|quot|\#039);',
1110 '<div class="attachments">( *\n *)?<a href',
1111 '<div class="subject">\n.*Hello Moodle\'">&', '>Moodle Forum\'">&',
1112 '>Welcome.*Moodle\'">&', '>Love Moodle&\#039;">&', '>101\'">&');
1113 $htmlcases['HTML mail with quotes, gt, lt and ampersand everywhere'] = array('data' => $newcase);
1115 // Text+image message i.e. @@PLUGINFILE@@ token handling.
1116 $newcase = $htmlbase;
1117 $newcase['forums'][0]['forumposts'][0]['name'] = 'HTML text and image';
1118 $newcase['forums'][0]['forumposts'][0]['message'] = '<p>Welcome to Moodle, '
1119 .'<img src="@@PLUGINFILE@@/Screen%20Shot%202016-03-22%20at%205.54.36%20AM%20%281%29.png"'
1120 .' alt="" width="200" height="393" class="img-responsive" />!</p>';
1121 $newcase['expectations'][0]['subject'] = '.*101.*HTML text and image';
1122 $newcase['expectations'][0]['contents'] = array(
1124 '~&(amp|lt|gt|quot|\#039);(?!course)',
1125 '<div class="attachments">( *\n *)?<a href',
1126 '<div class="subject">\n.*HTML text and image', '>Moodle Forum',
1127 '<p>Welcome to Moodle, '
1128 .'<img src="https://www.example.com/moodle/tokenpluginfile.php/[^/]*/\d+/mod_forum/post/\d+/'
1129 .'Screen%20Shot%202016-03-22%20at%205\.54\.36%20AM%20%281%29\.png"'
1130 .' alt="" width="200" height="393" class="img-responsive" />!</p>',
1131 '>Love Moodle', '>1\d1');
1132 $htmlcases['HTML mail with text+image message i.e. @@PLUGINFILE@@ token handling'] = array('data' => $newcase);
1134 return $textcases +
$htmlcases;
1138 * Verify forum emails body using templates to generate the expected results.
1140 * @dataProvider forum_post_email_templates_provider
1141 * @param array $data provider samples.
1143 public function test_forum_post_email_templates($data) {
1146 $this->resetAfterTest();
1148 // Create the course, with the specified options.
1150 foreach ($data['course'] as $option => $value) {
1151 $options[$option] = $value;
1153 $course = $this->getDataGenerator()->create_course($options);
1155 // Create the user, with the specified options and enrol in the course.
1157 foreach ($data['user'] as $option => $value) {
1158 $options[$option] = $value;
1160 $user = $this->getDataGenerator()->create_user($options);
1161 $this->getDataGenerator()->enrol_user($user->id
, $course->id
);
1163 // Create forums, always force susbscribed (for easy), with the specified options.
1165 foreach ($data['forums'] as $dataforum) {
1166 $forumposts = isset($dataforum['forumposts']) ?
$dataforum['forumposts'] : array();
1167 unset($dataforum['forumposts']);
1168 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
1169 foreach ($dataforum as $option => $value) {
1170 $options[$option] = $value;
1172 $forum = $this->getDataGenerator()->create_module('forum', $options);
1174 // Create posts, always for immediate delivery (for easy), with the specified options.
1175 foreach ($forumposts as $forumpost) {
1176 $attachments = isset($forumpost['attachments']) ?
$forumpost['attachments'] : array();
1177 unset($forumpost['attachments']);
1178 $postoptions = array('course' => $course->id
, 'forum' => $forum->id
, 'userid' => $user->id
,
1179 'mailnow' => 1, 'attachment' => !empty($attachments));
1180 foreach ($forumpost as $option => $value) {
1181 $postoptions[$option] = $value;
1183 list($discussion, $post) = $this->helper_post_to_forum($forum, $user, $postoptions);
1184 $posts[$post->subject
] = $post; // Need this to verify cron output.
1186 // Add the attachments to the post.
1188 $fs = get_file_storage();
1189 foreach ($attachments as $attachment) {
1190 $filerecord = array(
1191 'contextid' => context_module
::instance($forum->cmid
)->id
,
1192 'component' => 'mod_forum',
1193 'filearea' => 'attachment',
1194 'itemid' => $post->id
,
1196 'filename' => $attachment['filename']
1198 $fs->create_file_from_string($filerecord, $attachment['filecontents']);
1200 $DB->set_field('forum_posts', 'attachment', '1', array('id' => $post->id
));
1205 // Clear the mailsink and close the messagesink.
1206 // (surely setup should provide us this cleared but...)
1207 $this->mailsink
->clear();
1208 $this->messagesink
->close();
1211 'author' => (object) [
1212 'userid' => $user->id
,
1213 'messages' => count($posts),
1216 $this->queue_tasks_and_assert($expect);
1218 $this->send_notifications_and_assert($user, $posts);
1221 $mails = $this->mailsink
->get_messages();
1223 // Start testing the expectations.
1224 $expectations = $data['expectations'];
1226 // Assert the number is the expected.
1227 $this->assertSame(count($expectations), count($mails));
1229 // Start processing mails, first localizing its expectations, then checking them.
1230 foreach ($mails as $mail) {
1231 // Find the corresponding expectation.
1232 $foundexpectation = null;
1233 foreach ($expectations as $key => $expectation) {
1234 // All expectations must have a subject for matching.
1235 if (!isset($expectation['subject'])) {
1236 $this->fail('Provider expectation missing mandatory subject');
1238 if (preg_match('!' . $expectation['subject'] . '!', $mail->subject
)) {
1239 // If we already had found the expectation, there are non-unique subjects. Fail.
1240 if (isset($foundexpectation)) {
1241 $this->fail('Multiple expectations found (by subject matching). Please make them unique.');
1243 $foundexpectation = $expectation;
1244 unset($expectations[$key]);
1247 // Arrived here, we should have found the expectations.
1248 $this->assertNotEmpty($foundexpectation, 'Expectation not found for the mail');
1250 // If we have found the expectation and have contents to match, let's do it.
1251 if (isset($foundexpectation) and isset($foundexpectation['contents'])) {
1252 $mail->body
= quoted_printable_decode($mail->body
);
1253 if (!is_array($foundexpectation['contents'])) { // Accept both string and array.
1254 $foundexpectation['contents'] = array($foundexpectation['contents']);
1256 foreach ($foundexpectation['contents'] as $content) {
1257 if (strpos($content, '~') !== 0) {
1258 $this->assertRegexp('#' . $content . '#m', $mail->body
);
1260 preg_match('#' . substr($content, 1) . '#m', $mail->body
, $matches);
1261 $this->assertNotRegexp('#' . substr($content, 1) . '#m', $mail->body
);
1267 // Finished, there should not be remaining expectations.
1268 $this->assertCount(0, $expectations);
1272 * Ensure that posts already mailed are not re-sent.
1274 public function test_already_mailed() {
1277 $this->resetAfterTest(true);
1279 // Create a course, with a forum.
1280 $course = $this->getDataGenerator()->create_course();
1282 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1283 $forum = $this->getDataGenerator()->create_module('forum', $options);
1285 // Create two users enrolled in the course as students.
1286 list($author, $recipient) = $this->helper_create_users($course, 2);
1288 // Post a discussion to the forum.
1289 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1290 $DB->set_field('forum_posts', 'mailed', 1);
1292 // No posts shoudl be considered.
1293 $this->queue_tasks_and_assert([]);
1295 // No notifications should be queued.
1296 $this->send_notifications_and_assert($author, []);
1297 $this->send_notifications_and_assert($recipient, []);
1301 * Ensure that posts marked mailnow are not suspect to the maxeditingtime.
1303 public function test_mailnow() {
1306 // Update the maxeditingtime to 1 day so that posts won't be sent.
1307 $CFG->maxeditingtime
= DAYSECS
;
1309 $this->resetAfterTest(true);
1311 // Create a course, with a forum.
1312 $course = $this->getDataGenerator()->create_course();
1314 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1315 $forum = $this->getDataGenerator()->create_module('forum', $options);
1317 // Create two users enrolled in the course as students.
1318 list($author, $recipient) = $this->helper_create_users($course, 2);
1320 // Post a discussion to the forum.
1321 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1323 // Post a discussion to the forum.
1324 list($discussion, $postmailednow) = $this->helper_post_to_forum($forum, $author, ['mailnow' => 1]);
1326 // Only the mailnow post should be considered.
1328 'author' => (object) [
1329 'userid' => $author->id
,
1332 'recipient' => (object) [
1333 'userid' => $recipient->id
,
1337 $this->queue_tasks_and_assert($expect);
1339 // No notifications should be queued.
1340 $this->send_notifications_and_assert($author, [$postmailednow]);
1341 $this->send_notifications_and_assert($recipient, [$postmailednow]);
1345 * Ensure that if a user has no permission to view a post, then it is not sent.
1347 public function test_access_coursemodule_hidden() {
1350 $this->resetAfterTest(true);
1352 // Create a course, with a forum.
1353 $course = $this->getDataGenerator()->create_course();
1355 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1356 $forum = $this->getDataGenerator()->create_module('forum', $options);
1358 // Create two users enrolled in the course as students.
1359 list($author, $recipient) = $this->helper_create_users($course, 2);
1361 // Create one users enrolled in the course as an editing teacher.
1362 list($editor) = $this->helper_create_users($course, 1, 'editingteacher');
1364 // Post a discussion to the forum.
1365 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1367 // Hide the coursemodule.
1368 set_coursemodule_visible($forum->cmid
, 0);
1370 // Only the mailnow post should be considered.
1372 'author' => (object) [
1373 'userid' => $author->id
,
1376 'recipient' => (object) [
1377 'userid' => $recipient->id
,
1380 'editor' => (object) [
1381 'userid' => $editor->id
,
1385 $this->queue_tasks_and_assert($expect);
1387 // No notifications should be queued.
1388 $this->send_notifications_and_assert($author, [], true);
1389 $this->send_notifications_and_assert($recipient, [], true);
1390 $this->send_notifications_and_assert($editor, [$post], true);
1394 * Ensure that if a user loses permission to view a post after it is queued, that it is not sent.
1396 public function test_access_coursemodule_hidden_after_queue() {
1399 $this->resetAfterTest(true);
1401 // Create a course, with a forum.
1402 $course = $this->getDataGenerator()->create_course();
1404 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1405 $forum = $this->getDataGenerator()->create_module('forum', $options);
1407 // Create two users enrolled in the course as students.
1408 list($author, $recipient) = $this->helper_create_users($course, 2);
1410 // Create one users enrolled in the course as an editing teacher.
1411 list($editor) = $this->helper_create_users($course, 1, 'editingteacher');
1413 // Post a discussion to the forum.
1414 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1416 // Only the mailnow post should be considered.
1418 'author' => (object) [
1419 'userid' => $author->id
,
1422 'recipient' => (object) [
1423 'userid' => $recipient->id
,
1426 'editor' => (object) [
1427 'userid' => $editor->id
,
1431 $this->queue_tasks_and_assert($expect);
1433 // Hide the coursemodule.
1434 set_coursemodule_visible($forum->cmid
, 0);
1436 // No notifications should be queued for the students.
1437 $this->send_notifications_and_assert($author, [], true);
1438 $this->send_notifications_and_assert($recipient, [], true);
1440 // The editing teacher should still receive the post.
1441 $this->send_notifications_and_assert($editor, [$post]);
1445 * Ensure that messages are not sent until the timestart.
1447 public function test_access_before_timestart() {
1450 $this->resetAfterTest(true);
1452 // Create a course, with a forum.
1453 $course = $this->getDataGenerator()->create_course();
1455 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1456 $forum = $this->getDataGenerator()->create_module('forum', $options);
1458 // Create two users enrolled in the course as students.
1459 list($author, $recipient) = $this->helper_create_users($course, 2);
1461 // Create one users enrolled in the course as an editing teacher.
1462 list($editor) = $this->helper_create_users($course, 1, 'editingteacher');
1464 // Post a discussion to the forum.
1465 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1467 // Update the discussion to have a timestart in the future.
1468 $DB->set_field('forum_discussions', 'timestart', time() + DAYSECS
);
1470 // None should be sent.
1471 $this->queue_tasks_and_assert([]);
1473 // No notifications should be queued for any user.
1474 $this->send_notifications_and_assert($author, []);
1475 $this->send_notifications_and_assert($recipient, []);
1476 $this->send_notifications_and_assert($editor, []);
1478 // Update the discussion to have a timestart in the past.
1479 $DB->set_field('forum_discussions', 'timestart', time() - DAYSECS
);
1481 // Now should be sent to all.
1483 'author' => (object) [
1484 'userid' => $author->id
,
1487 'recipient' => (object) [
1488 'userid' => $recipient->id
,
1491 'editor' => (object) [
1492 'userid' => $editor->id
,
1496 $this->queue_tasks_and_assert($expect);
1498 // No notifications should be queued for any user.
1499 $this->send_notifications_and_assert($author, [$post]);
1500 $this->send_notifications_and_assert($recipient, [$post]);
1501 $this->send_notifications_and_assert($editor, [$post]);
1505 * Ensure that messages are not sent after the timeend.
1507 public function test_access_after_timeend() {
1510 $this->resetAfterTest(true);
1512 // Create a course, with a forum.
1513 $course = $this->getDataGenerator()->create_course();
1515 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE
);
1516 $forum = $this->getDataGenerator()->create_module('forum', $options);
1518 // Create two users enrolled in the course as students.
1519 list($author, $recipient) = $this->helper_create_users($course, 2);
1521 // Create one users enrolled in the course as an editing teacher.
1522 list($editor) = $this->helper_create_users($course, 1, 'editingteacher');
1524 // Post a discussion to the forum.
1525 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1527 // Update the discussion to have a timestart in the past.
1528 $DB->set_field('forum_discussions', 'timeend', time() - DAYSECS
);
1530 // None should be sent.
1531 $this->queue_tasks_and_assert([]);
1533 // No notifications should be queued for any user.
1534 $this->send_notifications_and_assert($author, []);
1535 $this->send_notifications_and_assert($recipient, []);
1536 $this->send_notifications_and_assert($editor, []);
1538 // Update the discussion to have a timestart in the past.
1539 $DB->set_field('forum_discussions', 'timeend', time() + DAYSECS
);
1541 // Now should be sent to all.
1543 'author' => (object) [
1544 'userid' => $author->id
,
1547 'recipient' => (object) [
1548 'userid' => $recipient->id
,
1551 'editor' => (object) [
1552 'userid' => $editor->id
,
1556 $this->queue_tasks_and_assert($expect);
1558 // No notifications should be queued for any user.
1559 $this->send_notifications_and_assert($author, [$post]);
1560 $this->send_notifications_and_assert($recipient, [$post]);
1561 $this->send_notifications_and_assert($editor, [$post]);
1565 * Test notification comes with customdata.
1567 public function test_notification_customdata() {
1568 $this->resetAfterTest(true);
1570 $course = $this->getDataGenerator()->create_course();
1572 $options = array('course' => $course->id
, 'forcesubscribe' => FORUM_FORCESUBSCRIBE
);
1573 $forum = $this->getDataGenerator()->create_module('forum', $options);
1575 list($author) = $this->helper_create_users($course, 1);
1576 list($commenter) = $this->helper_create_users($course, 1);
1578 $strre = get_string('re', 'forum');
1580 // New posts should not have Re: in the subject.
1581 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1583 'author' => (object) [
1584 'userid' => $author->id
,
1587 'commenter' => (object) [
1588 'userid' => $commenter->id
,
1592 $this->queue_tasks_and_assert($expect);
1594 $this->send_notifications_and_assert($author, [$post]);
1595 $this->send_notifications_and_assert($commenter, [$post]);
1596 $messages = $this->messagesink
->get_messages();
1597 $customdata = json_decode($messages[0]->customdata
);
1598 $this->assertEquals($forum->id
, $customdata->instance
);
1599 $this->assertEquals($forum->cmid
, $customdata->cmid
);
1600 $this->assertEquals($post->id
, $customdata->postid
);
1601 $this->assertEquals($discussion->id
, $customdata->discussionid
);
1602 $this->assertObjectHasAttribute('notificationiconurl', $customdata);
1603 $this->assertObjectHasAttribute('actionbuttons', $customdata);
1604 $this->assertCount(1, (array) $customdata->actionbuttons
);