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