[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/mod/forum/tests/ -> subscriptions_test.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * The module forums tests
  19   *
  20   * @package    mod_forum
  21   * @copyright  2013 Frédéric Massart
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->dirroot . '/mod/forum/lib.php');
  29  
  30  class mod_forum_subscriptions_testcase extends advanced_testcase {
  31  
  32      /**
  33       * Test setUp.
  34       */
  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();
  40      }
  41  
  42      /**
  43       * Test tearDown.
  44       */
  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();
  50      }
  51  
  52      /**
  53       * Helper to create the required number of users in the specified
  54       * course.
  55       * Users are enrolled as students.
  56       *
  57       * @param stdClass $course The course object
  58       * @param integer $count The number of users to create
  59       * @return array The users created
  60       */
  61      protected function helper_create_users($course, $count) {
  62          $users = array();
  63  
  64          for ($i = 0; $i < $count; $i++) {
  65              $user = $this->getDataGenerator()->create_user();
  66              $this->getDataGenerator()->enrol_user($user->id, $course->id);
  67              $users[] = $user;
  68          }
  69  
  70          return $users;
  71      }
  72  
  73      /**
  74       * Create a new discussion and post within the specified forum, as the
  75       * specified author.
  76       *
  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
  80       */
  81      protected function helper_post_to_forum($forum, $author) {
  82          global $DB;
  83          $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
  84  
  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);
  91  
  92          // Retrieve the post which was created by create_discussion.
  93          $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
  94  
  95          return array($discussion, $post);
  96      }
  97  
  98      public function test_subscription_modes() {
  99          global $DB;
 100  
 101          $this->resetAfterTest(true);
 102  
 103          // Create a course, with a forum.
 104          $course = $this->getDataGenerator()->create_course();
 105  
 106          $options = array('course' => $course->id);
 107          $forum = $this->getDataGenerator()->create_module('forum', $options);
 108  
 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));
 115  
 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));
 122  
 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));
 129  
 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));
 136      }
 137  
 138      /**
 139       * Test fetching unsubscribable forums.
 140       */
 141      public function test_unsubscribable_forums() {
 142          global $DB;
 143  
 144          $this->resetAfterTest(true);
 145  
 146          // Create a course, with a forum.
 147          $course = $this->getDataGenerator()->create_course();
 148  
 149          // Create a user enrolled in the course as a student.
 150          list($user) = $this->helper_create_users($course, 1);
 151  
 152          // Must be logged in as the current user.
 153          $this->setUser($user);
 154  
 155          // Without any subscriptions, there should be nothing returned.
 156          $result = \mod_forum\subscriptions::get_unsubscribable_forums();
 157          $this->assertEquals(0, count($result));
 158  
 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);
 168  
 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));
 172  
 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);
 176  
 177          $result = \mod_forum\subscriptions::get_unsubscribable_forums();
 178          $this->assertEquals(3, count($result));
 179  
 180          // Hide the forums.
 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));
 187  
 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();
 193  
 194          // All of the unsubscribable forums should now be listed.
 195          $result = \mod_forum\subscriptions::get_unsubscribable_forums();
 196          $this->assertEquals(3, count($result));
 197      }
 198  
 199      /**
 200       * Test that toggling the forum-level subscription for a different user does not affect their discussion-level
 201       * subscriptions.
 202       */
 203      public function test_forum_subscribe_toggle_as_other() {
 204          global $DB;
 205  
 206          $this->resetAfterTest(true);
 207  
 208          // Create a course, with a forum.
 209          $course = $this->getDataGenerator()->create_course();
 210  
 211          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 212          $forum = $this->getDataGenerator()->create_module('forum', $options);
 213  
 214          // Create a user enrolled in the course as a student.
 215          list($author) = $this->helper_create_users($course, 1);
 216  
 217          // Post a discussion to the forum.
 218          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 219  
 220          // Check that the user is currently not subscribed to the forum.
 221          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 222  
 223          // Check the deprecated function too.
 224          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 225          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 226          phpunit_util::reset_debugging();
 227  
 228          // Check that the user is unsubscribed from the discussion too.
 229          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 230  
 231          // Check that we have no records in either of the subscription tables.
 232          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 233              'userid'        => $author->id,
 234              'forum'         => $forum->id,
 235          )));
 236          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 237              'userid'        => $author->id,
 238              'discussion'    => $discussion->id,
 239          )));
 240  
 241          // Subscribing to the forum should create a record in the subscriptions table, but not the forum discussion
 242          // subscriptions table.
 243          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 244          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 245              'userid'        => $author->id,
 246              'forum'         => $forum->id,
 247          )));
 248          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 249              'userid'        => $author->id,
 250              'discussion'    => $discussion->id,
 251          )));
 252  
 253          // Unsubscribing should remove the record from the forum subscriptions table, and not modify the forum
 254          // discussion subscriptions table.
 255          \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
 256          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 257              'userid'        => $author->id,
 258              'forum'         => $forum->id,
 259          )));
 260          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 261              'userid'        => $author->id,
 262              'discussion'    => $discussion->id,
 263          )));
 264  
 265          // The same thing should happen calling the deprecated versions of
 266          // these functions.
 267          // Subscribing to the forum should create a record in the subscriptions table, but not the forum discussion
 268          // subscriptions table.
 269          forum_subscribe($author->id, $forum->id);
 270          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 271          phpunit_util::reset_debugging();
 272          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 273              'userid'        => $author->id,
 274              'forum'         => $forum->id,
 275          )));
 276          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 277              'userid'        => $author->id,
 278              'discussion'    => $discussion->id,
 279          )));
 280  
 281          // Unsubscribing should remove the record from the forum subscriptions table, and not modify the forum
 282          // discussion subscriptions table.
 283          forum_unsubscribe($author->id, $forum->id);
 284          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 285          phpunit_util::reset_debugging();
 286          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 287              'userid'        => $author->id,
 288              'forum'         => $forum->id,
 289          )));
 290          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 291              'userid'        => $author->id,
 292              'discussion'    => $discussion->id,
 293          )));
 294  
 295          // Enroling the user in the discussion should add one record to the forum discussion table without modifying the
 296          // form subscriptions.
 297          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 298          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 299              'userid'        => $author->id,
 300              'forum'         => $forum->id,
 301          )));
 302          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 303              'userid'        => $author->id,
 304              'discussion'    => $discussion->id,
 305          )));
 306  
 307          // Unsubscribing should remove the record from the forum subscriptions table, and not modify the forum
 308          // discussion subscriptions table.
 309          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 310          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 311              'userid'        => $author->id,
 312              'forum'         => $forum->id,
 313          )));
 314          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 315              'userid'        => $author->id,
 316              'discussion'    => $discussion->id,
 317          )));
 318  
 319          // Re-subscribe to the discussion so that we can check the effect of forum-level subscriptions.
 320          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 321          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 322              'userid'        => $author->id,
 323              'forum'         => $forum->id,
 324          )));
 325          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 326              'userid'        => $author->id,
 327              'discussion'    => $discussion->id,
 328          )));
 329  
 330          // Subscribing to the forum should have no effect on the forum discussion subscriptions table if the user did
 331          // not request the change themself.
 332          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 333          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 334              'userid'        => $author->id,
 335              'forum'         => $forum->id,
 336          )));
 337          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 338              'userid'        => $author->id,
 339              'discussion'    => $discussion->id,
 340          )));
 341  
 342          // Unsubscribing from the forum should have no effect on the forum discussion subscriptions table if the user
 343          // did not request the change themself.
 344          \mod_forum\subscriptions::unsubscribe_user($author->id, $forum);
 345          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 346              'userid'        => $author->id,
 347              'forum'         => $forum->id,
 348          )));
 349          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 350              'userid'        => $author->id,
 351              'discussion'    => $discussion->id,
 352          )));
 353  
 354          // Subscribing to the forum should remove the per-discussion subscription preference if the user requested the
 355          // change themself.
 356          \mod_forum\subscriptions::subscribe_user($author->id, $forum, null, true);
 357          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 358              'userid'        => $author->id,
 359              'forum'         => $forum->id,
 360          )));
 361          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 362              'userid'        => $author->id,
 363              'discussion'    => $discussion->id,
 364          )));
 365  
 366          // Now unsubscribe from the current discussion whilst being subscribed to the forum as a whole.
 367          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 368          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 369              'userid'        => $author->id,
 370              'forum'         => $forum->id,
 371          )));
 372          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 373              'userid'        => $author->id,
 374              'discussion'    => $discussion->id,
 375          )));
 376  
 377          // Unsubscribing from the forum should remove the per-discussion subscription preference if the user requested the
 378          // change themself.
 379          \mod_forum\subscriptions::unsubscribe_user($author->id, $forum, null, true);
 380          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 381              'userid'        => $author->id,
 382              'forum'         => $forum->id,
 383          )));
 384          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 385              'userid'        => $author->id,
 386              'discussion'    => $discussion->id,
 387          )));
 388  
 389          // Subscribe to the discussion.
 390          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 391          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 392              'userid'        => $author->id,
 393              'forum'         => $forum->id,
 394          )));
 395          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 396              'userid'        => $author->id,
 397              'discussion'    => $discussion->id,
 398          )));
 399  
 400          // Subscribe to the forum without removing the discussion preferences.
 401          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 402          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 403              'userid'        => $author->id,
 404              'forum'         => $forum->id,
 405          )));
 406          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 407              'userid'        => $author->id,
 408              'discussion'    => $discussion->id,
 409          )));
 410  
 411          // Unsubscribing from the discussion should result in a change.
 412          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 413          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 414              'userid'        => $author->id,
 415              'forum'         => $forum->id,
 416          )));
 417          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 418              'userid'        => $author->id,
 419              'discussion'    => $discussion->id,
 420          )));
 421  
 422      }
 423  
 424      /**
 425       * Test that a user unsubscribed from a forum is not subscribed to it's discussions by default.
 426       */
 427      public function test_forum_discussion_subscription_forum_unsubscribed() {
 428          $this->resetAfterTest(true);
 429  
 430          // Create a course, with a forum.
 431          $course = $this->getDataGenerator()->create_course();
 432  
 433          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 434          $forum = $this->getDataGenerator()->create_module('forum', $options);
 435  
 436          // Create users enrolled in the course as students.
 437          list($author) = $this->helper_create_users($course, 1);
 438  
 439          // Check that the user is currently not subscribed to the forum.
 440          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 441  
 442          // Check the deprecated function too.
 443          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 444          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 445          phpunit_util::reset_debugging();
 446  
 447          // Post a discussion to the forum.
 448          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 449  
 450          // Check that the user is unsubscribed from the discussion too.
 451          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 452      }
 453  
 454      /**
 455       * Test that the act of subscribing to a forum subscribes the user to it's discussions by default.
 456       */
 457      public function test_forum_discussion_subscription_forum_subscribed() {
 458          $this->resetAfterTest(true);
 459  
 460          // Create a course, with a forum.
 461          $course = $this->getDataGenerator()->create_course();
 462  
 463          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 464          $forum = $this->getDataGenerator()->create_module('forum', $options);
 465  
 466          // Create users enrolled in the course as students.
 467          list($author) = $this->helper_create_users($course, 1);
 468  
 469          // Enrol the user in the forum.
 470          // If a subscription was added, we get the record ID.
 471          $this->assertInternalType('int', \mod_forum\subscriptions::subscribe_user($author->id, $forum));
 472  
 473          // If we already have a subscription when subscribing the user, we get a boolean (true).
 474          $this->assertTrue(\mod_forum\subscriptions::subscribe_user($author->id, $forum));
 475  
 476          // Check that the user is currently subscribed to the forum.
 477          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 478  
 479          // Check the deprecated function too.
 480          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 481          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 482          phpunit_util::reset_debugging();
 483  
 484          // Post a discussion to the forum.
 485          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 486  
 487          // Check that the user is subscribed to the discussion too.
 488          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 489      }
 490  
 491      /**
 492       * Test that a user unsubscribed from a forum can be subscribed to a discussion.
 493       */
 494      public function test_forum_discussion_subscription_forum_unsubscribed_discussion_subscribed() {
 495          $this->resetAfterTest(true);
 496  
 497          // Create a course, with a forum.
 498          $course = $this->getDataGenerator()->create_course();
 499  
 500          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 501          $forum = $this->getDataGenerator()->create_module('forum', $options);
 502  
 503          // Create a user enrolled in the course as a student.
 504          list($author) = $this->helper_create_users($course, 1);
 505  
 506          // Check that the user is currently not subscribed to the forum.
 507          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 508  
 509          // Check the deprecated function too.
 510          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 511          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 512          phpunit_util::reset_debugging();
 513  
 514          // Post a discussion to the forum.
 515          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 516  
 517          // Attempting to unsubscribe from the discussion should not make a change.
 518          $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion));
 519  
 520          // Then subscribe them to the discussion.
 521          $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
 522  
 523          // Check that the user is still unsubscribed from the forum.
 524          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 525  
 526          // Check the deprecated function too.
 527          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 528          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 529          phpunit_util::reset_debugging();
 530  
 531          // But subscribed to the discussion.
 532          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 533      }
 534  
 535      /**
 536       * Test that a user subscribed to a forum can be unsubscribed from a discussion.
 537       */
 538      public function test_forum_discussion_subscription_forum_subscribed_discussion_unsubscribed() {
 539          $this->resetAfterTest(true);
 540  
 541          // Create a course, with a forum.
 542          $course = $this->getDataGenerator()->create_course();
 543  
 544          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 545          $forum = $this->getDataGenerator()->create_module('forum', $options);
 546  
 547          // Create two users enrolled in the course as students.
 548          list($author) = $this->helper_create_users($course, 2);
 549  
 550          // Enrol the student in the forum.
 551          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 552  
 553          // Check that the user is currently subscribed to the forum.
 554          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 555  
 556          // Check the deprecated function too.
 557          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 558          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 559          phpunit_util::reset_debugging();
 560  
 561          // Post a discussion to the forum.
 562          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 563  
 564          // Then unsubscribe them from the discussion.
 565          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 566  
 567          // Check that the user is still subscribed to the forum.
 568          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 569  
 570          // Check the deprecated function too.
 571          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 572          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 573          phpunit_util::reset_debugging();
 574  
 575          // But unsubscribed from the discussion.
 576          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 577      }
 578  
 579      /**
 580       * Test the effect of toggling the discussion subscription status when subscribed to the forum.
 581       */
 582      public function test_forum_discussion_toggle_forum_subscribed() {
 583          global $DB;
 584  
 585          $this->resetAfterTest(true);
 586  
 587          // Create a course, with a forum.
 588          $course = $this->getDataGenerator()->create_course();
 589  
 590          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 591          $forum = $this->getDataGenerator()->create_module('forum', $options);
 592  
 593          // Create two users enrolled in the course as students.
 594          list($author) = $this->helper_create_users($course, 2);
 595  
 596          // Enrol the student in the forum.
 597          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 598  
 599          // Check that the user is currently subscribed to the forum.
 600          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 601  
 602          // Check the deprecated function too.
 603          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 604          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 605          phpunit_util::reset_debugging();
 606  
 607          // Post a discussion to the forum.
 608          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 609  
 610          // Check that the user is initially subscribed to that discussion.
 611          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 612  
 613          // An attempt to subscribe again should result in a falsey return to indicate that no change was made.
 614          $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
 615  
 616          // And there should be no discussion subscriptions (and one forum subscription).
 617          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 618              'userid'        => $author->id,
 619              'discussion'    => $discussion->id,
 620          )));
 621          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 622              'userid'        => $author->id,
 623              'forum'         => $forum->id,
 624          )));
 625  
 626          // Then unsubscribe them from the discussion.
 627          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 628  
 629          // Check that the user is still subscribed to the forum.
 630          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 631  
 632          // Check the deprecated function too.
 633          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 634          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 635          phpunit_util::reset_debugging();
 636  
 637          // An attempt to unsubscribe again should result in a falsey return to indicate that no change was made.
 638          $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion));
 639  
 640          // And there should be a discussion subscriptions (and one forum subscription).
 641          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 642              'userid'        => $author->id,
 643              'discussion'    => $discussion->id,
 644          )));
 645          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 646              'userid'        => $author->id,
 647              'forum'         => $forum->id,
 648          )));
 649  
 650          // But unsubscribed from the discussion.
 651          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 652  
 653          // There should be a record in the discussion subscription tracking table.
 654          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 655              'userid'        => $author->id,
 656              'discussion'    => $discussion->id,
 657          )));
 658  
 659          // And one in the forum subscription tracking table.
 660          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 661              'userid'        => $author->id,
 662              'forum'         => $forum->id,
 663          )));
 664  
 665          // Now subscribe the user again to the discussion.
 666          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 667  
 668          // Check that the user is still subscribed to the forum.
 669          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 670  
 671          // Check the deprecated function too.
 672          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 673          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 674          phpunit_util::reset_debugging();
 675  
 676          // Check the deprecated function too.
 677          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 678          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 679          phpunit_util::reset_debugging();
 680  
 681          // And is subscribed to the discussion again.
 682          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 683  
 684          // There should be no record in the discussion subscription tracking table.
 685          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 686              'userid'        => $author->id,
 687              'discussion'    => $discussion->id,
 688          )));
 689  
 690          // And one in the forum subscription tracking table.
 691          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 692              'userid'        => $author->id,
 693              'forum'         => $forum->id,
 694          )));
 695  
 696          // And unsubscribe again.
 697          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 698  
 699          // Check that the user is still subscribed to the forum.
 700          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 701  
 702          // Check the deprecated function too.
 703          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 704          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 705          phpunit_util::reset_debugging();
 706  
 707          // But unsubscribed from the discussion.
 708          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 709  
 710          // There should be a record in the discussion subscription tracking table.
 711          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 712              'userid'        => $author->id,
 713              'discussion'    => $discussion->id,
 714          )));
 715  
 716          // And one in the forum subscription tracking table.
 717          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 718              'userid'        => $author->id,
 719              'forum'         => $forum->id,
 720          )));
 721  
 722          // And subscribe the user again to the discussion.
 723          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 724  
 725          // Check that the user is still subscribed to the forum.
 726          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 727          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 728  
 729          // And is subscribed to the discussion again.
 730          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 731  
 732          // There should be no record in the discussion subscription tracking table.
 733          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 734              'userid'        => $author->id,
 735              'discussion'    => $discussion->id,
 736          )));
 737  
 738          // And one in the forum subscription tracking table.
 739          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 740              'userid'        => $author->id,
 741              'forum'         => $forum->id,
 742          )));
 743  
 744          // And unsubscribe again.
 745          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 746  
 747          // Check that the user is still subscribed to the forum.
 748          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 749  
 750          // Check the deprecated function too.
 751          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 752          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 753          phpunit_util::reset_debugging();
 754  
 755          // But unsubscribed from the discussion.
 756          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 757  
 758          // There should be a record in the discussion subscription tracking table.
 759          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 760              'userid'        => $author->id,
 761              'discussion'    => $discussion->id,
 762          )));
 763  
 764          // And one in the forum subscription tracking table.
 765          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
 766              'userid'        => $author->id,
 767              'forum'         => $forum->id,
 768          )));
 769  
 770          // Now unsubscribe the user from the forum.
 771          $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user($author->id, $forum, null, true));
 772  
 773          // This removes both the forum_subscriptions, and the forum_discussion_subs records.
 774          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 775              'userid'        => $author->id,
 776              'discussion'    => $discussion->id,
 777          )));
 778          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
 779              'userid'        => $author->id,
 780              'forum'         => $forum->id,
 781          )));
 782  
 783          // And should have reset the discussion cache value.
 784          $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $author->id);
 785          $this->assertInternalType('array', $result);
 786          $this->assertFalse(isset($result[$discussion->id]));
 787      }
 788  
 789      /**
 790       * Test the effect of toggling the discussion subscription status when unsubscribed from the forum.
 791       */
 792      public function test_forum_discussion_toggle_forum_unsubscribed() {
 793          global $DB;
 794  
 795          $this->resetAfterTest(true);
 796  
 797          // Create a course, with a forum.
 798          $course = $this->getDataGenerator()->create_course();
 799  
 800          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 801          $forum = $this->getDataGenerator()->create_module('forum', $options);
 802  
 803          // Create two users enrolled in the course as students.
 804          list($author) = $this->helper_create_users($course, 2);
 805  
 806          // Check that the user is currently unsubscribed to the forum.
 807          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 808  
 809          // Check the deprecated function too.
 810          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 811          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 812          phpunit_util::reset_debugging();
 813  
 814          // Post a discussion to the forum.
 815          list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
 816  
 817          // Check that the user is initially unsubscribed to that discussion.
 818          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 819  
 820          // Then subscribe them to the discussion.
 821          $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
 822  
 823          // An attempt to subscribe again should result in a falsey return to indicate that no change was made.
 824          $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion));
 825  
 826          // Check that the user is still unsubscribed from the forum.
 827          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 828  
 829          // Check the deprecated function too.
 830          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 831          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 832          phpunit_util::reset_debugging();
 833  
 834          // But subscribed to the discussion.
 835          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 836  
 837          // There should be a record in the discussion subscription tracking table.
 838          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 839              'userid'        => $author->id,
 840              'discussion'    => $discussion->id,
 841          )));
 842  
 843          // Now unsubscribe the user again from the discussion.
 844          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 845  
 846          // Check that the user is still unsubscribed from the forum.
 847          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 848  
 849          // Check the deprecated function too.
 850          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 851          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 852          phpunit_util::reset_debugging();
 853  
 854          // And is unsubscribed from the discussion again.
 855          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 856  
 857          // There should be no record in the discussion subscription tracking table.
 858          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 859              'userid'        => $author->id,
 860              'discussion'    => $discussion->id,
 861          )));
 862  
 863          // And subscribe the user again to the discussion.
 864          \mod_forum\subscriptions::subscribe_user_to_discussion($author->id, $discussion);
 865  
 866          // Check that the user is still unsubscribed from the forum.
 867          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 868  
 869          // Check the deprecated function too.
 870          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 871          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 872          phpunit_util::reset_debugging();
 873  
 874          // And is subscribed to the discussion again.
 875          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 876  
 877          // There should be a record in the discussion subscription tracking table.
 878          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
 879              'userid'        => $author->id,
 880              'discussion'    => $discussion->id,
 881          )));
 882  
 883          // And unsubscribe again.
 884          \mod_forum\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion);
 885  
 886          // Check that the user is still unsubscribed from the forum.
 887          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum));
 888  
 889          // Check the deprecated function too.
 890          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 891          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 892          phpunit_util::reset_debugging();
 893  
 894          // But unsubscribed from the discussion.
 895          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($author->id, $forum, $discussion->id));
 896  
 897          // There should be no record in the discussion subscription tracking table.
 898          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
 899              'userid'        => $author->id,
 900              'discussion'    => $discussion->id,
 901          )));
 902      }
 903  
 904      /**
 905       * Test that the deprecated forum_is_subscribed accepts numeric forum IDs.
 906       */
 907      public function test_forum_is_subscribed_numeric() {
 908          global $DB;
 909  
 910          $this->resetAfterTest(true);
 911  
 912          // Create a course, with a forum.
 913          $course = $this->getDataGenerator()->create_course();
 914  
 915          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
 916          $forum = $this->getDataGenerator()->create_module('forum', $options);
 917  
 918          // Create a user enrolled in the course as a students.
 919          list($author) = $this->helper_create_users($course, 1);
 920  
 921          // Check that the user is currently unsubscribed to the forum.
 922          $this->assertFalse(forum_is_subscribed($author->id, $forum->id));
 923          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 924          phpunit_util::reset_debugging();
 925  
 926          // It should match the result of when it's called with the forum object.
 927          $this->assertFalse(forum_is_subscribed($author->id, $forum));
 928          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 929          phpunit_util::reset_debugging();
 930  
 931          // And when the user is subscribed, we should also get the correct result.
 932          \mod_forum\subscriptions::subscribe_user($author->id, $forum);
 933  
 934          $this->assertTrue(forum_is_subscribed($author->id, $forum->id));
 935          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 936          phpunit_util::reset_debugging();
 937  
 938          // It should match the result of when it's called with the forum object.
 939          $this->assertTrue(forum_is_subscribed($author->id, $forum));
 940          $this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
 941          phpunit_util::reset_debugging();
 942      }
 943  
 944      /**
 945       * Test that the correct users are returned when fetching subscribed users from a forum where users can choose to
 946       * subscribe and unsubscribe.
 947       */
 948      public function test_fetch_subscribed_users_subscriptions() {
 949          global $DB, $CFG;
 950  
 951          $this->resetAfterTest(true);
 952  
 953          // Create a course, with a forum. where users are initially subscribed.
 954          $course = $this->getDataGenerator()->create_course();
 955          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
 956          $forum = $this->getDataGenerator()->create_module('forum', $options);
 957  
 958          // Create some user enrolled in the course as a student.
 959          $usercount = 5;
 960          $users = $this->helper_create_users($course, $usercount);
 961  
 962          // All users should be subscribed.
 963          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
 964          $this->assertEquals($usercount, count($subscribers));
 965  
 966          // Subscribe the guest user too to the forum - they should never be returned by this function.
 967          $this->getDataGenerator()->enrol_user($CFG->siteguest, $course->id);
 968          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
 969          $this->assertEquals($usercount, count($subscribers));
 970  
 971          // Unsubscribe 2 users.
 972          $unsubscribedcount = 2;
 973          for ($i = 0; $i < $unsubscribedcount; $i++) {
 974              \mod_forum\subscriptions::unsubscribe_user($users[$i]->id, $forum);
 975          }
 976  
 977          // The subscription count should now take into account those users who have been unsubscribed.
 978          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
 979          $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
 980      }
 981  
 982      /**
 983       * Test that the correct users are returned hwen fetching subscribed users from a forum where users are forcibly
 984       * subscribed.
 985       */
 986      public function test_fetch_subscribed_users_forced() {
 987          global $DB;
 988  
 989          $this->resetAfterTest(true);
 990  
 991          // Create a course, with a forum. where users are initially subscribed.
 992          $course = $this->getDataGenerator()->create_course();
 993          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
 994          $forum = $this->getDataGenerator()->create_module('forum', $options);
 995  
 996          // Create some user enrolled in the course as a student.
 997          $usercount = 5;
 998          $users = $this->helper_create_users($course, $usercount);
 999  
1000          // All users should be subscribed.
1001          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1002          $this->assertEquals($usercount, count($subscribers));
1003      }
1004  
1005      /**
1006       * Test that unusual combinations of discussion subscriptions do not affect the subscribed user list.
1007       */
1008      public function test_fetch_subscribed_users_discussion_subscriptions() {
1009          global $DB;
1010  
1011          $this->resetAfterTest(true);
1012  
1013          // Create a course, with a forum. where users are initially subscribed.
1014          $course = $this->getDataGenerator()->create_course();
1015          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1016          $forum = $this->getDataGenerator()->create_module('forum', $options);
1017  
1018          // Create some user enrolled in the course as a student.
1019          $usercount = 5;
1020          $users = $this->helper_create_users($course, $usercount);
1021  
1022          list($discussion, $post) = $this->helper_post_to_forum($forum, $users[0]);
1023  
1024          // All users should be subscribed.
1025          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1026          $this->assertEquals($usercount, count($subscribers));
1027          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
1028          $this->assertEquals($usercount, count($subscribers));
1029  
1030          \mod_forum\subscriptions::unsubscribe_user_from_discussion($users[0]->id, $discussion);
1031  
1032          // All users should be subscribed.
1033          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1034          $this->assertEquals($usercount, count($subscribers));
1035  
1036          // All users should be subscribed.
1037          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
1038          $this->assertEquals($usercount, count($subscribers));
1039  
1040          // Manually insert an extra subscription for one of the users.
1041          $record = new stdClass();
1042          $record->userid = $users[2]->id;
1043          $record->forum = $forum->id;
1044          $record->discussion = $discussion->id;
1045          $record->preference = time();
1046          $DB->insert_record('forum_discussion_subs', $record);
1047  
1048          // The discussion count should not have changed.
1049          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1050          $this->assertEquals($usercount, count($subscribers));
1051          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
1052          $this->assertEquals($usercount, count($subscribers));
1053  
1054          // Unsubscribe 2 users.
1055          $unsubscribedcount = 2;
1056          for ($i = 0; $i < $unsubscribedcount; $i++) {
1057              \mod_forum\subscriptions::unsubscribe_user($users[$i]->id, $forum);
1058          }
1059  
1060          // The subscription count should now take into account those users who have been unsubscribed.
1061          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1062          $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
1063          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
1064          $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
1065  
1066          // Now subscribe one of those users back to the discussion.
1067          $subscribeddiscussionusers = 1;
1068          for ($i = 0; $i < $subscribeddiscussionusers; $i++) {
1069              \mod_forum\subscriptions::subscribe_user_to_discussion($users[$i]->id, $discussion);
1070          }
1071          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum);
1072          $this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
1073          $subscribers = \mod_forum\subscriptions::fetch_subscribed_users($forum, 0, null, null, true);
1074          $this->assertEquals($usercount - $unsubscribedcount + $subscribeddiscussionusers, count($subscribers));
1075      }
1076  
1077      /**
1078       * Test whether a user is force-subscribed to a forum.
1079       */
1080      public function test_force_subscribed_to_forum() {
1081          global $DB;
1082  
1083          $this->resetAfterTest(true);
1084  
1085          // Create a course, with a forum.
1086          $course = $this->getDataGenerator()->create_course();
1087  
1088          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
1089          $forum = $this->getDataGenerator()->create_module('forum', $options);
1090  
1091          // Create a user enrolled in the course as a student.
1092          $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
1093          $user = $this->getDataGenerator()->create_user();
1094          $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleids['student']);
1095  
1096          // Check that the user is currently subscribed to the forum.
1097          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1098  
1099          // Remove the allowforcesubscribe capability from the user.
1100          $cm = get_coursemodule_from_instance('forum', $forum->id);
1101          $context = \context_module::instance($cm->id);
1102          assign_capability('mod/forum:allowforcesubscribe', CAP_PROHIBIT, $roleids['student'], $context);
1103          $context->mark_dirty();
1104          $this->assertFalse(has_capability('mod/forum:allowforcesubscribe', $context, $user->id));
1105  
1106          // Check that the user is no longer subscribed to the forum.
1107          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1108      }
1109  
1110      /**
1111       * Test that the subscription cache can be pre-filled.
1112       */
1113      public function test_subscription_cache_prefill() {
1114          global $DB;
1115  
1116          $this->resetAfterTest(true);
1117  
1118          // Create a course, with a forum.
1119          $course = $this->getDataGenerator()->create_course();
1120  
1121          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1122          $forum = $this->getDataGenerator()->create_module('forum', $options);
1123  
1124          // Create some users.
1125          $users = $this->helper_create_users($course, 20);
1126  
1127          // Reset the subscription cache.
1128          \mod_forum\subscriptions::reset_forum_cache();
1129  
1130          // Filling the subscription cache should only use a single query.
1131          $startcount = $DB->perf_get_reads();
1132          $this->assertNull(\mod_forum\subscriptions::fill_subscription_cache($forum->id));
1133          $postfillcount = $DB->perf_get_reads();
1134          $this->assertEquals(1, $postfillcount - $startcount);
1135  
1136          // Now fetch some subscriptions from that forum - these should use
1137          // the cache and not perform additional queries.
1138          foreach ($users as $user) {
1139              $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($forum->id, $user->id));
1140          }
1141          $finalcount = $DB->perf_get_reads();
1142          $this->assertEquals(0, $finalcount - $postfillcount);
1143      }
1144  
1145      /**
1146       * Test that the subscription cache can filled user-at-a-time.
1147       */
1148      public function test_subscription_cache_fill() {
1149          global $DB;
1150  
1151          $this->resetAfterTest(true);
1152  
1153          // Create a course, with a forum.
1154          $course = $this->getDataGenerator()->create_course();
1155  
1156          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1157          $forum = $this->getDataGenerator()->create_module('forum', $options);
1158  
1159          // Create some users.
1160          $users = $this->helper_create_users($course, 20);
1161  
1162          // Reset the subscription cache.
1163          \mod_forum\subscriptions::reset_forum_cache();
1164  
1165          // Filling the subscription cache should only use a single query.
1166          $startcount = $DB->perf_get_reads();
1167  
1168          // Fetch some subscriptions from that forum - these should not use the cache and will perform additional queries.
1169          foreach ($users as $user) {
1170              $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($forum->id, $user->id));
1171          }
1172          $finalcount = $DB->perf_get_reads();
1173          $this->assertEquals(20, $finalcount - $startcount);
1174      }
1175  
1176      /**
1177       * Test that the discussion subscription cache can filled course-at-a-time.
1178       */
1179      public function test_discussion_subscription_cache_fill_for_course() {
1180          global $DB;
1181  
1182          $this->resetAfterTest(true);
1183  
1184          // Create a course, with a forum.
1185          $course = $this->getDataGenerator()->create_course();
1186  
1187          // Create the forums.
1188          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE);
1189          $disallowforum = $this->getDataGenerator()->create_module('forum', $options);
1190          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1191          $chooseforum = $this->getDataGenerator()->create_module('forum', $options);
1192          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1193          $initialforum = $this->getDataGenerator()->create_module('forum', $options);
1194  
1195          // Create some users and keep a reference to the first user.
1196          $users = $this->helper_create_users($course, 20);
1197          $user = reset($users);
1198  
1199          // Reset the subscription caches.
1200          \mod_forum\subscriptions::reset_forum_cache();
1201  
1202          $startcount = $DB->perf_get_reads();
1203          $result = \mod_forum\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
1204          $this->assertNull($result);
1205          $postfillcount = $DB->perf_get_reads();
1206          $this->assertEquals(1, $postfillcount - $startcount);
1207          $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($disallowforum->id, $user->id));
1208          $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($chooseforum->id, $user->id));
1209          $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($initialforum->id, $user->id));
1210          $finalcount = $DB->perf_get_reads();
1211          $this->assertEquals(0, $finalcount - $postfillcount);
1212  
1213          // Test for all users.
1214          foreach ($users as $user) {
1215              $result = \mod_forum\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
1216              $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($disallowforum->id, $user->id));
1217              $this->assertFalse(\mod_forum\subscriptions::fetch_subscription_cache($chooseforum->id, $user->id));
1218              $this->assertTrue(\mod_forum\subscriptions::fetch_subscription_cache($initialforum->id, $user->id));
1219          }
1220          $finalcount = $DB->perf_get_reads();
1221          $this->assertEquals(count($users), $finalcount - $postfillcount);
1222      }
1223  
1224      /**
1225       * Test that the discussion subscription cache can be forcibly updated for a user.
1226       */
1227      public function test_discussion_subscription_cache_prefill() {
1228          global $DB;
1229  
1230          $this->resetAfterTest(true);
1231  
1232          // Create a course, with a forum.
1233          $course = $this->getDataGenerator()->create_course();
1234  
1235          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1236          $forum = $this->getDataGenerator()->create_module('forum', $options);
1237  
1238          // Create some users.
1239          $users = $this->helper_create_users($course, 20);
1240  
1241          // Post some discussions to the forum.
1242          $discussions = array();
1243          $author = $users[0];
1244          for ($i = 0; $i < 20; $i++) {
1245              list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1246              $discussions[] = $discussion;
1247          }
1248  
1249          // Unsubscribe half the users from the half the discussions.
1250          $forumcount = 0;
1251          $usercount = 0;
1252          foreach ($discussions as $data) {
1253              if ($forumcount % 2) {
1254                  continue;
1255              }
1256              foreach ($users as $user) {
1257                  if ($usercount % 2) {
1258                      continue;
1259                  }
1260                  \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
1261                  $usercount++;
1262              }
1263              $forumcount++;
1264          }
1265  
1266          // Reset the subscription caches.
1267          \mod_forum\subscriptions::reset_forum_cache();
1268          \mod_forum\subscriptions::reset_discussion_cache();
1269  
1270          // Filling the discussion subscription cache should only use a single query.
1271          $startcount = $DB->perf_get_reads();
1272          $this->assertNull(\mod_forum\subscriptions::fill_discussion_subscription_cache($forum->id));
1273          $postfillcount = $DB->perf_get_reads();
1274          $this->assertEquals(1, $postfillcount - $startcount);
1275  
1276          // Now fetch some subscriptions from that forum - these should use
1277          // the cache and not perform additional queries.
1278          foreach ($users as $user) {
1279              $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $user->id);
1280              $this->assertInternalType('array', $result);
1281          }
1282          $finalcount = $DB->perf_get_reads();
1283          $this->assertEquals(0, $finalcount - $postfillcount);
1284      }
1285  
1286      /**
1287       * Test that the discussion subscription cache can filled user-at-a-time.
1288       */
1289      public function test_discussion_subscription_cache_fill() {
1290          global $DB;
1291  
1292          $this->resetAfterTest(true);
1293  
1294          // Create a course, with a forum.
1295          $course = $this->getDataGenerator()->create_course();
1296  
1297          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
1298          $forum = $this->getDataGenerator()->create_module('forum', $options);
1299  
1300          // Create some users.
1301          $users = $this->helper_create_users($course, 20);
1302  
1303          // Post some discussions to the forum.
1304          $discussions = array();
1305          $author = $users[0];
1306          for ($i = 0; $i < 20; $i++) {
1307              list($discussion, $post) = $this->helper_post_to_forum($forum, $author);
1308              $discussions[] = $discussion;
1309          }
1310  
1311          // Unsubscribe half the users from the half the discussions.
1312          $forumcount = 0;
1313          $usercount = 0;
1314          foreach ($discussions as $data) {
1315              if ($forumcount % 2) {
1316                  continue;
1317              }
1318              foreach ($users as $user) {
1319                  if ($usercount % 2) {
1320                      continue;
1321                  }
1322                  \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
1323                  $usercount++;
1324              }
1325              $forumcount++;
1326          }
1327  
1328          // Reset the subscription caches.
1329          \mod_forum\subscriptions::reset_forum_cache();
1330          \mod_forum\subscriptions::reset_discussion_cache();
1331  
1332          $startcount = $DB->perf_get_reads();
1333  
1334          // Now fetch some subscriptions from that forum - these should use
1335          // the cache and not perform additional queries.
1336          foreach ($users as $user) {
1337              $result = \mod_forum\subscriptions::fetch_discussion_subscription($forum->id, $user->id);
1338              $this->assertInternalType('array', $result);
1339          }
1340          $finalcount = $DB->perf_get_reads();
1341          $this->assertEquals(20, $finalcount - $startcount);
1342      }
1343  
1344      /**
1345       * Test that after toggling the forum subscription as another user,
1346       * the discussion subscription functionality works as expected.
1347       */
1348      public function test_forum_subscribe_toggle_as_other_repeat_subscriptions() {
1349          global $DB;
1350  
1351          $this->resetAfterTest(true);
1352  
1353          // Create a course, with a forum.
1354          $course = $this->getDataGenerator()->create_course();
1355  
1356          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1357          $forum = $this->getDataGenerator()->create_module('forum', $options);
1358  
1359          // Create a user enrolled in the course as a student.
1360          list($user) = $this->helper_create_users($course, 1);
1361  
1362          // Post a discussion to the forum.
1363          list($discussion, $post) = $this->helper_post_to_forum($forum, $user);
1364  
1365          // Confirm that the user is currently not subscribed to the forum.
1366          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1367  
1368          // Confirm that the user is unsubscribed from the discussion too.
1369          $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum, $discussion->id));
1370  
1371          // Confirm that we have no records in either of the subscription tables.
1372          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1373              'userid'        => $user->id,
1374              'forum'         => $forum->id,
1375          )));
1376          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
1377              'userid'        => $user->id,
1378              'discussion'    => $discussion->id,
1379          )));
1380  
1381          // Subscribing to the forum should create a record in the subscriptions table, but not the forum discussion
1382          // subscriptions table.
1383          \mod_forum\subscriptions::subscribe_user($user->id, $forum);
1384          $this->assertEquals(1, $DB->count_records('forum_subscriptions', array(
1385              'userid'        => $user->id,
1386              'forum'         => $forum->id,
1387          )));
1388          $this->assertEquals(0, $DB->count_records('forum_discussion_subs', array(
1389              'userid'        => $user->id,
1390              'discussion'    => $discussion->id,
1391          )));
1392  
1393          // Now unsubscribe from the discussion. This should return true.
1394          $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1395  
1396          // Attempting to unsubscribe again should return false because no change was made.
1397          $this->assertFalse(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1398  
1399          // Subscribing to the discussion again should return truthfully as the subscription preference was removed.
1400          $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1401  
1402          // Attempting to subscribe again should return false because no change was made.
1403          $this->assertFalse(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1404  
1405          // Now unsubscribe from the discussion. This should return true once more.
1406          $this->assertTrue(\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion));
1407  
1408          // And unsubscribing from the forum but not as a request from the user should maintain their preference.
1409          \mod_forum\subscriptions::unsubscribe_user($user->id, $forum);
1410  
1411          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1412              'userid'        => $user->id,
1413              'forum'         => $forum->id,
1414          )));
1415          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
1416              'userid'        => $user->id,
1417              'discussion'    => $discussion->id,
1418          )));
1419  
1420          // Subscribing to the discussion should return truthfully because a change was made.
1421          $this->assertTrue(\mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion));
1422          $this->assertEquals(0, $DB->count_records('forum_subscriptions', array(
1423              'userid'        => $user->id,
1424              'forum'         => $forum->id,
1425          )));
1426          $this->assertEquals(1, $DB->count_records('forum_discussion_subs', array(
1427              'userid'        => $user->id,
1428              'discussion'    => $discussion->id,
1429          )));
1430      }
1431  
1432      /**
1433       * Test that providing a context_module instance to is_subscribed does not result in additional lookups to retrieve
1434       * the context_module.
1435       */
1436      public function test_is_subscribed_cm() {
1437          global $DB;
1438  
1439          $this->resetAfterTest(true);
1440  
1441          // Create a course, with a forum.
1442          $course = $this->getDataGenerator()->create_course();
1443  
1444          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
1445          $forum = $this->getDataGenerator()->create_module('forum', $options);
1446  
1447          // Create a user enrolled in the course as a student.
1448          list($user) = $this->helper_create_users($course, 1);
1449  
1450          // Retrieve the $cm now.
1451          $cm = get_fast_modinfo($forum->course)->instances['forum'][$forum->id];
1452  
1453          // Reset get_fast_modinfo.
1454          get_fast_modinfo(0, 0, true);
1455  
1456          // Call is_subscribed without passing the $cmid - this should result in a lookup and filling of some of the
1457          // caches. This provides us with consistent data to start from.
1458          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1459          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1460  
1461          // Make a note of the number of DB calls.
1462          $basecount = $DB->perf_get_reads();
1463  
1464          // Call is_subscribed - it should give return the correct result (False), and result in no additional queries.
1465          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum, null, $cm));
1466  
1467          // The capability check does require some queries, so we don't test it directly.
1468          // We don't assert here because this is dependant upon linked code which could change at any time.
1469          $suppliedcmcount = $DB->perf_get_reads() - $basecount;
1470  
1471          // Call is_subscribed without passing the $cmid now - this should result in a lookup.
1472          get_fast_modinfo(0, 0, true);
1473          $basecount = $DB->perf_get_reads();
1474          $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
1475          $calculatedcmcount = $DB->perf_get_reads() - $basecount;
1476  
1477          // There should be more queries than when we performed the same check a moment ago.
1478          $this->assertGreaterThan($suppliedcmcount, $calculatedcmcount);
1479      }
1480  
1481  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1