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