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 module forums tests
21 * @copyright 2013 Frédéric Massart
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die();
28 require_once($CFG->dirroot . '/mod/forum/lib.php');
30 class mod_forum_subscriptions_testcase extends advanced_testcase {
35 public function setUp() {
36 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
37 // tests using these functions.
38 \mod_forum\subscriptions::reset_forum_cache();
39 \mod_forum\subscriptions::reset_discussion_cache();
45 public function tearDown() {
46 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
47 // tests using these functions.
48 \mod_forum\subscriptions::reset_forum_cache();
49 \mod_forum\subscriptions::reset_discussion_cache();
53 * Helper to create the required number of users in the specified
55 * Users are enrolled as students.
57 * @param stdClass $course The course object
58 * @param integer $count The number of users to create
59 * @return array The users created
61 protected function helper_create_users($course, $count) {
64 for ($i = 0; $i < $count; $i++) {
65 $user = $this->getDataGenerator()->create_user();
66 $this->getDataGenerator()->enrol_user($user->id, $course->id);
74 * Create a new discussion and post within the specified forum, as the
77 * @param stdClass $forum The forum to post in
78 * @param stdClass $author The author to post as
79 * @param array An array containing the discussion object, and the post object
81 protected function helper_post_to_forum($forum, $author) {
83 $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
85 // Create a discussion in the forum, and then add a post to that discussion.
86 $record = new stdClass();
87 $record->course = $forum->course;
88 $record->userid = $author->id;
89 $record->forum = $forum->id;
90 $discussion = $generator->create_discussion($record);
92 // Retrieve the post which was created by create_discussion.
93 $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
95 return array($discussion, $post);
98 public function test_subscription_modes() {
101 $this->resetAfterTest(true);
103 // Create a course, with a forum.
104 $course = $this->getDataGenerator()->create_course();
106 $options = array('course' => $course->id);
107 $forum = $this->getDataGenerator()->create_module('forum', $options);
109 \mod_forum\subscriptions::set_subscription_mode($forum->id, FORUM_FORCESUBSCRIBE);
110 $forum = $DB->get_record('forum', array('id' => $forum->id));
111 $this->assertEquals(FORUM_FORCESUBSCRIBE, \mod_forum\subscriptions::get_subscription_mode($forum));
112 $this->assertTrue(\mod_forum\subscriptions::is_forcesubscribed($forum));
113 $this->assertFalse(\mod_forum\subscriptions::is_subscribable($forum));
114 $this->assertFalse(\mod_forum\subscriptions::subscription_disabled($forum));
116 \mod_forum\subscriptions::set_subscription_mode($forum->id, FORUM_DISALLOWSUBSCRIBE);
117 $forum = $DB->get_record('forum', array('id' => $forum->id));
118 $this->assertEquals(FORUM_DISALLOWSUBSCRIBE, \mod_forum\subscriptions::get_subscription_mode($forum));
119 $this->assertTrue(\mod_forum\subscriptions::subscription_disabled($forum));
120 $this->assertFalse(\mod_forum\subscriptions::is_subscribable($forum));
121 $this->assertFalse(\mod_forum\subscriptions::is_forcesubscribed($forum));
123 \mod_forum\subscriptions::set_subscription_mode($forum->id, FORUM_INITIALSUBSCRIBE);
124 $forum = $DB->get_record('forum', array('id' => $forum->id));
125 $this->assertEquals(FORUM_INITIALSUBSCRIBE, \mod_forum\subscriptions::get_subscription_mode($forum));
126 $this->assertTrue(\mod_forum\subscriptions::is_subscribable($forum));
127 $this->assertFalse(\mod_forum\subscriptions::subscription_disabled($forum));
128 $this->assertFalse(\mod_forum\subscriptions::is_forcesubscribed($forum));
130 \mod_forum\subscriptions::set_subscription_mode($forum->id, FORUM_CHOOSESUBSCRIBE);
131 $forum = $DB->get_record('forum', array('id' => $forum->id));
132 $this->assertEquals(FORUM_CHOOSESUBSCRIBE, \mod_forum\subscriptions::get_subscription_mode($forum));
133 $this->assertTrue(\mod_forum\subscriptions::is_subscribable($forum));
134 $this->assertFalse(\mod_forum\subscriptions::subscription_disabled($forum));
135 $this->assertFalse(\mod_forum\subscriptions::is_forcesubscribed($forum));
139 * Test fetching unsubscribable forums.
141 public function test_unsubscribable_forums() {
144 $this->resetAfterTest(true);
146 // Create a course, with a forum.
147 $course = $this->getDataGenerator()->create_course();
149 // Create a user enrolled in the course as a student.
150 list($user) = $this->helper_create_users($course, 1);
152 // Must be logged in as the current user.
153 $this->setUser($user);
155 // Without any subscriptions, there should be nothing returned.
156 $result = \mod_forum\subscriptions::get_unsubscribable_forums();
157 $this->assertEquals(0, count($result));
159 // Create the forums.
160 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
161 $forceforum = $this->getDataGenerator()->create_module('forum', $options);
162 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE);
163 $disallowforum = $this->getDataGenerator()->create_module('forum', $options);
164 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
165 $chooseforum = $this->getDataGenerator()->create_module('forum', $options);
166 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
167 $initialforum = $this->getDataGenerator()->create_module('forum', $options);
169 // At present the user is only subscribed to the initial forum.
170 $result = \mod_forum\subscriptions::get_unsubscribable_forums();
171 $this->assertEquals(1, count($result));
173 // Ensure that the user is enrolled in all of the forums except force subscribed.
174 \mod_forum\subscriptions::subscribe_user($user->id, $disallowforum);
175 \mod_forum\subscriptions::subscribe_user($user->id, $chooseforum);
177 $result = \mod_forum\subscriptions::get_unsubscribable_forums();
178 $this->assertEquals(3, count($result));
181 set_coursemodule_visible($forceforum->cmid, 0);
182 set_coursemodule_visible($disallowforum->cmid, 0);
183 set_coursemodule_visible($chooseforum->cmid, 0);
184 set_coursemodule_visible($initialforum->cmid, 0);
185 $result = \mod_forum\subscriptions::get_unsubscribable_forums();
186 $this->assertEquals(0, count($result));
188 // Add the moodle/course:viewhiddenactivities capability to the student user.
189 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
190 $context = \context_course::instance($course->id);
191 assign_capability('moodle/course:viewhiddenactivities', CAP_ALLOW, $roleids['student'], $context);
192 $context->mark_dirty();
194 // All of the unsubscribable forums should now be listed.
195 $result = \mod_forum\subscriptions::get_unsubscribable_forums();
196 $this->assertEquals(3, count($result));
200 * Test that toggling the forum-level subscription for a different user does not affect their discussion-level
203 public function test_forum_subscribe_toggle_as_other() {
206 $this->resetAfterTest(true);
208 // Create a course, with a forum.
209 $course = $this->getDataGenerator()->create_course();
211 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
212 $forum = $this->getDataGenerator()->create_module('forum', $options);
214 // Create a user enrolled in the course as a student.
215 list($author) = $this->helper_create_users($course, 1);
217 // Post a discussion to the forum.
218 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
220 // Check that the user is currently not subscribed to the forum.
221 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
223 // Check that the user is unsubscribed from the discussion too.
224 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
226 // Check that we have no records in either of the subscription tables.
227 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
228 'userid' => $author->id,
229 'forum' => $forum->id,
231 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
232 'userid' => $author->id,
233 'discussion' => $discussion->id,
236 // Subscribing to the forum should create a record in the subscriptions table, but not the forum discussion
237 // subscriptions table.
238 \mod_forum\subscriptions::subscribe_user($author->id, $forum);
239 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
240 'userid' => $author->id,
241 'forum' => $forum->id,
243 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
244 'userid' => $author->id,
245 'discussion' => $discussion->id,
248 // Unsubscribing should remove the record from the forum subscriptions table, and not modify the forum
249 // discussion subscriptions table.
250 \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
251 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
252 'userid' => $author->id,
253 'forum' => $forum->id,
255 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
256 'userid' => $author->id,
257 'discussion' => $discussion->id,
260 // Enroling the user in the discussion should add one record to the forum discussion table without modifying the
261 // form subscriptions.
262 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
263 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
264 'userid' => $author->id,
265 'forum' => $forum->id,
267 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
268 'userid' => $author->id,
269 'discussion' => $discussion->id,
272 // Unsubscribing should remove the record from the forum subscriptions table, and not modify the forum
273 // discussion subscriptions table.
274 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
275 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
276 'userid' => $author->id,
277 'forum' => $forum->id,
279 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
280 'userid' => $author->id,
281 'discussion' => $discussion->id,
284 // Re-subscribe to the discussion so that we can check the effect of forum-level subscriptions.
285 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
286 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
287 'userid' => $author->id,
288 'forum' => $forum->id,
290 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
291 'userid' => $author->id,
292 'discussion' => $discussion->id,
295 // Subscribing to the forum should have no effect on the forum discussion subscriptions table if the user did
296 // not request the change themself.
297 \mod_forum\subscriptions::subscribe_user($author->id, $forum);
298 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
299 'userid' => $author->id,
300 'forum' => $forum->id,
302 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
303 'userid' => $author->id,
304 'discussion' => $discussion->id,
307 // Unsubscribing from the forum should have no effect on the forum discussion subscriptions table if the user
308 // did not request the change themself.
309 \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
310 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
311 'userid' => $author->id,
312 'forum' => $forum->id,
314 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
315 'userid' => $author->id,
316 'discussion' => $discussion->id,
319 // Subscribing to the forum should remove the per-discussion subscription preference if the user requested the
321 \mod_forum\subscriptions::subscribe_user($author->id, $forum, null, true);
322 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
323 'userid' => $author->id,
324 'forum' => $forum->id,
326 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
327 'userid' => $author->id,
328 'discussion' => $discussion->id,
331 // Now unsubscribe from the current discussion whilst being subscribed to the forum as a whole.
332 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
333 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
334 'userid' => $author->id,
335 'forum' => $forum->id,
337 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
338 'userid' => $author->id,
339 'discussion' => $discussion->id,
342 // Unsubscribing from the forum should remove the per-discussion subscription preference if the user requested the
344 \mod_forum\subscriptions::unsubscribe_user($author->id, $forum, null, true);
345 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
346 'userid' => $author->id,
347 'forum' => $forum->id,
349 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
350 'userid' => $author->id,
351 'discussion' => $discussion->id,
354 // Subscribe to the discussion.
355 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
356 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
357 'userid' => $author->id,
358 'forum' => $forum->id,
360 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
361 'userid' => $author->id,
362 'discussion' => $discussion->id,
365 // Subscribe to the forum without removing the discussion preferences.
366 \mod_forum\subscriptions::subscribe_user($author->id, $forum);
367 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
368 'userid' => $author->id,
369 'forum' => $forum->id,
371 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
372 'userid' => $author->id,
373 'discussion' => $discussion->id,
376 // Unsubscribing from the discussion should result in a change.
377 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
378 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
379 'userid' => $author->id,
380 'forum' => $forum->id,
382 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
383 'userid' => $author->id,
384 'discussion' => $discussion->id,
390 * Test that a user unsubscribed from a forum is not subscribed to it's discussions by default.
392 public function test_forum_discussion_subscription_forum_unsubscribed() {
393 $this->resetAfterTest(true);
395 // Create a course, with a forum.
396 $course = $this->getDataGenerator()->create_course();
398 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
399 $forum = $this->getDataGenerator()->create_module('forum', $options);
401 // Create users enrolled in the course as students.
402 list($author) = $this->helper_create_users($course, 1);
404 // Check that the user is currently not subscribed to the forum.
405 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
407 // Post a discussion to the forum.
408 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
410 // Check that the user is unsubscribed from the discussion too.
411 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
415 * Test that the act of subscribing to a forum subscribes the user to it's discussions by default.
417 public function test_forum_discussion_subscription_forum_subscribed() {
418 $this->resetAfterTest(true);
420 // Create a course, with a forum.
421 $course = $this->getDataGenerator()->create_course();
423 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
424 $forum = $this->getDataGenerator()->create_module('forum', $options);
426 // Create users enrolled in the course as students.
427 list($author) = $this->helper_create_users($course, 1);
429 // Enrol the user in the forum.
430 // If a subscription was added, we get the record ID.
431 $this->assertInternalType('int', \mod_forum\subscriptions::subscribe_user($author->id, $forum));
433 // If we already have a subscription when subscribing the user, we get a boolean (true).
434 $this->assertTrue(\mod_forum\subscriptions::subscribe_user($author->id, $forum));
436 // Check that the user is currently subscribed to the forum.
437 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
439 // Post a discussion to the forum.
440 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
442 // Check that the user is subscribed to the discussion too.
443 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
447 * Test that a user unsubscribed from a forum can be subscribed to a discussion.
449 public function test_forum_discussion_subscription_forum_unsubscribed_discussion_subscribed() {
450 $this->resetAfterTest(true);
452 // Create a course, with a forum.
453 $course = $this->getDataGenerator()->create_course();
455 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
456 $forum = $this->getDataGenerator()->create_module('forum', $options);
458 // Create a user enrolled in the course as a student.
459 list($author) = $this->helper_create_users($course, 1);
461 // Check that the user is currently not subscribed to the forum.
462 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
464 // Post a discussion to the forum.
465 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
467 // Attempting to unsubscribe from the discussion should not make a change.
468 $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion));
470 // Then subscribe them to the discussion.
471 $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
473 // Check that the user is still unsubscribed from the forum.
474 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
476 // But subscribed to the discussion.
477 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
481 * Test that a user subscribed to a forum can be unsubscribed from a discussion.
483 public function test_forum_discussion_subscription_forum_subscribed_discussion_unsubscribed() {
484 $this->resetAfterTest(true);
486 // Create a course, with a forum.
487 $course = $this->getDataGenerator()->create_course();
489 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
490 $forum = $this->getDataGenerator()->create_module('forum', $options);
492 // Create two users enrolled in the course as students.
493 list($author) = $this->helper_create_users($course, 2);
495 // Enrol the student in the forum.
496 \mod_forum\subscriptions::subscribe_user($author->id, $forum);
498 // Check that the user is currently subscribed to the forum.
499 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
501 // Post a discussion to the forum.
502 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
504 // Then unsubscribe them from the discussion.
505 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
507 // Check that the user is still subscribed to the forum.
508 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
510 // But unsubscribed from the discussion.
511 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
515 * Test the effect of toggling the discussion subscription status when subscribed to the forum.
517 public function test_forum_discussion_toggle_forum_subscribed() {
520 $this->resetAfterTest(true);
522 // Create a course, with a forum.
523 $course = $this->getDataGenerator()->create_course();
525 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
526 $forum = $this->getDataGenerator()->create_module('forum', $options);
528 // Create two users enrolled in the course as students.
529 list($author) = $this->helper_create_users($course, 2);
531 // Enrol the student in the forum.
532 \mod_forum\subscriptions::subscribe_user($author->id, $forum);
534 // Check that the user is currently subscribed to the forum.
535 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
537 // Post a discussion to the forum.
538 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
540 // Check that the user is initially subscribed to that discussion.
541 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
543 // An attempt to subscribe again should result in a falsey return to indicate that no change was made.
544 $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
546 // And there should be no discussion subscriptions (and one forum subscription).
547 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
548 'userid' => $author->id,
549 'discussion' => $discussion->id,
551 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
552 'userid' => $author->id,
553 'forum' => $forum->id,
556 // Then unsubscribe them from the discussion.
557 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
559 // Check that the user is still subscribed to the forum.
560 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
562 // An attempt to unsubscribe again should result in a falsey return to indicate that no change was made.
563 $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion));
565 // And there should be a discussion subscriptions (and one forum subscription).
566 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
567 'userid' => $author->id,
568 'discussion' => $discussion->id,
570 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
571 'userid' => $author->id,
572 'forum' => $forum->id,
575 // But unsubscribed from the discussion.
576 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
578 // There should be a record in the discussion subscription tracking table.
579 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
580 'userid' => $author->id,
581 'discussion' => $discussion->id,
584 // And one in the forum subscription tracking table.
585 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
586 'userid' => $author->id,
587 'forum' => $forum->id,
590 // Now subscribe the user again to the discussion.
591 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
593 // Check that the user is still subscribed to the forum.
594 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
596 // And is subscribed to the discussion again.
597 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
599 // There should be no record in the discussion subscription tracking table.
600 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
601 'userid' => $author->id,
602 'discussion' => $discussion->id,
605 // And one in the forum subscription tracking table.
606 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
607 'userid' => $author->id,
608 'forum' => $forum->id,
611 // And unsubscribe again.
612 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
614 // Check that the user is still subscribed to the forum.
615 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
617 // But unsubscribed from the discussion.
618 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
620 // There should be a record in the discussion subscription tracking table.
621 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
622 'userid' => $author->id,
623 'discussion' => $discussion->id,
626 // And one in the forum subscription tracking table.
627 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
628 'userid' => $author->id,
629 'forum' => $forum->id,
632 // And subscribe the user again to the discussion.
633 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
635 // Check that the user is still subscribed to the forum.
636 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
637 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
639 // And is subscribed to the discussion again.
640 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
642 // There should be no record in the discussion subscription tracking table.
643 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
644 'userid' => $author->id,
645 'discussion' => $discussion->id,
648 // And one in the forum subscription tracking table.
649 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
650 'userid' => $author->id,
651 'forum' => $forum->id,
654 // And unsubscribe again.
655 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
657 // Check that the user is still subscribed to the forum.
658 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
660 // But unsubscribed from the discussion.
661 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
663 // There should be a record in the discussion subscription tracking table.
664 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
665 'userid' => $author->id,
666 'discussion' => $discussion->id,
669 // And one in the forum subscription tracking table.
670 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
671 'userid' => $author->id,
672 'forum' => $forum->id,
675 // Now unsubscribe the user from the forum.
676 $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user($author->id, $forum, null, true));
678 // This removes both the forum_subscriptions, and the forum_discussion_subs records.
679 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
680 'userid' => $author->id,
681 'discussion' => $discussion->id,
683 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
684 'userid' => $author->id,
685 'forum' => $forum->id,
688 // And should have reset the discussion cache value.
689 $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $author->id);
690 $this->assertInternalType('array', $result);
691 $this->assertFalse(isset($result[$discussion->id]));
695 * Test the effect of toggling the discussion subscription status when unsubscribed from the forum.
697 public function test_forum_discussion_toggle_forum_unsubscribed() {
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) = $this->helper_create_users($course, 2);
711 // Check that the user is currently unsubscribed to the forum.
712 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
714 // Post a discussion to the forum.
715 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
717 // Check that the user is initially unsubscribed to that discussion.
718 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
720 // Then subscribe them to the discussion.
721 $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
723 // An attempt to subscribe again should result in a falsey return to indicate that no change was made.
724 $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
726 // Check that the user is still unsubscribed from the forum.
727 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
729 // But subscribed to the discussion.
730 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
732 // There should be a record in the discussion subscription tracking table.
733 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
734 'userid' => $author->id,
735 'discussion' => $discussion->id,
738 // Now unsubscribe the user again from the discussion.
739 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
741 // Check that the user is still unsubscribed from the forum.
742 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
744 // And is unsubscribed from the discussion again.
745 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
747 // There should be no record in the discussion subscription tracking table.
748 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
749 'userid' => $author->id,
750 'discussion' => $discussion->id,
753 // And subscribe the user again to the discussion.
754 \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
756 // Check that the user is still unsubscribed from the forum.
757 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
759 // And is subscribed to the discussion again.
760 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
762 // There should be a record in the discussion subscription tracking table.
763 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
764 'userid' => $author->id,
765 'discussion' => $discussion->id,
768 // And unsubscribe again.
769 \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
771 // Check that the user is still unsubscribed from the forum.
772 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
774 // But unsubscribed from the discussion.
775 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
777 // There should be no record in the discussion subscription tracking table.
778 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
779 'userid' => $author->id,
780 'discussion' => $discussion->id,
785 * Test that the correct users are returned when fetching subscribed users from a forum where users can choose to
786 * subscribe and unsubscribe.
788 public function test_fetch_subscribed_users_subscriptions() {
791 $this->resetAfterTest(true);
793 // Create a course, with a forum. where users are initially subscribed.
794 $course = $this->getDataGenerator()->create_course();
795 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
796 $forum = $this->getDataGenerator()->create_module('forum', $options);
798 // Create some user enrolled in the course as a student.
800 $users = $this->helper_create_users($course, $usercount);
802 // All users should be subscribed.
803 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
804 $this->assertEquals($usercount, count($subscribers));
806 // Subscribe the guest user too to the forum - they should never be returned by this function.
807 $this->getDataGenerator()->enrol_user($CFG->siteguest, $course->id);
808 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
809 $this->assertEquals($usercount, count($subscribers));
811 // Unsubscribe 2 users.
812 $unsubscribedcount = 2;
813 for ($i = 0; $i < $unsubscribedcount; $i++) {
814 \mod_forum\subscriptions::unsubscribe_user($users[$i]->id, $forum);
817 // The subscription count should now take into account those users who have been unsubscribed.
818 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
819 $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
823 * Test that the correct users are returned hwen fetching subscribed users from a forum where users are forcibly
826 public function test_fetch_subscribed_users_forced() {
829 $this->resetAfterTest(true);
831 // Create a course, with a forum. where users are initially subscribed.
832 $course = $this->getDataGenerator()->create_course();
833 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
834 $forum = $this->getDataGenerator()->create_module('forum', $options);
836 // Create some user enrolled in the course as a student.
838 $users = $this->helper_create_users($course, $usercount);
840 // All users should be subscribed.
841 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
842 $this->assertEquals($usercount, count($subscribers));
846 * Test that unusual combinations of discussion subscriptions do not affect the subscribed user list.
848 public function test_fetch_subscribed_users_discussion_subscriptions() {
851 $this->resetAfterTest(true);
853 // Create a course, with a forum. where users are initially subscribed.
854 $course = $this->getDataGenerator()->create_course();
855 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
856 $forum = $this->getDataGenerator()->create_module('forum', $options);
858 // Create some user enrolled in the course as a student.
860 $users = $this->helper_create_users($course, $usercount);
862 list($discussion, $post) = $this->helper_post_to_forum($forum, $users[0]);
864 // All users should be subscribed.
865 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
866 $this->assertEquals($usercount, count($subscribers));
867 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
868 $this->assertEquals($usercount, count($subscribers));
870 \mod_forum\subscriptions::unsubscribe_user_from_discussion($users[0]->id, $discussion);
872 // All users should be subscribed.
873 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
874 $this->assertEquals($usercount, count($subscribers));
876 // All users should be subscribed.
877 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
878 $this->assertEquals($usercount, count($subscribers));
880 // Manually insert an extra subscription for one of the users.
881 $record = new stdClass();
882 $record->userid = $users[2]->id;
883 $record->forum = $forum->id;
884 $record->discussion = $discussion->id;
885 $record->preference = time();
886 $DB->insert_record('forum_discussion_subs', $record);
888 // The discussion count should not have changed.
889 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
890 $this->assertEquals($usercount, count($subscribers));
891 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
892 $this->assertEquals($usercount, count($subscribers));
894 // Unsubscribe 2 users.
895 $unsubscribedcount = 2;
896 for ($i = 0; $i < $unsubscribedcount; $i++) {
897 \mod_forum\subscriptions::unsubscribe_user($users[$i]->id, $forum);
900 // The subscription count should now take into account those users who have been unsubscribed.
901 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
902 $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
903 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
904 $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
906 // Now subscribe one of those users back to the discussion.
907 $subscribeddiscussionusers = 1;
908 for ($i = 0; $i < $subscribeddiscussionusers; $i++) {
909 \mod_forum\subscriptions::subscribe_user_to_discussion($users[$i]->id, $discussion);
911 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
912 $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
913 $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
914 $this->assertEquals($usercount - $unsubscribedcount + $subscribeddiscussionusers, count($subscribers));
918 * Test whether a user is force-subscribed to a forum.
920 public function test_force_subscribed_to_forum() {
923 $this->resetAfterTest(true);
925 // Create a course, with a forum.
926 $course = $this->getDataGenerator()->create_course();
928 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
929 $forum = $this->getDataGenerator()->create_module('forum', $options);
931 // Create a user enrolled in the course as a student.
932 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
933 $user = $this->getDataGenerator()->create_user();
934 $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleids['student']);
936 // Check that the user is currently subscribed to the forum.
937 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
939 // Remove the allowforcesubscribe capability from the user.
940 $cm = get_coursemodule_from_instance('forum', $forum->id);
941 $context = \context_module::instance($cm->id);
942 assign_capability('mod/forum:allowforcesubscribe', CAP_PROHIBIT, $roleids['student'], $context);
943 $context->mark_dirty();
944 $this->assertFalse(has_capability('mod/forum:allowforcesubscribe', $context, $user->id));
946 // Check that the user is no longer subscribed to the forum.
947 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
951 * Test that the subscription cache can be pre-filled.
953 public function test_subscription_cache_prefill() {
956 $this->resetAfterTest(true);
958 // Create a course, with a forum.
959 $course = $this->getDataGenerator()->create_course();
961 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
962 $forum = $this->getDataGenerator()->create_module('forum', $options);
964 // Create some users.
965 $users = $this->helper_create_users($course, 20);
967 // Reset the subscription cache.
968 \mod_forum\subscriptions::reset_forum_cache();
970 // Filling the subscription cache should only use a single query.
971 $startcount = $DB->perf_get_reads();
972 $this->assertNull(\mod_forum\subscriptions::fill_subscription_cache($forum->id));
973 $postfillcount = $DB->perf_get_reads();
974 $this->assertEquals(1, $postfillcount - $startcount);
976 // Now fetch some subscriptions from that forum - these should use
977 // the cache and not perform additional queries.
978 foreach ($users as $user) {
979 $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($forum->id, $user->id));
981 $finalcount = $DB->perf_get_reads();
982 $this->assertEquals(0, $finalcount - $postfillcount);
986 * Test that the subscription cache can filled user-at-a-time.
988 public function test_subscription_cache_fill() {
991 $this->resetAfterTest(true);
993 // Create a course, with a forum.
994 $course = $this->getDataGenerator()->create_course();
996 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
997 $forum = $this->getDataGenerator()->create_module('forum', $options);
999 // Create some users.
1000 $users = $this->helper_create_users($course, 20);
1002 // Reset the subscription cache.
1003 \mod_forum\subscriptions::reset_forum_cache();
1005 // Filling the subscription cache should only use a single query.
1006 $startcount = $DB->perf_get_reads();
1008 // Fetch some subscriptions from that forum - these should not use the cache and will perform additional queries.
1009 foreach ($users as $user) {
1010 $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($forum->id, $user->id));
1012 $finalcount = $DB->perf_get_reads();
1013 $this->assertEquals(20, $finalcount - $startcount);
1017 * Test that the discussion subscription cache can filled course-at-a-time.
1019 public function test_discussion_subscription_cache_fill_for_course() {
1022 $this->resetAfterTest(true);
1024 // Create a course, with a forum.
1025 $course = $this->getDataGenerator()->create_course();
1027 // Create the forums.
1028 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE);
1029 $disallowforum = $this->getDataGenerator()->create_module('forum', $options);
1030 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1031 $chooseforum = $this->getDataGenerator()->create_module('forum', $options);
1032 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1033 $initialforum = $this->getDataGenerator()->create_module('forum', $options);
1035 // Create some users and keep a reference to the first user.
1036 $users = $this->helper_create_users($course, 20);
1037 $user = reset($users);
1039 // Reset the subscription caches.
1040 \mod_forum\subscriptions::reset_forum_cache();
1042 $startcount = $DB->perf_get_reads();
1043 $result = \mod_forum\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
1044 $this->assertNull($result);
1045 $postfillcount = $DB->perf_get_reads();
1046 $this->assertEquals(1, $postfillcount - $startcount);
1047 $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($disallowforum->id, $user->id));
1048 $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($chooseforum->id, $user->id));
1049 $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($initialforum->id, $user->id));
1050 $finalcount = $DB->perf_get_reads();
1051 $this->assertEquals(0, $finalcount - $postfillcount);
1053 // Test for all users.
1054 foreach ($users as $user) {
1055 $result = \mod_forum\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
1056 $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($disallowforum->id, $user->id));
1057 $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($chooseforum->id, $user->id));
1058 $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($initialforum->id, $user->id));
1060 $finalcount = $DB->perf_get_reads();
1061 $this->assertEquals(count($users), $finalcount - $postfillcount);
1065 * Test that the discussion subscription cache can be forcibly updated for a user.
1067 public function test_discussion_subscription_cache_prefill() {
1070 $this->resetAfterTest(true);
1072 // Create a course, with a forum.
1073 $course = $this->getDataGenerator()->create_course();
1075 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1076 $forum = $this->getDataGenerator()->create_module('forum', $options);
1078 // Create some users.
1079 $users = $this->helper_create_users($course, 20);
1081 // Post some discussions to the forum.
1082 $discussions = array();
1083 $author = $users[0];
1084 for ($i = 0; $i < 20; $i++) {
1085 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1086 $discussions[] = $discussion;
1089 // Unsubscribe half the users from the half the discussions.
1092 foreach ($discussions as $data) {
1093 if ($forumcount % 2) {
1096 foreach ($users as $user) {
1097 if ($usercount % 2) {
1100 \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
1106 // Reset the subscription caches.
1107 \mod_forum\subscriptions::reset_forum_cache();
1108 \mod_forum\subscriptions::reset_discussion_cache();
1110 // Filling the discussion subscription cache should only use a single query.
1111 $startcount = $DB->perf_get_reads();
1112 $this->assertNull(\mod_forum\subscriptions::fill_discussion_subscription_cache($forum->id));
1113 $postfillcount = $DB->perf_get_reads();
1114 $this->assertEquals(1, $postfillcount - $startcount);
1116 // Now fetch some subscriptions from that forum - these should use
1117 // the cache and not perform additional queries.
1118 foreach ($users as $user) {
1119 $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $user->id);
1120 $this->assertInternalType('array', $result);
1122 $finalcount = $DB->perf_get_reads();
1123 $this->assertEquals(0, $finalcount - $postfillcount);
1127 * Test that the discussion subscription cache can filled user-at-a-time.
1129 public function test_discussion_subscription_cache_fill() {
1132 $this->resetAfterTest(true);
1134 // Create a course, with a forum.
1135 $course = $this->getDataGenerator()->create_course();
1137 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1138 $forum = $this->getDataGenerator()->create_module('forum', $options);
1140 // Create some users.
1141 $users = $this->helper_create_users($course, 20);
1143 // Post some discussions to the forum.
1144 $discussions = array();
1145 $author = $users[0];
1146 for ($i = 0; $i < 20; $i++) {
1147 list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1148 $discussions[] = $discussion;
1151 // Unsubscribe half the users from the half the discussions.
1154 foreach ($discussions as $data) {
1155 if ($forumcount % 2) {
1158 foreach ($users as $user) {
1159 if ($usercount % 2) {
1162 \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
1168 // Reset the subscription caches.
1169 \mod_forum\subscriptions::reset_forum_cache();
1170 \mod_forum\subscriptions::reset_discussion_cache();
1172 $startcount = $DB->perf_get_reads();
1174 // Now fetch some subscriptions from that forum - these should use
1175 // the cache and not perform additional queries.
1176 foreach ($users as $user) {
1177 $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $user->id);
1178 $this->assertInternalType('array', $result);
1180 $finalcount = $DB->perf_get_reads();
1181 $this->assertEquals(20, $finalcount - $startcount);
1185 * Test that after toggling the forum subscription as another user,
1186 * the discussion subscription functionality works as expected.
1188 public function test_forum_subscribe_toggle_as_other_repeat_subscriptions() {
1191 $this->resetAfterTest(true);
1193 // Create a course, with a forum.
1194 $course = $this->getDataGenerator()->create_course();
1196 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1197 $forum = $this->getDataGenerator()->create_module('forum', $options);
1199 // Create a user enrolled in the course as a student.
1200 list($user) = $this->helper_create_users($course, 1);
1202 // Post a discussion to the forum.
1203 list($discussion, $post) = $this->helper_post_to_forum($forum, $user);
1205 // Confirm that the user is currently not subscribed to the forum.
1206 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1208 // Confirm that the user is unsubscribed from the discussion too.
1209 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum, $discussion->id));
1211 // Confirm that we have no records in either of the subscription tables.
1212 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1213 'userid' => $user->id,
1214 'forum' => $forum->id,
1216 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
1217 'userid' => $user->id,
1218 'discussion' => $discussion->id,
1221 // Subscribing to the forum should create a record in the subscriptions table, but not the forum discussion
1222 // subscriptions table.
1223 \mod_forum\subscriptions::subscribe_user($user->id, $forum);
1224 $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
1225 'userid' => $user->id,
1226 'forum' => $forum->id,
1228 $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
1229 'userid' => $user->id,
1230 'discussion' => $discussion->id,
1233 // Now unsubscribe from the discussion. This should return true.
1234 $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1236 // Attempting to unsubscribe again should return false because no change was made.
1237 $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1239 // Subscribing to the discussion again should return truthfully as the subscription preference was removed.
1240 $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1242 // Attempting to subscribe again should return false because no change was made.
1243 $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1245 // Now unsubscribe from the discussion. This should return true once more.
1246 $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1248 // And unsubscribing from the forum but not as a request from the user should maintain their preference.
1249 \mod_forum\subscriptions::unsubscribe_user($user->id, $forum);
1251 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1252 'userid' => $user->id,
1253 'forum' => $forum->id,
1255 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
1256 'userid' => $user->id,
1257 'discussion' => $discussion->id,
1260 // Subscribing to the discussion should return truthfully because a change was made.
1261 $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1262 $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1263 'userid' => $user->id,
1264 'forum' => $forum->id,
1266 $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
1267 'userid' => $user->id,
1268 'discussion' => $discussion->id,
1273 * Test that providing a context_module instance to is_subscribed does not result in additional lookups to retrieve
1274 * the context_module.
1276 public function test_is_subscribed_cm() {
1279 $this->resetAfterTest(true);
1281 // Create a course, with a forum.
1282 $course = $this->getDataGenerator()->create_course();
1284 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
1285 $forum = $this->getDataGenerator()->create_module('forum', $options);
1287 // Create a user enrolled in the course as a student.
1288 list($user) = $this->helper_create_users($course, 1);
1290 // Retrieve the $cm now.
1291 $cm = get_fast_modinfo($forum->course)->instances['forum'][$forum->id];
1293 // Reset get_fast_modinfo.
1294 get_fast_modinfo(0, 0, true);
1296 // Call is_subscribed without passing the $cmid - this should result in a lookup and filling of some of the
1297 // caches. This provides us with consistent data to start from.
1298 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1299 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1301 // Make a note of the number of DB calls.
1302 $basecount = $DB->perf_get_reads();
1304 // Call is_subscribed - it should give return the correct result (False), and result in no additional queries.
1305 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum, null, $cm));
1307 // The capability check does require some queries, so we don't test it directly.
1308 // We don't assert here because this is dependant upon linked code which could change at any time.
1309 $suppliedcmcount = $DB->perf_get_reads() - $basecount;
1311 // Call is_subscribed without passing the $cmid now - this should result in a lookup.
1312 get_fast_modinfo(0, 0, true);
1313 $basecount = $DB->perf_get_reads();
1314 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1315 $calculatedcmcount = $DB->perf_get_reads() - $basecount;
1317 // There should be more queries than when we performed the same check a moment ago.
1318 $this->assertGreaterThan($suppliedcmcount, $calculatedcmcount);