[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * The module forums tests 19 * 20 * @package mod_forum 21 * @copyright 2013 Frédéric Massart 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 global $CFG; 28 require_once($CFG->dirroot . '/mod/forum/lib.php'); 29 require_once($CFG->dirroot . '/rating/lib.php'); 30 31 class mod_forum_lib_testcase extends advanced_testcase { 32 33 public function setUp() { 34 // We must clear the subscription caches. This has to be done both before each test, and after in case of other 35 // tests using these functions. 36 \mod_forum\subscriptions::reset_forum_cache(); 37 } 38 39 public function tearDown() { 40 // We must clear the subscription caches. This has to be done both before each test, and after in case of other 41 // tests using these functions. 42 \mod_forum\subscriptions::reset_forum_cache(); 43 } 44 45 public function test_forum_trigger_content_uploaded_event() { 46 $this->resetAfterTest(); 47 48 $user = $this->getDataGenerator()->create_user(); 49 $course = $this->getDataGenerator()->create_course(); 50 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 51 $context = context_module::instance($forum->cmid); 52 53 $this->setUser($user->id); 54 $fakepost = (object) array('id' => 123, 'message' => 'Yay!', 'discussion' => 100); 55 $cm = get_coursemodule_from_instance('forum', $forum->id); 56 57 $fs = get_file_storage(); 58 $dummy = (object) array( 59 'contextid' => $context->id, 60 'component' => 'mod_forum', 61 'filearea' => 'attachment', 62 'itemid' => $fakepost->id, 63 'filepath' => '/', 64 'filename' => 'myassignmnent.pdf' 65 ); 66 $fi = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename); 67 68 $data = new stdClass(); 69 $sink = $this->redirectEvents(); 70 forum_trigger_content_uploaded_event($fakepost, $cm, 'some triggered from value'); 71 $events = $sink->get_events(); 72 73 $this->assertCount(1, $events); 74 $event = reset($events); 75 $this->assertInstanceOf('\mod_forum\event\assessable_uploaded', $event); 76 $this->assertEquals($context->id, $event->contextid); 77 $this->assertEquals($fakepost->id, $event->objectid); 78 $this->assertEquals($fakepost->message, $event->other['content']); 79 $this->assertEquals($fakepost->discussion, $event->other['discussionid']); 80 $this->assertCount(1, $event->other['pathnamehashes']); 81 $this->assertEquals($fi->get_pathnamehash(), $event->other['pathnamehashes'][0]); 82 $expected = new stdClass(); 83 $expected->modulename = 'forum'; 84 $expected->name = 'some triggered from value'; 85 $expected->cmid = $forum->cmid; 86 $expected->itemid = $fakepost->id; 87 $expected->courseid = $course->id; 88 $expected->userid = $user->id; 89 $expected->content = $fakepost->message; 90 $expected->pathnamehashes = array($fi->get_pathnamehash()); 91 $this->assertEventLegacyData($expected, $event); 92 $this->assertEventContextNotUsed($event); 93 } 94 95 public function test_forum_get_courses_user_posted_in() { 96 $this->resetAfterTest(); 97 98 $user1 = $this->getDataGenerator()->create_user(); 99 $user2 = $this->getDataGenerator()->create_user(); 100 $user3 = $this->getDataGenerator()->create_user(); 101 102 $course1 = $this->getDataGenerator()->create_course(); 103 $course2 = $this->getDataGenerator()->create_course(); 104 $course3 = $this->getDataGenerator()->create_course(); 105 106 // Create 3 forums, one in each course. 107 $record = new stdClass(); 108 $record->course = $course1->id; 109 $forum1 = $this->getDataGenerator()->create_module('forum', $record); 110 111 $record = new stdClass(); 112 $record->course = $course2->id; 113 $forum2 = $this->getDataGenerator()->create_module('forum', $record); 114 115 $record = new stdClass(); 116 $record->course = $course3->id; 117 $forum3 = $this->getDataGenerator()->create_module('forum', $record); 118 119 // Add a second forum in course 1. 120 $record = new stdClass(); 121 $record->course = $course1->id; 122 $forum4 = $this->getDataGenerator()->create_module('forum', $record); 123 124 // Add discussions to course 1 started by user1. 125 $record = new stdClass(); 126 $record->course = $course1->id; 127 $record->userid = $user1->id; 128 $record->forum = $forum1->id; 129 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 130 131 $record = new stdClass(); 132 $record->course = $course1->id; 133 $record->userid = $user1->id; 134 $record->forum = $forum4->id; 135 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 136 137 // Add discussions to course2 started by user1. 138 $record = new stdClass(); 139 $record->course = $course2->id; 140 $record->userid = $user1->id; 141 $record->forum = $forum2->id; 142 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 143 144 // Add discussions to course 3 started by user2. 145 $record = new stdClass(); 146 $record->course = $course3->id; 147 $record->userid = $user2->id; 148 $record->forum = $forum3->id; 149 $discussion3 = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 150 151 // Add post to course 3 by user1. 152 $record = new stdClass(); 153 $record->course = $course3->id; 154 $record->userid = $user1->id; 155 $record->forum = $forum3->id; 156 $record->discussion = $discussion3->id; 157 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); 158 159 // User 3 hasn't posted anything, so shouldn't get any results. 160 $user3courses = forum_get_courses_user_posted_in($user3); 161 $this->assertEmpty($user3courses); 162 163 // User 2 has only posted in course3. 164 $user2courses = forum_get_courses_user_posted_in($user2); 165 $this->assertCount(1, $user2courses); 166 $user2course = array_shift($user2courses); 167 $this->assertEquals($course3->id, $user2course->id); 168 $this->assertEquals($course3->shortname, $user2course->shortname); 169 170 // User 1 has posted in all 3 courses. 171 $user1courses = forum_get_courses_user_posted_in($user1); 172 $this->assertCount(3, $user1courses); 173 foreach ($user1courses as $course) { 174 $this->assertContains($course->id, array($course1->id, $course2->id, $course3->id)); 175 $this->assertContains($course->shortname, array($course1->shortname, $course2->shortname, 176 $course3->shortname)); 177 178 } 179 180 // User 1 has only started a discussion in course 1 and 2 though. 181 $user1courses = forum_get_courses_user_posted_in($user1, true); 182 $this->assertCount(2, $user1courses); 183 foreach ($user1courses as $course) { 184 $this->assertContains($course->id, array($course1->id, $course2->id)); 185 $this->assertContains($course->shortname, array($course1->shortname, $course2->shortname)); 186 } 187 } 188 189 /** 190 * Test the logic in the forum_tp_can_track_forums() function. 191 */ 192 public function test_forum_tp_can_track_forums() { 193 global $CFG; 194 195 $this->resetAfterTest(); 196 197 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); 198 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); 199 $course = $this->getDataGenerator()->create_course(); 200 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. 201 $forumoff = $this->getDataGenerator()->create_module('forum', $options); 202 203 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On. 204 $forumforce = $this->getDataGenerator()->create_module('forum', $options); 205 206 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. 207 $forumoptional = $this->getDataGenerator()->create_module('forum', $options); 208 209 // Allow force. 210 $CFG->forum_allowforcedreadtracking = 1; 211 212 // User on, forum off, should be off. 213 $result = forum_tp_can_track_forums($forumoff, $useron); 214 $this->assertEquals(false, $result); 215 216 // User on, forum on, should be on. 217 $result = forum_tp_can_track_forums($forumforce, $useron); 218 $this->assertEquals(true, $result); 219 220 // User on, forum optional, should be on. 221 $result = forum_tp_can_track_forums($forumoptional, $useron); 222 $this->assertEquals(true, $result); 223 224 // User off, forum off, should be off. 225 $result = forum_tp_can_track_forums($forumoff, $useroff); 226 $this->assertEquals(false, $result); 227 228 // User off, forum force, should be on. 229 $result = forum_tp_can_track_forums($forumforce, $useroff); 230 $this->assertEquals(true, $result); 231 232 // User off, forum optional, should be off. 233 $result = forum_tp_can_track_forums($forumoptional, $useroff); 234 $this->assertEquals(false, $result); 235 236 // Don't allow force. 237 $CFG->forum_allowforcedreadtracking = 0; 238 239 // User on, forum off, should be off. 240 $result = forum_tp_can_track_forums($forumoff, $useron); 241 $this->assertEquals(false, $result); 242 243 // User on, forum on, should be on. 244 $result = forum_tp_can_track_forums($forumforce, $useron); 245 $this->assertEquals(true, $result); 246 247 // User on, forum optional, should be on. 248 $result = forum_tp_can_track_forums($forumoptional, $useron); 249 $this->assertEquals(true, $result); 250 251 // User off, forum off, should be off. 252 $result = forum_tp_can_track_forums($forumoff, $useroff); 253 $this->assertEquals(false, $result); 254 255 // User off, forum force, should be off. 256 $result = forum_tp_can_track_forums($forumforce, $useroff); 257 $this->assertEquals(false, $result); 258 259 // User off, forum optional, should be off. 260 $result = forum_tp_can_track_forums($forumoptional, $useroff); 261 $this->assertEquals(false, $result); 262 263 } 264 265 /** 266 * Test the logic in the test_forum_tp_is_tracked() function. 267 */ 268 public function test_forum_tp_is_tracked() { 269 global $CFG; 270 271 $this->resetAfterTest(); 272 273 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); 274 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); 275 $course = $this->getDataGenerator()->create_course(); 276 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. 277 $forumoff = $this->getDataGenerator()->create_module('forum', $options); 278 279 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On. 280 $forumforce = $this->getDataGenerator()->create_module('forum', $options); 281 282 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. 283 $forumoptional = $this->getDataGenerator()->create_module('forum', $options); 284 285 // Allow force. 286 $CFG->forum_allowforcedreadtracking = 1; 287 288 // User on, forum off, should be off. 289 $result = forum_tp_is_tracked($forumoff, $useron); 290 $this->assertEquals(false, $result); 291 292 // User on, forum force, should be on. 293 $result = forum_tp_is_tracked($forumforce, $useron); 294 $this->assertEquals(true, $result); 295 296 // User on, forum optional, should be on. 297 $result = forum_tp_is_tracked($forumoptional, $useron); 298 $this->assertEquals(true, $result); 299 300 // User off, forum off, should be off. 301 $result = forum_tp_is_tracked($forumoff, $useroff); 302 $this->assertEquals(false, $result); 303 304 // User off, forum force, should be on. 305 $result = forum_tp_is_tracked($forumforce, $useroff); 306 $this->assertEquals(true, $result); 307 308 // User off, forum optional, should be off. 309 $result = forum_tp_is_tracked($forumoptional, $useroff); 310 $this->assertEquals(false, $result); 311 312 // Don't allow force. 313 $CFG->forum_allowforcedreadtracking = 0; 314 315 // User on, forum off, should be off. 316 $result = forum_tp_is_tracked($forumoff, $useron); 317 $this->assertEquals(false, $result); 318 319 // User on, forum force, should be on. 320 $result = forum_tp_is_tracked($forumforce, $useron); 321 $this->assertEquals(true, $result); 322 323 // User on, forum optional, should be on. 324 $result = forum_tp_is_tracked($forumoptional, $useron); 325 $this->assertEquals(true, $result); 326 327 // User off, forum off, should be off. 328 $result = forum_tp_is_tracked($forumoff, $useroff); 329 $this->assertEquals(false, $result); 330 331 // User off, forum force, should be off. 332 $result = forum_tp_is_tracked($forumforce, $useroff); 333 $this->assertEquals(false, $result); 334 335 // User off, forum optional, should be off. 336 $result = forum_tp_is_tracked($forumoptional, $useroff); 337 $this->assertEquals(false, $result); 338 339 // Stop tracking so we can test again. 340 forum_tp_stop_tracking($forumforce->id, $useron->id); 341 forum_tp_stop_tracking($forumoptional->id, $useron->id); 342 forum_tp_stop_tracking($forumforce->id, $useroff->id); 343 forum_tp_stop_tracking($forumoptional->id, $useroff->id); 344 345 // Allow force. 346 $CFG->forum_allowforcedreadtracking = 1; 347 348 // User on, preference off, forum force, should be on. 349 $result = forum_tp_is_tracked($forumforce, $useron); 350 $this->assertEquals(true, $result); 351 352 // User on, preference off, forum optional, should be on. 353 $result = forum_tp_is_tracked($forumoptional, $useron); 354 $this->assertEquals(false, $result); 355 356 // User off, preference off, forum force, should be on. 357 $result = forum_tp_is_tracked($forumforce, $useroff); 358 $this->assertEquals(true, $result); 359 360 // User off, preference off, forum optional, should be off. 361 $result = forum_tp_is_tracked($forumoptional, $useroff); 362 $this->assertEquals(false, $result); 363 364 // Don't allow force. 365 $CFG->forum_allowforcedreadtracking = 0; 366 367 // User on, preference off, forum force, should be on. 368 $result = forum_tp_is_tracked($forumforce, $useron); 369 $this->assertEquals(false, $result); 370 371 // User on, preference off, forum optional, should be on. 372 $result = forum_tp_is_tracked($forumoptional, $useron); 373 $this->assertEquals(false, $result); 374 375 // User off, preference off, forum force, should be off. 376 $result = forum_tp_is_tracked($forumforce, $useroff); 377 $this->assertEquals(false, $result); 378 379 // User off, preference off, forum optional, should be off. 380 $result = forum_tp_is_tracked($forumoptional, $useroff); 381 $this->assertEquals(false, $result); 382 } 383 384 /** 385 * Test the logic in the forum_tp_get_course_unread_posts() function. 386 */ 387 public function test_forum_tp_get_course_unread_posts() { 388 global $CFG; 389 390 $this->resetAfterTest(); 391 392 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); 393 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); 394 $course = $this->getDataGenerator()->create_course(); 395 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. 396 $forumoff = $this->getDataGenerator()->create_module('forum', $options); 397 398 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On. 399 $forumforce = $this->getDataGenerator()->create_module('forum', $options); 400 401 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. 402 $forumoptional = $this->getDataGenerator()->create_module('forum', $options); 403 404 // Add discussions to the tracking off forum. 405 $record = new stdClass(); 406 $record->course = $course->id; 407 $record->userid = $useron->id; 408 $record->forum = $forumoff->id; 409 $discussionoff = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 410 411 // Add discussions to the tracking forced forum. 412 $record = new stdClass(); 413 $record->course = $course->id; 414 $record->userid = $useron->id; 415 $record->forum = $forumforce->id; 416 $discussionforce = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 417 418 // Add post to the tracking forced discussion. 419 $record = new stdClass(); 420 $record->course = $course->id; 421 $record->userid = $useroff->id; 422 $record->forum = $forumforce->id; 423 $record->discussion = $discussionforce->id; 424 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); 425 426 // Add discussions to the tracking optional forum. 427 $record = new stdClass(); 428 $record->course = $course->id; 429 $record->userid = $useron->id; 430 $record->forum = $forumoptional->id; 431 $discussionoptional = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 432 433 // Allow force. 434 $CFG->forum_allowforcedreadtracking = 1; 435 436 $result = forum_tp_get_course_unread_posts($useron->id, $course->id); 437 $this->assertEquals(2, count($result)); 438 $this->assertEquals(false, isset($result[$forumoff->id])); 439 $this->assertEquals(true, isset($result[$forumforce->id])); 440 $this->assertEquals(2, $result[$forumforce->id]->unread); 441 $this->assertEquals(true, isset($result[$forumoptional->id])); 442 $this->assertEquals(1, $result[$forumoptional->id]->unread); 443 444 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); 445 $this->assertEquals(1, count($result)); 446 $this->assertEquals(false, isset($result[$forumoff->id])); 447 $this->assertEquals(true, isset($result[$forumforce->id])); 448 $this->assertEquals(2, $result[$forumforce->id]->unread); 449 $this->assertEquals(false, isset($result[$forumoptional->id])); 450 451 // Don't allow force. 452 $CFG->forum_allowforcedreadtracking = 0; 453 454 $result = forum_tp_get_course_unread_posts($useron->id, $course->id); 455 $this->assertEquals(2, count($result)); 456 $this->assertEquals(false, isset($result[$forumoff->id])); 457 $this->assertEquals(true, isset($result[$forumforce->id])); 458 $this->assertEquals(2, $result[$forumforce->id]->unread); 459 $this->assertEquals(true, isset($result[$forumoptional->id])); 460 $this->assertEquals(1, $result[$forumoptional->id]->unread); 461 462 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); 463 $this->assertEquals(0, count($result)); 464 $this->assertEquals(false, isset($result[$forumoff->id])); 465 $this->assertEquals(false, isset($result[$forumforce->id])); 466 $this->assertEquals(false, isset($result[$forumoptional->id])); 467 468 // Stop tracking so we can test again. 469 forum_tp_stop_tracking($forumforce->id, $useron->id); 470 forum_tp_stop_tracking($forumoptional->id, $useron->id); 471 forum_tp_stop_tracking($forumforce->id, $useroff->id); 472 forum_tp_stop_tracking($forumoptional->id, $useroff->id); 473 474 // Allow force. 475 $CFG->forum_allowforcedreadtracking = 1; 476 477 $result = forum_tp_get_course_unread_posts($useron->id, $course->id); 478 $this->assertEquals(1, count($result)); 479 $this->assertEquals(false, isset($result[$forumoff->id])); 480 $this->assertEquals(true, isset($result[$forumforce->id])); 481 $this->assertEquals(2, $result[$forumforce->id]->unread); 482 $this->assertEquals(false, isset($result[$forumoptional->id])); 483 484 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); 485 $this->assertEquals(1, count($result)); 486 $this->assertEquals(false, isset($result[$forumoff->id])); 487 $this->assertEquals(true, isset($result[$forumforce->id])); 488 $this->assertEquals(2, $result[$forumforce->id]->unread); 489 $this->assertEquals(false, isset($result[$forumoptional->id])); 490 491 // Don't allow force. 492 $CFG->forum_allowforcedreadtracking = 0; 493 494 $result = forum_tp_get_course_unread_posts($useron->id, $course->id); 495 $this->assertEquals(0, count($result)); 496 $this->assertEquals(false, isset($result[$forumoff->id])); 497 $this->assertEquals(false, isset($result[$forumforce->id])); 498 $this->assertEquals(false, isset($result[$forumoptional->id])); 499 500 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); 501 $this->assertEquals(0, count($result)); 502 $this->assertEquals(false, isset($result[$forumoff->id])); 503 $this->assertEquals(false, isset($result[$forumforce->id])); 504 $this->assertEquals(false, isset($result[$forumoptional->id])); 505 } 506 507 /** 508 * Test the logic in the test_forum_tp_get_untracked_forums() function. 509 */ 510 public function test_forum_tp_get_untracked_forums() { 511 global $CFG; 512 513 $this->resetAfterTest(); 514 515 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); 516 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); 517 $course = $this->getDataGenerator()->create_course(); 518 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. 519 $forumoff = $this->getDataGenerator()->create_module('forum', $options); 520 521 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On. 522 $forumforce = $this->getDataGenerator()->create_module('forum', $options); 523 524 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. 525 $forumoptional = $this->getDataGenerator()->create_module('forum', $options); 526 527 // Allow force. 528 $CFG->forum_allowforcedreadtracking = 1; 529 530 // On user with force on. 531 $result = forum_tp_get_untracked_forums($useron->id, $course->id); 532 $this->assertEquals(1, count($result)); 533 $this->assertEquals(true, isset($result[$forumoff->id])); 534 535 // Off user with force on. 536 $result = forum_tp_get_untracked_forums($useroff->id, $course->id); 537 $this->assertEquals(2, count($result)); 538 $this->assertEquals(true, isset($result[$forumoff->id])); 539 $this->assertEquals(true, isset($result[$forumoptional->id])); 540 541 // Don't allow force. 542 $CFG->forum_allowforcedreadtracking = 0; 543 544 // On user with force off. 545 $result = forum_tp_get_untracked_forums($useron->id, $course->id); 546 $this->assertEquals(1, count($result)); 547 $this->assertEquals(true, isset($result[$forumoff->id])); 548 549 // Off user with force off. 550 $result = forum_tp_get_untracked_forums($useroff->id, $course->id); 551 $this->assertEquals(3, count($result)); 552 $this->assertEquals(true, isset($result[$forumoff->id])); 553 $this->assertEquals(true, isset($result[$forumoptional->id])); 554 $this->assertEquals(true, isset($result[$forumforce->id])); 555 556 // Stop tracking so we can test again. 557 forum_tp_stop_tracking($forumforce->id, $useron->id); 558 forum_tp_stop_tracking($forumoptional->id, $useron->id); 559 forum_tp_stop_tracking($forumforce->id, $useroff->id); 560 forum_tp_stop_tracking($forumoptional->id, $useroff->id); 561 562 // Allow force. 563 $CFG->forum_allowforcedreadtracking = 1; 564 565 // On user with force on. 566 $result = forum_tp_get_untracked_forums($useron->id, $course->id); 567 $this->assertEquals(2, count($result)); 568 $this->assertEquals(true, isset($result[$forumoff->id])); 569 $this->assertEquals(true, isset($result[$forumoptional->id])); 570 571 // Off user with force on. 572 $result = forum_tp_get_untracked_forums($useroff->id, $course->id); 573 $this->assertEquals(2, count($result)); 574 $this->assertEquals(true, isset($result[$forumoff->id])); 575 $this->assertEquals(true, isset($result[$forumoptional->id])); 576 577 // Don't allow force. 578 $CFG->forum_allowforcedreadtracking = 0; 579 580 // On user with force off. 581 $result = forum_tp_get_untracked_forums($useron->id, $course->id); 582 $this->assertEquals(3, count($result)); 583 $this->assertEquals(true, isset($result[$forumoff->id])); 584 $this->assertEquals(true, isset($result[$forumoptional->id])); 585 $this->assertEquals(true, isset($result[$forumforce->id])); 586 587 // Off user with force off. 588 $result = forum_tp_get_untracked_forums($useroff->id, $course->id); 589 $this->assertEquals(3, count($result)); 590 $this->assertEquals(true, isset($result[$forumoff->id])); 591 $this->assertEquals(true, isset($result[$forumoptional->id])); 592 $this->assertEquals(true, isset($result[$forumforce->id])); 593 } 594 595 /** 596 * Test subscription using automatic subscription on create. 597 */ 598 public function test_forum_auto_subscribe_on_create() { 599 global $CFG; 600 601 $this->resetAfterTest(); 602 603 $usercount = 5; 604 $course = $this->getDataGenerator()->create_course(); 605 $users = array(); 606 607 for ($i = 0; $i < $usercount; $i++) { 608 $user = $this->getDataGenerator()->create_user(); 609 $users[] = $user; 610 $this->getDataGenerator()->enrol_user($user->id, $course->id); 611 } 612 613 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE); // Automatic Subscription. 614 $forum = $this->getDataGenerator()->create_module('forum', $options); 615 616 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum); 617 $this->assertEquals($usercount, count($result)); 618 foreach ($users as $user) { 619 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum)); 620 } 621 } 622 623 /** 624 * Test subscription using forced subscription on create. 625 */ 626 public function test_forum_forced_subscribe_on_create() { 627 global $CFG; 628 629 $this->resetAfterTest(); 630 631 $usercount = 5; 632 $course = $this->getDataGenerator()->create_course(); 633 $users = array(); 634 635 for ($i = 0; $i < $usercount; $i++) { 636 $user = $this->getDataGenerator()->create_user(); 637 $users[] = $user; 638 $this->getDataGenerator()->enrol_user($user->id, $course->id); 639 } 640 641 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE); // Forced subscription. 642 $forum = $this->getDataGenerator()->create_module('forum', $options); 643 644 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum); 645 $this->assertEquals($usercount, count($result)); 646 foreach ($users as $user) { 647 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum)); 648 } 649 } 650 651 /** 652 * Test subscription using optional subscription on create. 653 */ 654 public function test_forum_optional_subscribe_on_create() { 655 global $CFG; 656 657 $this->resetAfterTest(); 658 659 $usercount = 5; 660 $course = $this->getDataGenerator()->create_course(); 661 $users = array(); 662 663 for ($i = 0; $i < $usercount; $i++) { 664 $user = $this->getDataGenerator()->create_user(); 665 $users[] = $user; 666 $this->getDataGenerator()->enrol_user($user->id, $course->id); 667 } 668 669 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); // Subscription optional. 670 $forum = $this->getDataGenerator()->create_module('forum', $options); 671 672 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum); 673 // No subscriptions by default. 674 $this->assertEquals(0, count($result)); 675 foreach ($users as $user) { 676 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum)); 677 } 678 } 679 680 /** 681 * Test subscription using disallow subscription on create. 682 */ 683 public function test_forum_disallow_subscribe_on_create() { 684 global $CFG; 685 686 $this->resetAfterTest(); 687 688 $usercount = 5; 689 $course = $this->getDataGenerator()->create_course(); 690 $users = array(); 691 692 for ($i = 0; $i < $usercount; $i++) { 693 $user = $this->getDataGenerator()->create_user(); 694 $users[] = $user; 695 $this->getDataGenerator()->enrol_user($user->id, $course->id); 696 } 697 698 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE); // Subscription prevented. 699 $forum = $this->getDataGenerator()->create_module('forum', $options); 700 701 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum); 702 // No subscriptions by default. 703 $this->assertEquals(0, count($result)); 704 foreach ($users as $user) { 705 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum)); 706 } 707 } 708 709 /** 710 * Test that context fetching returns the appropriate context. 711 */ 712 public function test_forum_get_context() { 713 global $DB, $PAGE; 714 715 $this->resetAfterTest(); 716 717 // Setup test data. 718 $course = $this->getDataGenerator()->create_course(); 719 $coursecontext = \context_course::instance($course->id); 720 721 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); 722 $forum = $this->getDataGenerator()->create_module('forum', $options); 723 $forumcm = get_coursemodule_from_instance('forum', $forum->id); 724 $forumcontext = \context_module::instance($forumcm->id); 725 726 // First check that specifying the context results in the correct context being returned. 727 // Do this before we set up the page object and we should return from the coursemodule record. 728 // There should be no DB queries here because the context type was correct. 729 $startcount = $DB->perf_get_reads(); 730 $result = forum_get_context($forum->id, $forumcontext); 731 $aftercount = $DB->perf_get_reads(); 732 $this->assertEquals($forumcontext, $result); 733 $this->assertEquals(0, $aftercount - $startcount); 734 735 // And a context which is not the correct type. 736 // This tests will result in a DB query to fetch the course_module. 737 $startcount = $DB->perf_get_reads(); 738 $result = forum_get_context($forum->id, $coursecontext); 739 $aftercount = $DB->perf_get_reads(); 740 $this->assertEquals($forumcontext, $result); 741 $this->assertEquals(1, $aftercount - $startcount); 742 743 // Now do not specify a context at all. 744 // This tests will result in a DB query to fetch the course_module. 745 $startcount = $DB->perf_get_reads(); 746 $result = forum_get_context($forum->id); 747 $aftercount = $DB->perf_get_reads(); 748 $this->assertEquals($forumcontext, $result); 749 $this->assertEquals(1, $aftercount - $startcount); 750 751 // Set up the default page event to use the forum. 752 $PAGE = new moodle_page(); 753 $PAGE->set_context($forumcontext); 754 $PAGE->set_cm($forumcm, $course, $forum); 755 756 // Now specify a context which is not a context_module. 757 // There should be no DB queries here because we use the PAGE. 758 $startcount = $DB->perf_get_reads(); 759 $result = forum_get_context($forum->id, $coursecontext); 760 $aftercount = $DB->perf_get_reads(); 761 $this->assertEquals($forumcontext, $result); 762 $this->assertEquals(0, $aftercount - $startcount); 763 764 // Now do not specify a context at all. 765 // There should be no DB queries here because we use the PAGE. 766 $startcount = $DB->perf_get_reads(); 767 $result = forum_get_context($forum->id); 768 $aftercount = $DB->perf_get_reads(); 769 $this->assertEquals($forumcontext, $result); 770 $this->assertEquals(0, $aftercount - $startcount); 771 772 // Now specify the page context of the course instead.. 773 $PAGE = new moodle_page(); 774 $PAGE->set_context($coursecontext); 775 776 // Now specify a context which is not a context_module. 777 // This tests will result in a DB query to fetch the course_module. 778 $startcount = $DB->perf_get_reads(); 779 $result = forum_get_context($forum->id, $coursecontext); 780 $aftercount = $DB->perf_get_reads(); 781 $this->assertEquals($forumcontext, $result); 782 $this->assertEquals(1, $aftercount - $startcount); 783 784 // Now do not specify a context at all. 785 // This tests will result in a DB query to fetch the course_module. 786 $startcount = $DB->perf_get_reads(); 787 $result = forum_get_context($forum->id); 788 $aftercount = $DB->perf_get_reads(); 789 $this->assertEquals($forumcontext, $result); 790 $this->assertEquals(1, $aftercount - $startcount); 791 } 792 793 /** 794 * Test getting the neighbour threads of a discussion. 795 */ 796 public function test_forum_get_neighbours() { 797 global $CFG, $DB; 798 $this->resetAfterTest(); 799 800 $timenow = time(); 801 $timenext = $timenow; 802 803 // Setup test data. 804 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 805 $course = $this->getDataGenerator()->create_course(); 806 $user = $this->getDataGenerator()->create_user(); 807 $user2 = $this->getDataGenerator()->create_user(); 808 809 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 810 $cm = get_coursemodule_from_instance('forum', $forum->id); 811 $context = context_module::instance($cm->id); 812 813 $record = new stdClass(); 814 $record->course = $course->id; 815 $record->userid = $user->id; 816 $record->forum = $forum->id; 817 $record->timemodified = time(); 818 $disc1 = $forumgen->create_discussion($record); 819 $record->timemodified++; 820 $disc2 = $forumgen->create_discussion($record); 821 $record->timemodified++; 822 $disc3 = $forumgen->create_discussion($record); 823 $record->timemodified++; 824 $disc4 = $forumgen->create_discussion($record); 825 $record->timemodified++; 826 $disc5 = $forumgen->create_discussion($record); 827 828 // Getting the neighbours. 829 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum); 830 $this->assertEmpty($neighbours['prev']); 831 $this->assertEquals($disc2->id, $neighbours['next']->id); 832 833 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 834 $this->assertEquals($disc1->id, $neighbours['prev']->id); 835 $this->assertEquals($disc3->id, $neighbours['next']->id); 836 837 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum); 838 $this->assertEquals($disc2->id, $neighbours['prev']->id); 839 $this->assertEquals($disc4->id, $neighbours['next']->id); 840 841 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum); 842 $this->assertEquals($disc3->id, $neighbours['prev']->id); 843 $this->assertEquals($disc5->id, $neighbours['next']->id); 844 845 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum); 846 $this->assertEquals($disc4->id, $neighbours['prev']->id); 847 $this->assertEmpty($neighbours['next']); 848 849 // Post in some discussions. We manually update the discussion record because 850 // the data generator plays with timemodified in a way that would break this test. 851 $record->timemodified++; 852 $disc1->timemodified = $record->timemodified; 853 $DB->update_record('forum_discussions', $disc1); 854 855 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum); 856 $this->assertEquals($disc4->id, $neighbours['prev']->id); 857 $this->assertEquals($disc1->id, $neighbours['next']->id); 858 859 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 860 $this->assertEmpty($neighbours['prev']); 861 $this->assertEquals($disc3->id, $neighbours['next']->id); 862 863 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum); 864 $this->assertEquals($disc5->id, $neighbours['prev']->id); 865 $this->assertEmpty($neighbours['next']); 866 867 // After some discussions were created. 868 $record->timemodified++; 869 $disc6 = $forumgen->create_discussion($record); 870 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum); 871 $this->assertEquals($disc1->id, $neighbours['prev']->id); 872 $this->assertEmpty($neighbours['next']); 873 874 $record->timemodified++; 875 $disc7 = $forumgen->create_discussion($record); 876 $neighbours = forum_get_discussion_neighbours($cm, $disc7, $forum); 877 $this->assertEquals($disc6->id, $neighbours['prev']->id); 878 $this->assertEmpty($neighbours['next']); 879 880 // Adding timed discussions. 881 $CFG->forum_enabletimedposts = true; 882 $now = $record->timemodified; 883 $past = $now - 60; 884 $future = $now + 60; 885 886 $record = new stdClass(); 887 $record->course = $course->id; 888 $record->userid = $user->id; 889 $record->forum = $forum->id; 890 $record->timestart = $past; 891 $record->timeend = $future; 892 $record->timemodified = $now; 893 $record->timemodified++; 894 $disc8 = $forumgen->create_discussion($record); 895 $record->timemodified++; 896 $record->timestart = $future; 897 $record->timeend = 0; 898 $disc9 = $forumgen->create_discussion($record); 899 $record->timemodified++; 900 $record->timestart = 0; 901 $record->timeend = 0; 902 $disc10 = $forumgen->create_discussion($record); 903 $record->timemodified++; 904 $record->timestart = 0; 905 $record->timeend = $past; 906 $disc11 = $forumgen->create_discussion($record); 907 $record->timemodified++; 908 $record->timestart = $past; 909 $record->timeend = $future; 910 $disc12 = $forumgen->create_discussion($record); 911 $record->timemodified++; 912 $record->timestart = $future + 1; // Should be last post for those that can see it. 913 $record->timeend = 0; 914 $disc13 = $forumgen->create_discussion($record); 915 916 // Admin user ignores the timed settings of discussions. 917 // Post ordering taking into account timestart: 918 // 8 = t 919 // 10 = t+3 920 // 11 = t+4 921 // 12 = t+5 922 // 9 = t+60 923 // 13 = t+61. 924 $this->setAdminUser(); 925 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 926 $this->assertEquals($disc7->id, $neighbours['prev']->id); 927 $this->assertEquals($disc10->id, $neighbours['next']->id); 928 929 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum); 930 $this->assertEquals($disc12->id, $neighbours['prev']->id); 931 $this->assertEquals($disc13->id, $neighbours['next']->id); 932 933 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 934 $this->assertEquals($disc8->id, $neighbours['prev']->id); 935 $this->assertEquals($disc11->id, $neighbours['next']->id); 936 937 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum); 938 $this->assertEquals($disc10->id, $neighbours['prev']->id); 939 $this->assertEquals($disc12->id, $neighbours['next']->id); 940 941 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 942 $this->assertEquals($disc11->id, $neighbours['prev']->id); 943 $this->assertEquals($disc9->id, $neighbours['next']->id); 944 945 $neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum); 946 $this->assertEquals($disc9->id, $neighbours['prev']->id); 947 $this->assertEmpty($neighbours['next']); 948 949 // Normal user can see their own timed discussions. 950 $this->setUser($user); 951 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 952 $this->assertEquals($disc7->id, $neighbours['prev']->id); 953 $this->assertEquals($disc10->id, $neighbours['next']->id); 954 955 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum); 956 $this->assertEquals($disc12->id, $neighbours['prev']->id); 957 $this->assertEquals($disc13->id, $neighbours['next']->id); 958 959 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 960 $this->assertEquals($disc8->id, $neighbours['prev']->id); 961 $this->assertEquals($disc11->id, $neighbours['next']->id); 962 963 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum); 964 $this->assertEquals($disc10->id, $neighbours['prev']->id); 965 $this->assertEquals($disc12->id, $neighbours['next']->id); 966 967 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 968 $this->assertEquals($disc11->id, $neighbours['prev']->id); 969 $this->assertEquals($disc9->id, $neighbours['next']->id); 970 971 $neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum); 972 $this->assertEquals($disc9->id, $neighbours['prev']->id); 973 $this->assertEmpty($neighbours['next']); 974 975 // Normal user does not ignore timed settings. 976 $this->setUser($user2); 977 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 978 $this->assertEquals($disc7->id, $neighbours['prev']->id); 979 $this->assertEquals($disc10->id, $neighbours['next']->id); 980 981 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 982 $this->assertEquals($disc8->id, $neighbours['prev']->id); 983 $this->assertEquals($disc12->id, $neighbours['next']->id); 984 985 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 986 $this->assertEquals($disc10->id, $neighbours['prev']->id); 987 $this->assertEmpty($neighbours['next']); 988 989 // Reset to normal mode. 990 $CFG->forum_enabletimedposts = false; 991 $this->setAdminUser(); 992 993 // Two discussions with identical timemodified will sort by id. 994 $record->timemodified += 25; 995 $DB->update_record('forum_discussions', (object) array('id' => $disc3->id, 'timemodified' => $record->timemodified)); 996 $DB->update_record('forum_discussions', (object) array('id' => $disc2->id, 'timemodified' => $record->timemodified)); 997 $DB->update_record('forum_discussions', (object) array('id' => $disc12->id, 'timemodified' => $record->timemodified - 5)); 998 $disc2 = $DB->get_record('forum_discussions', array('id' => $disc2->id)); 999 $disc3 = $DB->get_record('forum_discussions', array('id' => $disc3->id)); 1000 1001 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum); 1002 $this->assertEquals($disc2->id, $neighbours['prev']->id); 1003 $this->assertEmpty($neighbours['next']); 1004 1005 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 1006 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1007 $this->assertEquals($disc3->id, $neighbours['next']->id); 1008 1009 // Set timemodified to not be identical. 1010 $DB->update_record('forum_discussions', (object) array('id' => $disc2->id, 'timemodified' => $record->timemodified - 1)); 1011 1012 // Test pinned posts behave correctly. 1013 $disc8->pinned = FORUM_DISCUSSION_PINNED; 1014 $DB->update_record('forum_discussions', (object) array('id' => $disc8->id, 'pinned' => $disc8->pinned)); 1015 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 1016 $this->assertEquals($disc3->id, $neighbours['prev']->id); 1017 $this->assertEmpty($neighbours['next']); 1018 1019 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum); 1020 $this->assertEquals($disc2->id, $neighbours['prev']->id); 1021 $this->assertEquals($disc8->id, $neighbours['next']->id); 1022 1023 // Test 3 pinned posts. 1024 $disc6->pinned = FORUM_DISCUSSION_PINNED; 1025 $DB->update_record('forum_discussions', (object) array('id' => $disc6->id, 'pinned' => $disc6->pinned)); 1026 $disc4->pinned = FORUM_DISCUSSION_PINNED; 1027 $DB->update_record('forum_discussions', (object) array('id' => $disc4->id, 'pinned' => $disc4->pinned)); 1028 1029 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum); 1030 $this->assertEquals($disc4->id, $neighbours['prev']->id); 1031 $this->assertEquals($disc8->id, $neighbours['next']->id); 1032 1033 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum); 1034 $this->assertEquals($disc3->id, $neighbours['prev']->id); 1035 $this->assertEquals($disc6->id, $neighbours['next']->id); 1036 1037 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 1038 $this->assertEquals($disc6->id, $neighbours['prev']->id); 1039 $this->assertEmpty($neighbours['next']); 1040 } 1041 1042 /** 1043 * Test getting the neighbour threads of a blog-like forum. 1044 */ 1045 public function test_forum_get_neighbours_blog() { 1046 global $CFG, $DB; 1047 $this->resetAfterTest(); 1048 1049 $timenow = time(); 1050 $timenext = $timenow; 1051 1052 // Setup test data. 1053 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 1054 $course = $this->getDataGenerator()->create_course(); 1055 $user = $this->getDataGenerator()->create_user(); 1056 $user2 = $this->getDataGenerator()->create_user(); 1057 1058 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog')); 1059 $cm = get_coursemodule_from_instance('forum', $forum->id); 1060 $context = context_module::instance($cm->id); 1061 1062 $record = new stdClass(); 1063 $record->course = $course->id; 1064 $record->userid = $user->id; 1065 $record->forum = $forum->id; 1066 $record->timemodified = time(); 1067 $disc1 = $forumgen->create_discussion($record); 1068 $record->timemodified++; 1069 $disc2 = $forumgen->create_discussion($record); 1070 $record->timemodified++; 1071 $disc3 = $forumgen->create_discussion($record); 1072 $record->timemodified++; 1073 $disc4 = $forumgen->create_discussion($record); 1074 $record->timemodified++; 1075 $disc5 = $forumgen->create_discussion($record); 1076 1077 // Getting the neighbours. 1078 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum); 1079 $this->assertEmpty($neighbours['prev']); 1080 $this->assertEquals($disc2->id, $neighbours['next']->id); 1081 1082 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 1083 $this->assertEquals($disc1->id, $neighbours['prev']->id); 1084 $this->assertEquals($disc3->id, $neighbours['next']->id); 1085 1086 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum); 1087 $this->assertEquals($disc2->id, $neighbours['prev']->id); 1088 $this->assertEquals($disc4->id, $neighbours['next']->id); 1089 1090 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum); 1091 $this->assertEquals($disc3->id, $neighbours['prev']->id); 1092 $this->assertEquals($disc5->id, $neighbours['next']->id); 1093 1094 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum); 1095 $this->assertEquals($disc4->id, $neighbours['prev']->id); 1096 $this->assertEmpty($neighbours['next']); 1097 1098 // Make sure that the thread's timemodified does not affect the order. 1099 $record->timemodified++; 1100 $disc1->timemodified = $record->timemodified; 1101 $DB->update_record('forum_discussions', $disc1); 1102 1103 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum); 1104 $this->assertEmpty($neighbours['prev']); 1105 $this->assertEquals($disc2->id, $neighbours['next']->id); 1106 1107 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 1108 $this->assertEquals($disc1->id, $neighbours['prev']->id); 1109 $this->assertEquals($disc3->id, $neighbours['next']->id); 1110 1111 // Add another blog post. 1112 $record->timemodified++; 1113 $disc6 = $forumgen->create_discussion($record); 1114 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum); 1115 $this->assertEquals($disc5->id, $neighbours['prev']->id); 1116 $this->assertEmpty($neighbours['next']); 1117 1118 $record->timemodified++; 1119 $disc7 = $forumgen->create_discussion($record); 1120 $neighbours = forum_get_discussion_neighbours($cm, $disc7, $forum); 1121 $this->assertEquals($disc6->id, $neighbours['prev']->id); 1122 $this->assertEmpty($neighbours['next']); 1123 1124 // Adding timed discussions. 1125 $CFG->forum_enabletimedposts = true; 1126 $now = $record->timemodified; 1127 $past = $now - 60; 1128 $future = $now + 60; 1129 1130 $record = new stdClass(); 1131 $record->course = $course->id; 1132 $record->userid = $user->id; 1133 $record->forum = $forum->id; 1134 $record->timestart = $past; 1135 $record->timeend = $future; 1136 $record->timemodified = $now; 1137 $record->timemodified++; 1138 $disc8 = $forumgen->create_discussion($record); 1139 $record->timemodified++; 1140 $record->timestart = $future; 1141 $record->timeend = 0; 1142 $disc9 = $forumgen->create_discussion($record); 1143 $record->timemodified++; 1144 $record->timestart = 0; 1145 $record->timeend = 0; 1146 $disc10 = $forumgen->create_discussion($record); 1147 $record->timemodified++; 1148 $record->timestart = 0; 1149 $record->timeend = $past; 1150 $disc11 = $forumgen->create_discussion($record); 1151 $record->timemodified++; 1152 $record->timestart = $past; 1153 $record->timeend = $future; 1154 $disc12 = $forumgen->create_discussion($record); 1155 1156 // Admin user ignores the timed settings of discussions. 1157 $this->setAdminUser(); 1158 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 1159 $this->assertEquals($disc7->id, $neighbours['prev']->id); 1160 $this->assertEquals($disc9->id, $neighbours['next']->id); 1161 1162 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum); 1163 $this->assertEquals($disc8->id, $neighbours['prev']->id); 1164 $this->assertEquals($disc10->id, $neighbours['next']->id); 1165 1166 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 1167 $this->assertEquals($disc9->id, $neighbours['prev']->id); 1168 $this->assertEquals($disc11->id, $neighbours['next']->id); 1169 1170 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum); 1171 $this->assertEquals($disc10->id, $neighbours['prev']->id); 1172 $this->assertEquals($disc12->id, $neighbours['next']->id); 1173 1174 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 1175 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1176 $this->assertEmpty($neighbours['next']); 1177 1178 // Normal user can see their own timed discussions. 1179 $this->setUser($user); 1180 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 1181 $this->assertEquals($disc7->id, $neighbours['prev']->id); 1182 $this->assertEquals($disc9->id, $neighbours['next']->id); 1183 1184 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum); 1185 $this->assertEquals($disc8->id, $neighbours['prev']->id); 1186 $this->assertEquals($disc10->id, $neighbours['next']->id); 1187 1188 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 1189 $this->assertEquals($disc9->id, $neighbours['prev']->id); 1190 $this->assertEquals($disc11->id, $neighbours['next']->id); 1191 1192 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum); 1193 $this->assertEquals($disc10->id, $neighbours['prev']->id); 1194 $this->assertEquals($disc12->id, $neighbours['next']->id); 1195 1196 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 1197 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1198 $this->assertEmpty($neighbours['next']); 1199 1200 // Normal user does not ignore timed settings. 1201 $this->setUser($user2); 1202 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum); 1203 $this->assertEquals($disc7->id, $neighbours['prev']->id); 1204 $this->assertEquals($disc10->id, $neighbours['next']->id); 1205 1206 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum); 1207 $this->assertEquals($disc8->id, $neighbours['prev']->id); 1208 $this->assertEquals($disc12->id, $neighbours['next']->id); 1209 1210 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum); 1211 $this->assertEquals($disc10->id, $neighbours['prev']->id); 1212 $this->assertEmpty($neighbours['next']); 1213 1214 // Reset to normal mode. 1215 $CFG->forum_enabletimedposts = false; 1216 $this->setAdminUser(); 1217 1218 $record->timemodified++; 1219 // Two blog posts with identical creation time will sort by id. 1220 $DB->update_record('forum_posts', (object) array('id' => $disc2->firstpost, 'created' => $record->timemodified)); 1221 $DB->update_record('forum_posts', (object) array('id' => $disc3->firstpost, 'created' => $record->timemodified)); 1222 1223 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum); 1224 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1225 $this->assertEquals($disc3->id, $neighbours['next']->id); 1226 1227 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum); 1228 $this->assertEquals($disc2->id, $neighbours['prev']->id); 1229 $this->assertEmpty($neighbours['next']); 1230 } 1231 1232 /** 1233 * Test getting the neighbour threads of a discussion. 1234 */ 1235 public function test_forum_get_neighbours_with_groups() { 1236 $this->resetAfterTest(); 1237 1238 $timenow = time(); 1239 $timenext = $timenow; 1240 1241 // Setup test data. 1242 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 1243 $course = $this->getDataGenerator()->create_course(); 1244 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1245 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1246 $user1 = $this->getDataGenerator()->create_user(); 1247 $user2 = $this->getDataGenerator()->create_user(); 1248 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 1249 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 1250 $this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group1->id)); 1251 1252 $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'groupmode' => VISIBLEGROUPS)); 1253 $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'groupmode' => SEPARATEGROUPS)); 1254 $cm1 = get_coursemodule_from_instance('forum', $forum1->id); 1255 $cm2 = get_coursemodule_from_instance('forum', $forum2->id); 1256 $context1 = context_module::instance($cm1->id); 1257 $context2 = context_module::instance($cm2->id); 1258 1259 // Creating discussions in both forums. 1260 $record = new stdClass(); 1261 $record->course = $course->id; 1262 $record->userid = $user1->id; 1263 $record->forum = $forum1->id; 1264 $record->groupid = $group1->id; 1265 $record->timemodified = time(); 1266 $disc11 = $forumgen->create_discussion($record); 1267 $record->forum = $forum2->id; 1268 $record->timemodified++; 1269 $disc21 = $forumgen->create_discussion($record); 1270 1271 $record->timemodified++; 1272 $record->userid = $user2->id; 1273 $record->forum = $forum1->id; 1274 $record->groupid = $group2->id; 1275 $disc12 = $forumgen->create_discussion($record); 1276 $record->forum = $forum2->id; 1277 $disc22 = $forumgen->create_discussion($record); 1278 1279 $record->timemodified++; 1280 $record->userid = $user1->id; 1281 $record->forum = $forum1->id; 1282 $record->groupid = null; 1283 $disc13 = $forumgen->create_discussion($record); 1284 $record->forum = $forum2->id; 1285 $disc23 = $forumgen->create_discussion($record); 1286 1287 $record->timemodified++; 1288 $record->userid = $user2->id; 1289 $record->forum = $forum1->id; 1290 $record->groupid = $group2->id; 1291 $disc14 = $forumgen->create_discussion($record); 1292 $record->forum = $forum2->id; 1293 $disc24 = $forumgen->create_discussion($record); 1294 1295 $record->timemodified++; 1296 $record->userid = $user1->id; 1297 $record->forum = $forum1->id; 1298 $record->groupid = $group1->id; 1299 $disc15 = $forumgen->create_discussion($record); 1300 $record->forum = $forum2->id; 1301 $disc25 = $forumgen->create_discussion($record); 1302 1303 // Admin user can see all groups. 1304 $this->setAdminUser(); 1305 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1306 $this->assertEmpty($neighbours['prev']); 1307 $this->assertEquals($disc12->id, $neighbours['next']->id); 1308 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1309 $this->assertEmpty($neighbours['prev']); 1310 $this->assertEquals($disc22->id, $neighbours['next']->id); 1311 1312 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1); 1313 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1314 $this->assertEquals($disc13->id, $neighbours['next']->id); 1315 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2); 1316 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1317 $this->assertEquals($disc23->id, $neighbours['next']->id); 1318 1319 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1320 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1321 $this->assertEquals($disc14->id, $neighbours['next']->id); 1322 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1323 $this->assertEquals($disc22->id, $neighbours['prev']->id); 1324 $this->assertEquals($disc24->id, $neighbours['next']->id); 1325 1326 $neighbours = forum_get_discussion_neighbours($cm1, $disc14, $forum1); 1327 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1328 $this->assertEquals($disc15->id, $neighbours['next']->id); 1329 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2); 1330 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1331 $this->assertEquals($disc25->id, $neighbours['next']->id); 1332 1333 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1334 $this->assertEquals($disc14->id, $neighbours['prev']->id); 1335 $this->assertEmpty($neighbours['next']); 1336 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1337 $this->assertEquals($disc24->id, $neighbours['prev']->id); 1338 $this->assertEmpty($neighbours['next']); 1339 1340 // Admin user is only viewing group 1. 1341 $_POST['group'] = $group1->id; 1342 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true)); 1343 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true)); 1344 1345 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1346 $this->assertEmpty($neighbours['prev']); 1347 $this->assertEquals($disc13->id, $neighbours['next']->id); 1348 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1349 $this->assertEmpty($neighbours['prev']); 1350 $this->assertEquals($disc23->id, $neighbours['next']->id); 1351 1352 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1353 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1354 $this->assertEquals($disc15->id, $neighbours['next']->id); 1355 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1356 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1357 $this->assertEquals($disc25->id, $neighbours['next']->id); 1358 1359 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1360 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1361 $this->assertEmpty($neighbours['next']); 1362 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1363 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1364 $this->assertEmpty($neighbours['next']); 1365 1366 // Normal user viewing non-grouped posts (this is only possible in visible groups). 1367 $this->setUser($user1); 1368 $_POST['group'] = 0; 1369 $this->assertEquals(0, groups_get_activity_group($cm1, true)); 1370 1371 // They can see anything in visible groups. 1372 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1); 1373 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1374 $this->assertEquals($disc13->id, $neighbours['next']->id); 1375 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1376 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1377 $this->assertEquals($disc14->id, $neighbours['next']->id); 1378 1379 // Normal user, orphan of groups, can only see non-grouped posts in separate groups. 1380 $this->setUser($user2); 1381 $_POST['group'] = 0; 1382 $this->assertEquals(0, groups_get_activity_group($cm2, true)); 1383 1384 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1385 $this->assertEmpty($neighbours['prev']); 1386 $this->assertEmpty($neighbours['next']); 1387 1388 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2); 1389 $this->assertEmpty($neighbours['prev']); 1390 $this->assertEquals($disc23->id, $neighbours['next']->id); 1391 1392 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2); 1393 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1394 $this->assertEmpty($neighbours['next']); 1395 1396 // Switching to viewing group 1. 1397 $this->setUser($user1); 1398 $_POST['group'] = $group1->id; 1399 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true)); 1400 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true)); 1401 1402 // They can see non-grouped or same group. 1403 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1404 $this->assertEmpty($neighbours['prev']); 1405 $this->assertEquals($disc13->id, $neighbours['next']->id); 1406 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1407 $this->assertEmpty($neighbours['prev']); 1408 $this->assertEquals($disc23->id, $neighbours['next']->id); 1409 1410 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1411 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1412 $this->assertEquals($disc15->id, $neighbours['next']->id); 1413 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1414 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1415 $this->assertEquals($disc25->id, $neighbours['next']->id); 1416 1417 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1418 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1419 $this->assertEmpty($neighbours['next']); 1420 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1421 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1422 $this->assertEmpty($neighbours['next']); 1423 1424 // Querying the neighbours of a discussion passing the wrong CM. 1425 $this->expectException('coding_exception'); 1426 forum_get_discussion_neighbours($cm2, $disc11, $forum2); 1427 } 1428 1429 /** 1430 * Test getting the neighbour threads of a blog-like forum with groups involved. 1431 */ 1432 public function test_forum_get_neighbours_with_groups_blog() { 1433 $this->resetAfterTest(); 1434 1435 $timenow = time(); 1436 $timenext = $timenow; 1437 1438 // Setup test data. 1439 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 1440 $course = $this->getDataGenerator()->create_course(); 1441 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1442 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1443 $user1 = $this->getDataGenerator()->create_user(); 1444 $user2 = $this->getDataGenerator()->create_user(); 1445 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 1446 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 1447 $this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group1->id)); 1448 1449 $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog', 1450 'groupmode' => VISIBLEGROUPS)); 1451 $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog', 1452 'groupmode' => SEPARATEGROUPS)); 1453 $cm1 = get_coursemodule_from_instance('forum', $forum1->id); 1454 $cm2 = get_coursemodule_from_instance('forum', $forum2->id); 1455 $context1 = context_module::instance($cm1->id); 1456 $context2 = context_module::instance($cm2->id); 1457 1458 // Creating blog posts in both forums. 1459 $record = new stdClass(); 1460 $record->course = $course->id; 1461 $record->userid = $user1->id; 1462 $record->forum = $forum1->id; 1463 $record->groupid = $group1->id; 1464 $record->timemodified = time(); 1465 $disc11 = $forumgen->create_discussion($record); 1466 $record->timenow = $timenext++; 1467 $record->forum = $forum2->id; 1468 $record->timemodified++; 1469 $disc21 = $forumgen->create_discussion($record); 1470 1471 $record->timemodified++; 1472 $record->userid = $user2->id; 1473 $record->forum = $forum1->id; 1474 $record->groupid = $group2->id; 1475 $disc12 = $forumgen->create_discussion($record); 1476 $record->forum = $forum2->id; 1477 $disc22 = $forumgen->create_discussion($record); 1478 1479 $record->timemodified++; 1480 $record->userid = $user1->id; 1481 $record->forum = $forum1->id; 1482 $record->groupid = null; 1483 $disc13 = $forumgen->create_discussion($record); 1484 $record->forum = $forum2->id; 1485 $disc23 = $forumgen->create_discussion($record); 1486 1487 $record->timemodified++; 1488 $record->userid = $user2->id; 1489 $record->forum = $forum1->id; 1490 $record->groupid = $group2->id; 1491 $disc14 = $forumgen->create_discussion($record); 1492 $record->forum = $forum2->id; 1493 $disc24 = $forumgen->create_discussion($record); 1494 1495 $record->timemodified++; 1496 $record->userid = $user1->id; 1497 $record->forum = $forum1->id; 1498 $record->groupid = $group1->id; 1499 $disc15 = $forumgen->create_discussion($record); 1500 $record->forum = $forum2->id; 1501 $disc25 = $forumgen->create_discussion($record); 1502 1503 // Admin user can see all groups. 1504 $this->setAdminUser(); 1505 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1506 $this->assertEmpty($neighbours['prev']); 1507 $this->assertEquals($disc12->id, $neighbours['next']->id); 1508 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1509 $this->assertEmpty($neighbours['prev']); 1510 $this->assertEquals($disc22->id, $neighbours['next']->id); 1511 1512 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1); 1513 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1514 $this->assertEquals($disc13->id, $neighbours['next']->id); 1515 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2); 1516 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1517 $this->assertEquals($disc23->id, $neighbours['next']->id); 1518 1519 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1520 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1521 $this->assertEquals($disc14->id, $neighbours['next']->id); 1522 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1523 $this->assertEquals($disc22->id, $neighbours['prev']->id); 1524 $this->assertEquals($disc24->id, $neighbours['next']->id); 1525 1526 $neighbours = forum_get_discussion_neighbours($cm1, $disc14, $forum1); 1527 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1528 $this->assertEquals($disc15->id, $neighbours['next']->id); 1529 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2); 1530 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1531 $this->assertEquals($disc25->id, $neighbours['next']->id); 1532 1533 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1534 $this->assertEquals($disc14->id, $neighbours['prev']->id); 1535 $this->assertEmpty($neighbours['next']); 1536 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1537 $this->assertEquals($disc24->id, $neighbours['prev']->id); 1538 $this->assertEmpty($neighbours['next']); 1539 1540 // Admin user is only viewing group 1. 1541 $_POST['group'] = $group1->id; 1542 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true)); 1543 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true)); 1544 1545 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1546 $this->assertEmpty($neighbours['prev']); 1547 $this->assertEquals($disc13->id, $neighbours['next']->id); 1548 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1549 $this->assertEmpty($neighbours['prev']); 1550 $this->assertEquals($disc23->id, $neighbours['next']->id); 1551 1552 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1553 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1554 $this->assertEquals($disc15->id, $neighbours['next']->id); 1555 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1556 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1557 $this->assertEquals($disc25->id, $neighbours['next']->id); 1558 1559 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1560 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1561 $this->assertEmpty($neighbours['next']); 1562 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1563 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1564 $this->assertEmpty($neighbours['next']); 1565 1566 // Normal user viewing non-grouped posts (this is only possible in visible groups). 1567 $this->setUser($user1); 1568 $_POST['group'] = 0; 1569 $this->assertEquals(0, groups_get_activity_group($cm1, true)); 1570 1571 // They can see anything in visible groups. 1572 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1); 1573 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1574 $this->assertEquals($disc13->id, $neighbours['next']->id); 1575 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1576 $this->assertEquals($disc12->id, $neighbours['prev']->id); 1577 $this->assertEquals($disc14->id, $neighbours['next']->id); 1578 1579 // Normal user, orphan of groups, can only see non-grouped posts in separate groups. 1580 $this->setUser($user2); 1581 $_POST['group'] = 0; 1582 $this->assertEquals(0, groups_get_activity_group($cm2, true)); 1583 1584 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1585 $this->assertEmpty($neighbours['prev']); 1586 $this->assertEmpty($neighbours['next']); 1587 1588 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2); 1589 $this->assertEmpty($neighbours['prev']); 1590 $this->assertEquals($disc23->id, $neighbours['next']->id); 1591 1592 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2); 1593 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1594 $this->assertEmpty($neighbours['next']); 1595 1596 // Switching to viewing group 1. 1597 $this->setUser($user1); 1598 $_POST['group'] = $group1->id; 1599 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true)); 1600 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true)); 1601 1602 // They can see non-grouped or same group. 1603 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1); 1604 $this->assertEmpty($neighbours['prev']); 1605 $this->assertEquals($disc13->id, $neighbours['next']->id); 1606 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2); 1607 $this->assertEmpty($neighbours['prev']); 1608 $this->assertEquals($disc23->id, $neighbours['next']->id); 1609 1610 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1); 1611 $this->assertEquals($disc11->id, $neighbours['prev']->id); 1612 $this->assertEquals($disc15->id, $neighbours['next']->id); 1613 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2); 1614 $this->assertEquals($disc21->id, $neighbours['prev']->id); 1615 $this->assertEquals($disc25->id, $neighbours['next']->id); 1616 1617 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1); 1618 $this->assertEquals($disc13->id, $neighbours['prev']->id); 1619 $this->assertEmpty($neighbours['next']); 1620 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2); 1621 $this->assertEquals($disc23->id, $neighbours['prev']->id); 1622 $this->assertEmpty($neighbours['next']); 1623 1624 // Querying the neighbours of a discussion passing the wrong CM. 1625 $this->expectException('coding_exception'); 1626 forum_get_discussion_neighbours($cm2, $disc11, $forum2); 1627 } 1628 1629 public function test_count_discussion_replies_basic() { 1630 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1631 1632 // Count the discussion replies in the forum. 1633 $result = forum_count_discussion_replies($forum->id); 1634 $this->assertCount(10, $result); 1635 } 1636 1637 public function test_count_discussion_replies_limited() { 1638 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1639 // Adding limits shouldn't make a difference. 1640 $result = forum_count_discussion_replies($forum->id, "", 20); 1641 $this->assertCount(10, $result); 1642 } 1643 1644 public function test_count_discussion_replies_paginated() { 1645 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1646 // Adding paging shouldn't make any difference. 1647 $result = forum_count_discussion_replies($forum->id, "", -1, 0, 100); 1648 $this->assertCount(10, $result); 1649 } 1650 1651 public function test_count_discussion_replies_paginated_sorted() { 1652 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1653 // Specifying the forumsort should also give a good result. This follows a different path. 1654 $result = forum_count_discussion_replies($forum->id, "d.id asc", -1, 0, 100); 1655 $this->assertCount(10, $result); 1656 foreach ($result as $row) { 1657 // Grab the first discussionid. 1658 $discussionid = array_shift($discussionids); 1659 $this->assertEquals($discussionid, $row->discussion); 1660 } 1661 } 1662 1663 public function test_count_discussion_replies_limited_sorted() { 1664 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1665 // Adding limits, and a forumsort shouldn't make a difference. 1666 $result = forum_count_discussion_replies($forum->id, "d.id asc", 20); 1667 $this->assertCount(10, $result); 1668 foreach ($result as $row) { 1669 // Grab the first discussionid. 1670 $discussionid = array_shift($discussionids); 1671 $this->assertEquals($discussionid, $row->discussion); 1672 } 1673 } 1674 1675 public function test_count_discussion_replies_paginated_sorted_small() { 1676 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1677 // Grabbing a smaller subset and they should be ordered as expected. 1678 $result = forum_count_discussion_replies($forum->id, "d.id asc", -1, 0, 5); 1679 $this->assertCount(5, $result); 1680 foreach ($result as $row) { 1681 // Grab the first discussionid. 1682 $discussionid = array_shift($discussionids); 1683 $this->assertEquals($discussionid, $row->discussion); 1684 } 1685 } 1686 1687 public function test_count_discussion_replies_paginated_sorted_small_reverse() { 1688 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1689 // Grabbing a smaller subset and they should be ordered as expected. 1690 $result = forum_count_discussion_replies($forum->id, "d.id desc", -1, 0, 5); 1691 $this->assertCount(5, $result); 1692 foreach ($result as $row) { 1693 // Grab the last discussionid. 1694 $discussionid = array_pop($discussionids); 1695 $this->assertEquals($discussionid, $row->discussion); 1696 } 1697 } 1698 1699 public function test_count_discussion_replies_limited_sorted_small_reverse() { 1700 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1701 // Adding limits, and a forumsort shouldn't make a difference. 1702 $result = forum_count_discussion_replies($forum->id, "d.id desc", 5); 1703 $this->assertCount(5, $result); 1704 foreach ($result as $row) { 1705 // Grab the last discussionid. 1706 $discussionid = array_pop($discussionids); 1707 $this->assertEquals($discussionid, $row->discussion); 1708 } 1709 } 1710 public function test_discussion_pinned_sort() { 1711 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5); 1712 $cm = get_coursemodule_from_instance('forum', $forum->id); 1713 $discussions = forum_get_discussions($cm); 1714 // First discussion should be pinned. 1715 $first = reset($discussions); 1716 $this->assertEquals(1, $first->pinned, "First discussion should be pinned discussion"); 1717 } 1718 public function test_forum_view() { 1719 global $CFG; 1720 1721 $CFG->enablecompletion = 1; 1722 $this->resetAfterTest(); 1723 1724 // Setup test data. 1725 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 1726 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), 1727 array('completion' => 2, 'completionview' => 1)); 1728 $context = context_module::instance($forum->cmid); 1729 $cm = get_coursemodule_from_instance('forum', $forum->id); 1730 1731 // Trigger and capture the event. 1732 $sink = $this->redirectEvents(); 1733 1734 $this->setAdminUser(); 1735 forum_view($forum, $course, $cm, $context); 1736 1737 $events = $sink->get_events(); 1738 // 2 additional events thanks to completion. 1739 $this->assertCount(3, $events); 1740 $event = array_pop($events); 1741 1742 // Checking that the event contains the expected values. 1743 $this->assertInstanceOf('\mod_forum\event\course_module_viewed', $event); 1744 $this->assertEquals($context, $event->get_context()); 1745 $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id)); 1746 $this->assertEquals($url, $event->get_url()); 1747 $this->assertEventContextNotUsed($event); 1748 $this->assertNotEmpty($event->get_name()); 1749 1750 // Check completion status. 1751 $completion = new completion_info($course); 1752 $completiondata = $completion->get_data($cm); 1753 $this->assertEquals(1, $completiondata->completionstate); 1754 1755 } 1756 1757 /** 1758 * Test forum_discussion_view. 1759 */ 1760 public function test_forum_discussion_view() { 1761 global $CFG, $USER; 1762 1763 $this->resetAfterTest(); 1764 1765 // Setup test data. 1766 $course = $this->getDataGenerator()->create_course(); 1767 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 1768 $discussion = $this->create_single_discussion_with_replies($forum, $USER, 2); 1769 1770 $context = context_module::instance($forum->cmid); 1771 $cm = get_coursemodule_from_instance('forum', $forum->id); 1772 1773 // Trigger and capture the event. 1774 $sink = $this->redirectEvents(); 1775 1776 $this->setAdminUser(); 1777 forum_discussion_view($context, $forum, $discussion); 1778 1779 $events = $sink->get_events(); 1780 $this->assertCount(1, $events); 1781 $event = array_pop($events); 1782 1783 // Checking that the event contains the expected values. 1784 $this->assertInstanceOf('\mod_forum\event\discussion_viewed', $event); 1785 $this->assertEquals($context, $event->get_context()); 1786 $expected = array($course->id, 'forum', 'view discussion', "discuss.php?d={$discussion->id}", 1787 $discussion->id, $forum->cmid); 1788 $this->assertEventLegacyLogData($expected, $event); 1789 $this->assertEventContextNotUsed($event); 1790 1791 $this->assertNotEmpty($event->get_name()); 1792 1793 } 1794 1795 /** 1796 * Create a new course, forum, and user with a number of discussions and replies. 1797 * 1798 * @param int $discussioncount The number of discussions to create 1799 * @param int $replycount The number of replies to create in each discussion 1800 * @return array Containing the created forum object, and the ids of the created discussions. 1801 */ 1802 protected function create_multiple_discussions_with_replies($discussioncount, $replycount) { 1803 $this->resetAfterTest(); 1804 1805 // Setup the content. 1806 $user = $this->getDataGenerator()->create_user(); 1807 $course = $this->getDataGenerator()->create_course(); 1808 $record = new stdClass(); 1809 $record->course = $course->id; 1810 $forum = $this->getDataGenerator()->create_module('forum', $record); 1811 1812 // Create 10 discussions with replies. 1813 $discussionids = array(); 1814 for ($i = 0; $i < $discussioncount; $i++) { 1815 // Pin 3rd discussion. 1816 if ($i == 3) { 1817 $discussion = $this->create_single_discussion_pinned_with_replies($forum, $user, $replycount); 1818 } else { 1819 $discussion = $this->create_single_discussion_with_replies($forum, $user, $replycount); 1820 } 1821 1822 $discussionids[] = $discussion->id; 1823 } 1824 return array($forum, $discussionids); 1825 } 1826 1827 /** 1828 * Create a discussion with a number of replies. 1829 * 1830 * @param object $forum The forum which has been created 1831 * @param object $user The user making the discussion and replies 1832 * @param int $replycount The number of replies 1833 * @return object $discussion 1834 */ 1835 protected function create_single_discussion_with_replies($forum, $user, $replycount) { 1836 global $DB; 1837 1838 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); 1839 1840 $record = new stdClass(); 1841 $record->course = $forum->course; 1842 $record->forum = $forum->id; 1843 $record->userid = $user->id; 1844 $discussion = $generator->create_discussion($record); 1845 1846 // Retrieve the first post. 1847 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 1848 1849 // Create the replies. 1850 $post = new stdClass(); 1851 $post->userid = $user->id; 1852 $post->discussion = $discussion->id; 1853 $post->parent = $replyto->id; 1854 1855 for ($i = 0; $i < $replycount; $i++) { 1856 $generator->create_post($post); 1857 } 1858 1859 return $discussion; 1860 } 1861 /** 1862 * Create a discussion with a number of replies. 1863 * 1864 * @param object $forum The forum which has been created 1865 * @param object $user The user making the discussion and replies 1866 * @param int $replycount The number of replies 1867 * @return object $discussion 1868 */ 1869 protected function create_single_discussion_pinned_with_replies($forum, $user, $replycount) { 1870 global $DB; 1871 1872 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); 1873 1874 $record = new stdClass(); 1875 $record->course = $forum->course; 1876 $record->forum = $forum->id; 1877 $record->userid = $user->id; 1878 $record->pinned = FORUM_DISCUSSION_PINNED; 1879 $discussion = $generator->create_discussion($record); 1880 1881 // Retrieve the first post. 1882 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 1883 1884 // Create the replies. 1885 $post = new stdClass(); 1886 $post->userid = $user->id; 1887 $post->discussion = $discussion->id; 1888 $post->parent = $replyto->id; 1889 1890 for ($i = 0; $i < $replycount; $i++) { 1891 $generator->create_post($post); 1892 } 1893 1894 return $discussion; 1895 } 1896 1897 /** 1898 * Tests for mod_forum_rating_can_see_item_ratings(). 1899 * 1900 * @throws coding_exception 1901 * @throws rating_exception 1902 */ 1903 public function test_mod_forum_rating_can_see_item_ratings() { 1904 global $DB; 1905 1906 $this->resetAfterTest(); 1907 1908 // Setup test data. 1909 $course = new stdClass(); 1910 $course->groupmode = SEPARATEGROUPS; 1911 $course->groupmodeforce = true; 1912 $course = $this->getDataGenerator()->create_course($course); 1913 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 1914 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum'); 1915 $cm = get_coursemodule_from_instance('forum', $forum->id); 1916 $context = context_module::instance($cm->id); 1917 1918 // Create users. 1919 $user1 = $this->getDataGenerator()->create_user(); 1920 $user2 = $this->getDataGenerator()->create_user(); 1921 $user3 = $this->getDataGenerator()->create_user(); 1922 $user4 = $this->getDataGenerator()->create_user(); 1923 1924 // Groups and stuff. 1925 $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST); 1926 $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id); 1927 $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id); 1928 $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id); 1929 $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id); 1930 1931 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1932 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 1933 groups_add_member($group1, $user1); 1934 groups_add_member($group1, $user2); 1935 groups_add_member($group2, $user3); 1936 groups_add_member($group2, $user4); 1937 1938 $record = new stdClass(); 1939 $record->course = $forum->course; 1940 $record->forum = $forum->id; 1941 $record->userid = $user1->id; 1942 $record->groupid = $group1->id; 1943 $discussion = $generator->create_discussion($record); 1944 1945 // Retrieve the first post. 1946 $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 1947 1948 $ratingoptions = new stdClass; 1949 $ratingoptions->context = $context; 1950 $ratingoptions->ratingarea = 'post'; 1951 $ratingoptions->component = 'mod_forum'; 1952 $ratingoptions->itemid = $post->id; 1953 $ratingoptions->scaleid = 2; 1954 $ratingoptions->userid = $user2->id; 1955 $rating = new rating($ratingoptions); 1956 $rating->update_rating(2); 1957 1958 // Now try to access it as various users. 1959 unassign_capability('moodle/site:accessallgroups', $role->id); 1960 $params = array('contextid' => 2, 1961 'component' => 'mod_forum', 1962 'ratingarea' => 'post', 1963 'itemid' => $post->id, 1964 'scaleid' => 2); 1965 $this->setUser($user1); 1966 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1967 $this->setUser($user2); 1968 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1969 $this->setUser($user3); 1970 $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); 1971 $this->setUser($user4); 1972 $this->assertFalse(mod_forum_rating_can_see_item_ratings($params)); 1973 1974 // Now try with accessallgroups cap and make sure everything is visible. 1975 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id); 1976 $this->setUser($user1); 1977 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1978 $this->setUser($user2); 1979 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1980 $this->setUser($user3); 1981 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1982 $this->setUser($user4); 1983 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1984 1985 // Change group mode and verify visibility. 1986 $course->groupmode = VISIBLEGROUPS; 1987 $DB->update_record('course', $course); 1988 unassign_capability('moodle/site:accessallgroups', $role->id); 1989 $this->setUser($user1); 1990 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1991 $this->setUser($user2); 1992 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1993 $this->setUser($user3); 1994 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1995 $this->setUser($user4); 1996 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params)); 1997 1998 } 1999 2000 /** 2001 * Test forum_get_discussions 2002 */ 2003 public function test_forum_get_discussions_with_groups() { 2004 global $DB; 2005 2006 $this->resetAfterTest(true); 2007 2008 // Create course to add the module. 2009 $course = self::getDataGenerator()->create_course(array('groupmode' => VISIBLEGROUPS, 'groupmodeforce' => 0)); 2010 $user1 = self::getDataGenerator()->create_user(); 2011 $user2 = self::getDataGenerator()->create_user(); 2012 $user3 = self::getDataGenerator()->create_user(); 2013 2014 $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 2015 self::getDataGenerator()->enrol_user($user1->id, $course->id, $role->id); 2016 self::getDataGenerator()->enrol_user($user2->id, $course->id, $role->id); 2017 self::getDataGenerator()->enrol_user($user3->id, $course->id, $role->id); 2018 2019 // Forum forcing separate gropus. 2020 $record = new stdClass(); 2021 $record->course = $course->id; 2022 $forum = self::getDataGenerator()->create_module('forum', $record, array('groupmode' => SEPARATEGROUPS)); 2023 $cm = get_coursemodule_from_instance('forum', $forum->id); 2024 2025 // Create groups. 2026 $group1 = self::getDataGenerator()->create_group(array('courseid' => $course->id)); 2027 $group2 = self::getDataGenerator()->create_group(array('courseid' => $course->id)); 2028 $group3 = self::getDataGenerator()->create_group(array('courseid' => $course->id)); 2029 2030 // Add the user1 to g1 and g2 groups. 2031 groups_add_member($group1->id, $user1->id); 2032 groups_add_member($group2->id, $user1->id); 2033 2034 // Add the user 2 and 3 to only one group. 2035 groups_add_member($group1->id, $user2->id); 2036 groups_add_member($group3->id, $user3->id); 2037 2038 // Add a few discussions. 2039 $record = array(); 2040 $record['course'] = $course->id; 2041 $record['forum'] = $forum->id; 2042 $record['userid'] = $user1->id; 2043 $record['groupid'] = $group1->id; 2044 $discussiong1u1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2045 2046 $record['groupid'] = $group2->id; 2047 $discussiong2u1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2048 2049 $record['userid'] = $user2->id; 2050 $record['groupid'] = $group1->id; 2051 $discussiong1u2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2052 2053 $record['userid'] = $user3->id; 2054 $record['groupid'] = $group3->id; 2055 $discussiong3u3 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2056 2057 self::setUser($user1); 2058 // Test retrieve discussions not passing the groupid parameter. We will receive only first group discussions. 2059 $discussions = forum_get_discussions($cm); 2060 self::assertCount(2, $discussions); 2061 foreach ($discussions as $discussion) { 2062 self::assertEquals($group1->id, $discussion->groupid); 2063 } 2064 2065 // Get all my discussions. 2066 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, 0); 2067 self::assertCount(3, $discussions); 2068 2069 // Get all my g1 discussions. 2070 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group1->id); 2071 self::assertCount(2, $discussions); 2072 foreach ($discussions as $discussion) { 2073 self::assertEquals($group1->id, $discussion->groupid); 2074 } 2075 2076 // Get all my g2 discussions. 2077 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group2->id); 2078 self::assertCount(1, $discussions); 2079 $discussion = array_shift($discussions); 2080 self::assertEquals($group2->id, $discussion->groupid); 2081 self::assertEquals($user1->id, $discussion->userid); 2082 self::assertEquals($discussiong2u1->id, $discussion->discussion); 2083 2084 // Get all my g3 discussions (I'm not enrolled in that group). 2085 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id); 2086 self::assertCount(0, $discussions); 2087 2088 // This group does not exist. 2089 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id + 1000); 2090 self::assertCount(0, $discussions); 2091 2092 self::setUser($user2); 2093 2094 // Test retrieve discussions not passing the groupid parameter. We will receive only first group discussions. 2095 $discussions = forum_get_discussions($cm); 2096 self::assertCount(2, $discussions); 2097 foreach ($discussions as $discussion) { 2098 self::assertEquals($group1->id, $discussion->groupid); 2099 } 2100 2101 // Get all my viewable discussions. 2102 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, 0); 2103 self::assertCount(2, $discussions); 2104 foreach ($discussions as $discussion) { 2105 self::assertEquals($group1->id, $discussion->groupid); 2106 } 2107 2108 // Get all my g2 discussions (I'm not enrolled in that group). 2109 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group2->id); 2110 self::assertCount(0, $discussions); 2111 2112 // Get all my g3 discussions (I'm not enrolled in that group). 2113 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id); 2114 self::assertCount(0, $discussions); 2115 2116 } 2117 2118 /** 2119 * Test forum_user_can_post_discussion 2120 */ 2121 public function test_forum_user_can_post_discussion() { 2122 global $CFG, $DB; 2123 2124 $this->resetAfterTest(true); 2125 2126 // Create course to add the module. 2127 $course = self::getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1)); 2128 $user = self::getDataGenerator()->create_user(); 2129 $this->getDataGenerator()->enrol_user($user->id, $course->id); 2130 2131 // Forum forcing separate gropus. 2132 $record = new stdClass(); 2133 $record->course = $course->id; 2134 $forum = self::getDataGenerator()->create_module('forum', $record, array('groupmode' => SEPARATEGROUPS)); 2135 $cm = get_coursemodule_from_instance('forum', $forum->id); 2136 $context = context_module::instance($cm->id); 2137 2138 self::setUser($user); 2139 2140 // The user is not enroled in any group, try to post in a forum with separate groups. 2141 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2142 $this->assertFalse($can); 2143 2144 // Create a group. 2145 $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 2146 2147 // Try to post in a group the user is not enrolled. 2148 $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context); 2149 $this->assertFalse($can); 2150 2151 // Add the user to a group. 2152 groups_add_member($group->id, $user->id); 2153 2154 // Try to post in a group the user is not enrolled. 2155 $can = forum_user_can_post_discussion($forum, $group->id + 1, -1, $cm, $context); 2156 $this->assertFalse($can); 2157 2158 // Now try to post in the user group. (null means it will guess the group). 2159 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2160 $this->assertTrue($can); 2161 2162 $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context); 2163 $this->assertTrue($can); 2164 2165 // Test all groups. 2166 $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context); 2167 $this->assertFalse($can); 2168 2169 $this->setAdminUser(); 2170 $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context); 2171 $this->assertTrue($can); 2172 2173 // Change forum type. 2174 $forum->type = 'news'; 2175 $DB->update_record('forum', $forum); 2176 2177 // Admin can post news. 2178 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2179 $this->assertTrue($can); 2180 2181 // Normal users don't. 2182 self::setUser($user); 2183 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2184 $this->assertFalse($can); 2185 2186 // Change forum type. 2187 $forum->type = 'eachuser'; 2188 $DB->update_record('forum', $forum); 2189 2190 // I didn't post yet, so I should be able to post. 2191 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2192 $this->assertTrue($can); 2193 2194 // Post now. 2195 $record = new stdClass(); 2196 $record->course = $course->id; 2197 $record->userid = $user->id; 2198 $record->forum = $forum->id; 2199 $record->groupid = $group->id; 2200 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2201 2202 // I already posted, I shouldn't be able to post. 2203 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2204 $this->assertFalse($can); 2205 2206 // Last check with no groups, normal forum and course. 2207 $course->groupmode = NOGROUPS; 2208 $course->groupmodeforce = 0; 2209 $DB->update_record('course', $course); 2210 2211 $forum->type = 'general'; 2212 $forum->groupmode = NOGROUPS; 2213 $DB->update_record('forum', $forum); 2214 2215 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 2216 $this->assertTrue($can); 2217 } 2218 2219 /** 2220 * Test forum_user_has_posted_discussion with no groups. 2221 */ 2222 public function test_forum_user_has_posted_discussion_no_groups() { 2223 global $CFG; 2224 2225 $this->resetAfterTest(true); 2226 2227 $course = self::getDataGenerator()->create_course(); 2228 $author = self::getDataGenerator()->create_user(); 2229 $other = self::getDataGenerator()->create_user(); 2230 $this->getDataGenerator()->enrol_user($author->id, $course->id); 2231 $forum = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]); 2232 2233 self::setUser($author); 2234 2235 // Neither user has posted. 2236 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id)); 2237 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $other->id)); 2238 2239 // Post in the forum. 2240 $record = new stdClass(); 2241 $record->course = $course->id; 2242 $record->userid = $author->id; 2243 $record->forum = $forum->id; 2244 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2245 2246 // The author has now posted, but the other user has not. 2247 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id)); 2248 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $other->id)); 2249 } 2250 2251 /** 2252 * Test forum_user_has_posted_discussion with multiple forums 2253 */ 2254 public function test_forum_user_has_posted_discussion_multiple_forums() { 2255 global $CFG; 2256 2257 $this->resetAfterTest(true); 2258 2259 $course = self::getDataGenerator()->create_course(); 2260 $author = self::getDataGenerator()->create_user(); 2261 $this->getDataGenerator()->enrol_user($author->id, $course->id); 2262 $forum1 = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]); 2263 $forum2 = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]); 2264 2265 self::setUser($author); 2266 2267 // No post in either forum. 2268 $this->assertFalse(forum_user_has_posted_discussion($forum1->id, $author->id)); 2269 $this->assertFalse(forum_user_has_posted_discussion($forum2->id, $author->id)); 2270 2271 // Post in the forum. 2272 $record = new stdClass(); 2273 $record->course = $course->id; 2274 $record->userid = $author->id; 2275 $record->forum = $forum1->id; 2276 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2277 2278 // The author has now posted in forum1, but not forum2. 2279 $this->assertTrue(forum_user_has_posted_discussion($forum1->id, $author->id)); 2280 $this->assertFalse(forum_user_has_posted_discussion($forum2->id, $author->id)); 2281 } 2282 2283 /** 2284 * Test forum_user_has_posted_discussion with multiple groups. 2285 */ 2286 public function test_forum_user_has_posted_discussion_multiple_groups() { 2287 global $CFG; 2288 2289 $this->resetAfterTest(true); 2290 2291 $course = self::getDataGenerator()->create_course(); 2292 $author = self::getDataGenerator()->create_user(); 2293 $this->getDataGenerator()->enrol_user($author->id, $course->id); 2294 2295 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 2296 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 2297 groups_add_member($group1->id, $author->id); 2298 groups_add_member($group2->id, $author->id); 2299 2300 $forum = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ], [ 2301 'groupmode' => SEPARATEGROUPS, 2302 ]); 2303 2304 self::setUser($author); 2305 2306 // The user has not posted in either group. 2307 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id)); 2308 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id)); 2309 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id)); 2310 2311 // Post in one group. 2312 $record = new stdClass(); 2313 $record->course = $course->id; 2314 $record->userid = $author->id; 2315 $record->forum = $forum->id; 2316 $record->groupid = $group1->id; 2317 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2318 2319 // The author has now posted in one group, but the other user has not. 2320 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id)); 2321 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id)); 2322 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id)); 2323 2324 // Post in the other group. 2325 $record = new stdClass(); 2326 $record->course = $course->id; 2327 $record->userid = $author->id; 2328 $record->forum = $forum->id; 2329 $record->groupid = $group2->id; 2330 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2331 2332 // The author has now posted in one group, but the other user has not. 2333 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id)); 2334 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id)); 2335 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id)); 2336 } 2337 2338 /** 2339 * Tests the mod_forum_myprofile_navigation() function. 2340 */ 2341 public function test_mod_forum_myprofile_navigation() { 2342 $this->resetAfterTest(true); 2343 2344 // Set up the test. 2345 $tree = new \core_user\output\myprofile\tree(); 2346 $user = $this->getDataGenerator()->create_user(); 2347 $course = $this->getDataGenerator()->create_course(); 2348 $iscurrentuser = true; 2349 2350 // Set as the current user. 2351 $this->setUser($user); 2352 2353 // Check the node tree is correct. 2354 mod_forum_myprofile_navigation($tree, $user, $iscurrentuser, $course); 2355 $reflector = new ReflectionObject($tree); 2356 $nodes = $reflector->getProperty('nodes'); 2357 $nodes->setAccessible(true); 2358 $this->assertArrayHasKey('forumposts', $nodes->getValue($tree)); 2359 $this->assertArrayHasKey('forumdiscussions', $nodes->getValue($tree)); 2360 } 2361 2362 /** 2363 * Tests the mod_forum_myprofile_navigation() function as a guest. 2364 */ 2365 public function test_mod_forum_myprofile_navigation_as_guest() { 2366 global $USER; 2367 2368 $this->resetAfterTest(true); 2369 2370 // Set up the test. 2371 $tree = new \core_user\output\myprofile\tree(); 2372 $course = $this->getDataGenerator()->create_course(); 2373 $iscurrentuser = true; 2374 2375 // Set user as guest. 2376 $this->setGuestUser(); 2377 2378 // Check the node tree is correct. 2379 mod_forum_myprofile_navigation($tree, $USER, $iscurrentuser, $course); 2380 $reflector = new ReflectionObject($tree); 2381 $nodes = $reflector->getProperty('nodes'); 2382 $nodes->setAccessible(true); 2383 $this->assertArrayNotHasKey('forumposts', $nodes->getValue($tree)); 2384 $this->assertArrayNotHasKey('forumdiscussions', $nodes->getValue($tree)); 2385 } 2386 2387 /** 2388 * Tests the mod_forum_myprofile_navigation() function as a user viewing another user's profile. 2389 */ 2390 public function test_mod_forum_myprofile_navigation_different_user() { 2391 $this->resetAfterTest(true); 2392 2393 // Set up the test. 2394 $tree = new \core_user\output\myprofile\tree(); 2395 $user = $this->getDataGenerator()->create_user(); 2396 $user2 = $this->getDataGenerator()->create_user(); 2397 $course = $this->getDataGenerator()->create_course(); 2398 $iscurrentuser = true; 2399 2400 // Set to different user's profile. 2401 $this->setUser($user2); 2402 2403 // Check the node tree is correct. 2404 mod_forum_myprofile_navigation($tree, $user, $iscurrentuser, $course); 2405 $reflector = new ReflectionObject($tree); 2406 $nodes = $reflector->getProperty('nodes'); 2407 $nodes->setAccessible(true); 2408 $this->assertArrayHasKey('forumposts', $nodes->getValue($tree)); 2409 $this->assertArrayHasKey('forumdiscussions', $nodes->getValue($tree)); 2410 } 2411 2412 public function test_print_overview() { 2413 $this->resetAfterTest(); 2414 $course1 = self::getDataGenerator()->create_course(); 2415 $course2 = self::getDataGenerator()->create_course(); 2416 2417 // Create an author user. 2418 $author = self::getDataGenerator()->create_user(); 2419 $this->getDataGenerator()->enrol_user($author->id, $course1->id); 2420 $this->getDataGenerator()->enrol_user($author->id, $course2->id); 2421 2422 // Create a viewer user. 2423 $viewer = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2424 $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); 2425 $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); 2426 2427 // Create two forums - one in each course. 2428 $record = new stdClass(); 2429 $record->course = $course1->id; 2430 $forum1 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course1->id)); 2431 $forum2 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course2->id)); 2432 2433 // A standard post in the forum. 2434 $record = new stdClass(); 2435 $record->course = $course1->id; 2436 $record->userid = $author->id; 2437 $record->forum = $forum1->id; 2438 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2439 2440 $this->setUser($viewer->id); 2441 $courses = array( 2442 $course1->id => clone $course1, 2443 $course2->id => clone $course2, 2444 ); 2445 2446 foreach ($courses as $courseid => $course) { 2447 $courses[$courseid]->lastaccess = 0; 2448 } 2449 $results = array(); 2450 forum_print_overview($courses, $results); 2451 2452 // There should be one entry for course1, and no others. 2453 $this->assertCount(1, $results); 2454 2455 // There should be one entry for a forum in course1. 2456 $this->assertCount(1, $results[$course1->id]); 2457 $this->assertArrayHasKey('forum', $results[$course1->id]); 2458 } 2459 2460 public function test_print_overview_groups() { 2461 $this->resetAfterTest(); 2462 $course1 = self::getDataGenerator()->create_course(); 2463 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); 2464 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); 2465 2466 // Create an author user. 2467 $author = self::getDataGenerator()->create_user(); 2468 $this->getDataGenerator()->enrol_user($author->id, $course1->id); 2469 2470 // Create two viewer users - one in each group. 2471 $viewer1 = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2472 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id); 2473 $this->getDataGenerator()->create_group_member(array('userid' => $viewer1->id, 'groupid' => $group1->id)); 2474 2475 $viewer2 = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2476 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id); 2477 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group2->id)); 2478 2479 // Create a forum. 2480 $record = new stdClass(); 2481 $record->course = $course1->id; 2482 $forum1 = self::getDataGenerator()->create_module('forum', (object) array( 2483 'course' => $course1->id, 2484 'groupmode' => SEPARATEGROUPS, 2485 )); 2486 2487 // A post in the forum for group1. 2488 $record = new stdClass(); 2489 $record->course = $course1->id; 2490 $record->userid = $author->id; 2491 $record->forum = $forum1->id; 2492 $record->groupid = $group1->id; 2493 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2494 2495 $course1->lastaccess = 0; 2496 $courses = array($course1->id => $course1); 2497 2498 // As viewer1 (same group as post). 2499 $this->setUser($viewer1->id); 2500 $results = array(); 2501 forum_print_overview($courses, $results); 2502 2503 // There should be one entry for course1. 2504 $this->assertCount(1, $results); 2505 2506 // There should be one entry for a forum in course1. 2507 $this->assertCount(1, $results[$course1->id]); 2508 $this->assertArrayHasKey('forum', $results[$course1->id]); 2509 2510 $this->setUser($viewer2->id); 2511 $results = array(); 2512 forum_print_overview($courses, $results); 2513 2514 // There should be one entry for course1. 2515 $this->assertCount(0, $results); 2516 } 2517 2518 /** 2519 * @dataProvider print_overview_timed_provider 2520 */ 2521 public function test_print_overview_timed($config, $hasresult) { 2522 $this->resetAfterTest(); 2523 $course1 = self::getDataGenerator()->create_course(); 2524 2525 // Create an author user. 2526 $author = self::getDataGenerator()->create_user(); 2527 $this->getDataGenerator()->enrol_user($author->id, $course1->id); 2528 2529 // Create a viewer user. 2530 $viewer = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2531 $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); 2532 2533 // Create a forum. 2534 $record = new stdClass(); 2535 $record->course = $course1->id; 2536 $forum1 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course1->id)); 2537 2538 // A timed post with a timestart in the past (24 hours ago). 2539 $record = new stdClass(); 2540 $record->course = $course1->id; 2541 $record->userid = $author->id; 2542 $record->forum = $forum1->id; 2543 if (isset($config['timestartmodifier'])) { 2544 $record->timestart = time() + $config['timestartmodifier']; 2545 } 2546 if (isset($config['timeendmodifier'])) { 2547 $record->timeend = time() + $config['timeendmodifier']; 2548 } 2549 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2550 2551 $course1->lastaccess = 0; 2552 $courses = array($course1->id => $course1); 2553 2554 // As viewer, check the forum_print_overview result. 2555 $this->setUser($viewer->id); 2556 $results = array(); 2557 forum_print_overview($courses, $results); 2558 2559 if ($hasresult) { 2560 // There should be one entry for course1. 2561 $this->assertCount(1, $results); 2562 2563 // There should be one entry for a forum in course1. 2564 $this->assertCount(1, $results[$course1->id]); 2565 $this->assertArrayHasKey('forum', $results[$course1->id]); 2566 } else { 2567 // There should be no entries for any course. 2568 $this->assertCount(0, $results); 2569 } 2570 } 2571 2572 /** 2573 * @dataProvider print_overview_timed_provider 2574 */ 2575 public function test_print_overview_timed_groups($config, $hasresult) { 2576 $this->resetAfterTest(); 2577 $course1 = self::getDataGenerator()->create_course(); 2578 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); 2579 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); 2580 2581 // Create an author user. 2582 $author = self::getDataGenerator()->create_user(); 2583 $this->getDataGenerator()->enrol_user($author->id, $course1->id); 2584 2585 // Create two viewer users - one in each group. 2586 $viewer1 = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2587 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id); 2588 $this->getDataGenerator()->create_group_member(array('userid' => $viewer1->id, 'groupid' => $group1->id)); 2589 2590 $viewer2 = self::getDataGenerator()->create_user((object) array('trackforums' => 1)); 2591 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id); 2592 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group2->id)); 2593 2594 // Create a forum. 2595 $record = new stdClass(); 2596 $record->course = $course1->id; 2597 $forum1 = self::getDataGenerator()->create_module('forum', (object) array( 2598 'course' => $course1->id, 2599 'groupmode' => SEPARATEGROUPS, 2600 )); 2601 2602 // A post in the forum for group1. 2603 $record = new stdClass(); 2604 $record->course = $course1->id; 2605 $record->userid = $author->id; 2606 $record->forum = $forum1->id; 2607 $record->groupid = $group1->id; 2608 if (isset($config['timestartmodifier'])) { 2609 $record->timestart = time() + $config['timestartmodifier']; 2610 } 2611 if (isset($config['timeendmodifier'])) { 2612 $record->timeend = time() + $config['timeendmodifier']; 2613 } 2614 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 2615 2616 $course1->lastaccess = 0; 2617 $courses = array($course1->id => $course1); 2618 2619 // As viewer1 (same group as post). 2620 $this->setUser($viewer1->id); 2621 $results = array(); 2622 forum_print_overview($courses, $results); 2623 2624 if ($hasresult) { 2625 // There should be one entry for course1. 2626 $this->assertCount(1, $results); 2627 2628 // There should be one entry for a forum in course1. 2629 $this->assertCount(1, $results[$course1->id]); 2630 $this->assertArrayHasKey('forum', $results[$course1->id]); 2631 } else { 2632 // There should be no entries for any course. 2633 $this->assertCount(0, $results); 2634 } 2635 2636 $this->setUser($viewer2->id); 2637 $results = array(); 2638 forum_print_overview($courses, $results); 2639 2640 // There should be one entry for course1. 2641 $this->assertCount(0, $results); 2642 } 2643 2644 public function print_overview_timed_provider() { 2645 return array( 2646 'timestart_past' => array( 2647 'discussionconfig' => array( 2648 'timestartmodifier' => -86000, 2649 ), 2650 'hasresult' => true, 2651 ), 2652 'timestart_future' => array( 2653 'discussionconfig' => array( 2654 'timestartmodifier' => 86000, 2655 ), 2656 'hasresult' => false, 2657 ), 2658 'timeend_past' => array( 2659 'discussionconfig' => array( 2660 'timeendmodifier' => -86000, 2661 ), 2662 'hasresult' => false, 2663 ), 2664 'timeend_future' => array( 2665 'discussionconfig' => array( 2666 'timeendmodifier' => 86000, 2667 ), 2668 'hasresult' => true, 2669 ), 2670 ); 2671 } 2672 2673 /** 2674 * Test test_pinned_discussion_with_group. 2675 */ 2676 public function test_pinned_discussion_with_group() { 2677 global $SESSION; 2678 2679 $this->resetAfterTest(); 2680 $course1 = $this->getDataGenerator()->create_course(); 2681 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id)); 2682 2683 // Create an author user. 2684 $author = $this->getDataGenerator()->create_user(); 2685 $this->getDataGenerator()->enrol_user($author->id, $course1->id); 2686 2687 // Create two viewer users - one in a group, one not. 2688 $viewer1 = $this->getDataGenerator()->create_user((object) array('trackforums' => 1)); 2689 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id); 2690 2691 $viewer2 = $this->getDataGenerator()->create_user((object) array('trackforums' => 1)); 2692 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id); 2693 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group1->id)); 2694 2695 $forum1 = $this->getDataGenerator()->create_module('forum', (object) array( 2696 'course' => $course1->id, 2697 'groupmode' => SEPARATEGROUPS, 2698 )); 2699 2700 $coursemodule = get_coursemodule_from_instance('forum', $forum1->id); 2701 2702 $alldiscussions = array(); 2703 $group1discussions = array(); 2704 2705 // Create 4 discussions in all participants group and group1, where the first 2706 // discussion is pinned in each group. 2707 $allrecord = new stdClass(); 2708 $allrecord->course = $course1->id; 2709 $allrecord->userid = $author->id; 2710 $allrecord->forum = $forum1->id; 2711 $allrecord->pinned = FORUM_DISCUSSION_PINNED; 2712 2713 $group1record = new stdClass(); 2714 $group1record->course = $course1->id; 2715 $group1record->userid = $author->id; 2716 $group1record->forum = $forum1->id; 2717 $group1record->groupid = $group1->id; 2718 $group1record->pinned = FORUM_DISCUSSION_PINNED; 2719 2720 $alldiscussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($allrecord); 2721 $group1discussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($group1record); 2722 2723 // Create unpinned discussions. 2724 $allrecord->pinned = FORUM_DISCUSSION_UNPINNED; 2725 $group1record->pinned = FORUM_DISCUSSION_UNPINNED; 2726 for ($i = 0; $i < 3; $i++) { 2727 $alldiscussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($allrecord); 2728 $group1discussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($group1record); 2729 } 2730 2731 // As viewer1 (no group). This user shouldn't see any of group1's discussions 2732 // so their expected discussion order is (where rightmost is highest priority): 2733 // Ad1, ad2, ad3, ad0. 2734 $this->setUser($viewer1->id); 2735 2736 // CHECK 1. 2737 // Take the neighbours of ad3, which should be prev: ad2 and next: ad0. 2738 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[3], $forum1); 2739 // Ad2 check. 2740 $this->assertEquals($alldiscussions[2]->id, $neighbours['prev']->id); 2741 // Ad0 check. 2742 $this->assertEquals($alldiscussions[0]->id, $neighbours['next']->id); 2743 2744 // CHECK 2. 2745 // Take the neighbours of ad0, which should be prev: ad3 and next: null. 2746 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[0], $forum1); 2747 // Ad3 check. 2748 $this->assertEquals($alldiscussions[3]->id, $neighbours['prev']->id); 2749 // Null check. 2750 $this->assertEmpty($neighbours['next']); 2751 2752 // CHECK 3. 2753 // Take the neighbours of ad1, which should be prev: null and next: ad2. 2754 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[1], $forum1); 2755 // Null check. 2756 $this->assertEmpty($neighbours['prev']); 2757 // Ad2 check. 2758 $this->assertEquals($alldiscussions[2]->id, $neighbours['next']->id); 2759 2760 // Temporary hack to workaround for MDL-52656. 2761 $SESSION->currentgroup = null; 2762 2763 // As viewer2 (group1). This user should see all of group1's posts and the all participants group. 2764 // The expected discussion order is (rightmost is highest priority): 2765 // Ad1, gd1, ad2, gd2, ad3, gd3, ad0, gd0. 2766 $this->setUser($viewer2->id); 2767 2768 // CHECK 1. 2769 // Take the neighbours of ad1, which should be prev: null and next: gd1. 2770 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[1], $forum1); 2771 // Null check. 2772 $this->assertEmpty($neighbours['prev']); 2773 // Gd1 check. 2774 $this->assertEquals($group1discussions[1]->id, $neighbours['next']->id); 2775 2776 // CHECK 2. 2777 // Take the neighbours of ad3, which should be prev: gd2 and next: gd3. 2778 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[3], $forum1); 2779 // Gd2 check. 2780 $this->assertEquals($group1discussions[2]->id, $neighbours['prev']->id); 2781 // Gd3 check. 2782 $this->assertEquals($group1discussions[3]->id, $neighbours['next']->id); 2783 2784 // CHECK 3. 2785 // Take the neighbours of gd3, which should be prev: ad3 and next: ad0. 2786 $neighbours = forum_get_discussion_neighbours($coursemodule, $group1discussions[3], $forum1); 2787 // Ad3 check. 2788 $this->assertEquals($alldiscussions[3]->id, $neighbours['prev']->id); 2789 // Ad0 check. 2790 $this->assertEquals($alldiscussions[0]->id, $neighbours['next']->id); 2791 2792 // CHECK 4. 2793 // Take the neighbours of gd0, which should be prev: ad0 and next: null. 2794 $neighbours = forum_get_discussion_neighbours($coursemodule, $group1discussions[0], $forum1); 2795 // Ad0 check. 2796 $this->assertEquals($alldiscussions[0]->id, $neighbours['prev']->id); 2797 // Null check. 2798 $this->assertEmpty($neighbours['next']); 2799 } 2800 2801 /** 2802 * Test test_pinned_with_timed_discussions. 2803 */ 2804 public function test_pinned_with_timed_discussions() { 2805 global $CFG; 2806 2807 $CFG->forum_enabletimedposts = true; 2808 2809 $this->resetAfterTest(); 2810 $course = $this->getDataGenerator()->create_course(); 2811 2812 // Create an user. 2813 $user = $this->getDataGenerator()->create_user(); 2814 $this->getDataGenerator()->enrol_user($user->id, $course->id); 2815 2816 // Create a forum. 2817 $record = new stdClass(); 2818 $record->course = $course->id; 2819 $forum = $this->getDataGenerator()->create_module('forum', (object) array( 2820 'course' => $course->id, 2821 'groupmode' => SEPARATEGROUPS, 2822 )); 2823 2824 $coursemodule = get_coursemodule_from_instance('forum', $forum->id); 2825 $now = time(); 2826 $discussions = array(); 2827 $discussiongenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 2828 2829 $record = new stdClass(); 2830 $record->course = $course->id; 2831 $record->userid = $user->id; 2832 $record->forum = $forum->id; 2833 $record->pinned = FORUM_DISCUSSION_PINNED; 2834 $record->timemodified = $now; 2835 2836 $discussions[] = $discussiongenerator->create_discussion($record); 2837 2838 $record->pinned = FORUM_DISCUSSION_UNPINNED; 2839 $record->timestart = $now + 10; 2840 2841 $discussions[] = $discussiongenerator->create_discussion($record); 2842 2843 $record->timestart = $now; 2844 2845 $discussions[] = $discussiongenerator->create_discussion($record); 2846 2847 // Expected order of discussions: 2848 // D2, d1, d0. 2849 $this->setUser($user->id); 2850 2851 // CHECK 1. 2852 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[2], $forum); 2853 // Null check. 2854 $this->assertEmpty($neighbours['prev']); 2855 // D1 check. 2856 $this->assertEquals($discussions[1]->id, $neighbours['next']->id); 2857 2858 // CHECK 2. 2859 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[1], $forum); 2860 // D2 check. 2861 $this->assertEquals($discussions[2]->id, $neighbours['prev']->id); 2862 // D0 check. 2863 $this->assertEquals($discussions[0]->id, $neighbours['next']->id); 2864 2865 // CHECK 3. 2866 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[0], $forum); 2867 // D2 check. 2868 $this->assertEquals($discussions[1]->id, $neighbours['prev']->id); 2869 // Null check. 2870 $this->assertEmpty($neighbours['next']); 2871 } 2872 2873 /** 2874 * Test test_pinned_timed_discussions_with_timed_discussions. 2875 */ 2876 public function test_pinned_timed_discussions_with_timed_discussions() { 2877 global $CFG; 2878 2879 $CFG->forum_enabletimedposts = true; 2880 2881 $this->resetAfterTest(); 2882 $course = $this->getDataGenerator()->create_course(); 2883 2884 // Create an user. 2885 $user = $this->getDataGenerator()->create_user(); 2886 $this->getDataGenerator()->enrol_user($user->id, $course->id); 2887 2888 // Create a forum. 2889 $record = new stdClass(); 2890 $record->course = $course->id; 2891 $forum = $this->getDataGenerator()->create_module('forum', (object) array( 2892 'course' => $course->id, 2893 'groupmode' => SEPARATEGROUPS, 2894 )); 2895 2896 $coursemodule = get_coursemodule_from_instance('forum', $forum->id); 2897 $now = time(); 2898 $discussions = array(); 2899 $discussiongenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 2900 2901 $record = new stdClass(); 2902 $record->course = $course->id; 2903 $record->userid = $user->id; 2904 $record->forum = $forum->id; 2905 $record->pinned = FORUM_DISCUSSION_PINNED; 2906 $record->timemodified = $now; 2907 $record->timestart = $now + 10; 2908 2909 $discussions[] = $discussiongenerator->create_discussion($record); 2910 2911 $record->pinned = FORUM_DISCUSSION_UNPINNED; 2912 2913 $discussions[] = $discussiongenerator->create_discussion($record); 2914 2915 $record->timestart = $now; 2916 2917 $discussions[] = $discussiongenerator->create_discussion($record); 2918 2919 $record->pinned = FORUM_DISCUSSION_PINNED; 2920 2921 $discussions[] = $discussiongenerator->create_discussion($record); 2922 2923 // Expected order of discussions: 2924 // D2, d1, d3, d0. 2925 $this->setUser($user->id); 2926 2927 // CHECK 1. 2928 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[2], $forum); 2929 // Null check. 2930 $this->assertEmpty($neighbours['prev']); 2931 // D1 check. 2932 $this->assertEquals($discussions[1]->id, $neighbours['next']->id); 2933 2934 // CHECK 2. 2935 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[1], $forum); 2936 // D2 check. 2937 $this->assertEquals($discussions[2]->id, $neighbours['prev']->id); 2938 // D3 check. 2939 $this->assertEquals($discussions[3]->id, $neighbours['next']->id); 2940 2941 // CHECK 3. 2942 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[3], $forum); 2943 // D1 check. 2944 $this->assertEquals($discussions[1]->id, $neighbours['prev']->id); 2945 // D0 check. 2946 $this->assertEquals($discussions[0]->id, $neighbours['next']->id); 2947 2948 // CHECK 4. 2949 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[0], $forum); 2950 // D3 check. 2951 $this->assertEquals($discussions[3]->id, $neighbours['prev']->id); 2952 // Null check. 2953 $this->assertEmpty($neighbours['next']); 2954 } 2955 2956 /** 2957 * @dataProvider forum_get_unmailed_posts_provider 2958 */ 2959 public function test_forum_get_unmailed_posts($discussiondata, $enabletimedposts, $expectedcount, $expectedreplycount) { 2960 global $CFG, $DB; 2961 2962 $this->resetAfterTest(); 2963 2964 // Configure timed posts. 2965 $CFG->forum_enabletimedposts = $enabletimedposts; 2966 2967 $course = $this->getDataGenerator()->create_course(); 2968 $forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]); 2969 $user = $this->getDataGenerator()->create_user(); 2970 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum'); 2971 2972 // Keep track of the start time of the test. Do not use time() after this point to prevent random failures. 2973 $time = time(); 2974 2975 $record = new stdClass(); 2976 $record->course = $course->id; 2977 $record->userid = $user->id; 2978 $record->forum = $forum->id; 2979 if (isset($discussiondata['timecreated'])) { 2980 $record->timemodified = $time + $discussiondata['timecreated']; 2981 } 2982 if (isset($discussiondata['timestart'])) { 2983 $record->timestart = $time + $discussiondata['timestart']; 2984 } 2985 if (isset($discussiondata['timeend'])) { 2986 $record->timeend = $time + $discussiondata['timeend']; 2987 } 2988 if (isset($discussiondata['mailed'])) { 2989 $record->mailed = $discussiondata['mailed']; 2990 } 2991 2992 $discussion = $forumgen->create_discussion($record); 2993 2994 // Fetch the unmailed posts. 2995 $timenow = $time; 2996 $endtime = $timenow - $CFG->maxeditingtime; 2997 $starttime = $endtime - 2 * DAYSECS; 2998 2999 $unmailed = forum_get_unmailed_posts($starttime, $endtime, $timenow); 3000 $this->assertCount($expectedcount, $unmailed); 3001 3002 // Add a reply just outside the maxeditingtime. 3003 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 3004 $reply = new stdClass(); 3005 $reply->userid = $user->id; 3006 $reply->discussion = $discussion->id; 3007 $reply->parent = $replyto->id; 3008 $reply->created = max($replyto->created, $endtime - 1); 3009 $forumgen->create_post($reply); 3010 3011 $unmailed = forum_get_unmailed_posts($starttime, $endtime, $timenow); 3012 $this->assertCount($expectedreplycount, $unmailed); 3013 } 3014 3015 /** 3016 * Test for forum_is_author_hidden. 3017 */ 3018 public function test_forum_is_author_hidden() { 3019 // First post, different forum type. 3020 $post = (object) ['parent' => 0]; 3021 $forum = (object) ['type' => 'standard']; 3022 $this->assertFalse(forum_is_author_hidden($post, $forum)); 3023 3024 // Child post, different forum type. 3025 $post->parent = 1; 3026 $this->assertFalse(forum_is_author_hidden($post, $forum)); 3027 3028 // First post, single simple discussion forum type. 3029 $post->parent = 0; 3030 $forum->type = 'single'; 3031 $this->assertTrue(forum_is_author_hidden($post, $forum)); 3032 3033 // Child post, single simple discussion forum type. 3034 $post->parent = 1; 3035 $this->assertFalse(forum_is_author_hidden($post, $forum)); 3036 3037 // Incorrect parameters: $post. 3038 $this->expectException('coding_exception'); 3039 $this->expectExceptionMessage('$post->parent must be set.'); 3040 unset($post->parent); 3041 forum_is_author_hidden($post, $forum); 3042 3043 // Incorrect parameters: $forum. 3044 $this->expectException('coding_exception'); 3045 $this->expectExceptionMessage('$forum->type must be set.'); 3046 unset($forum->type); 3047 forum_is_author_hidden($post, $forum); 3048 } 3049 3050 public function forum_get_unmailed_posts_provider() { 3051 return [ 3052 'Untimed discussion; Single post; maxeditingtime not expired' => [ 3053 'discussion' => [ 3054 ], 3055 'timedposts' => false, 3056 'postcount' => 0, 3057 'replycount' => 0, 3058 ], 3059 'Untimed discussion; Single post; maxeditingtime expired' => [ 3060 'discussion' => [ 3061 'timecreated' => - DAYSECS, 3062 ], 3063 'timedposts' => false, 3064 'postcount' => 1, 3065 'replycount' => 2, 3066 ], 3067 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime not expired' => [ 3068 'discussion' => [ 3069 'timecreated' => - WEEKSECS, 3070 'timestart' => 0, 3071 ], 3072 'timedposts' => true, 3073 'postcount' => 0, 3074 'replycount' => 0, 3075 ], 3076 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired' => [ 3077 'discussion' => [ 3078 'timecreated' => - WEEKSECS, 3079 'timestart' => - DAYSECS, 3080 ], 3081 'timedposts' => true, 3082 'postcount' => 1, 3083 'replycount' => 2, 3084 ], 3085 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend not reached' => [ 3086 'discussion' => [ 3087 'timecreated' => - WEEKSECS, 3088 'timestart' => - DAYSECS, 3089 'timeend' => + DAYSECS 3090 ], 3091 'timedposts' => true, 3092 'postcount' => 1, 3093 'replycount' => 2, 3094 ], 3095 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend passed' => [ 3096 'discussion' => [ 3097 'timecreated' => - WEEKSECS, 3098 'timestart' => - DAYSECS, 3099 'timeend' => - HOURSECS, 3100 ], 3101 'timedposts' => true, 3102 'postcount' => 0, 3103 'replycount' => 0, 3104 ], 3105 'Timed discussion; Single post; Posted 1 week ago; timeend not reached' => [ 3106 'discussion' => [ 3107 'timecreated' => - WEEKSECS, 3108 'timeend' => + DAYSECS 3109 ], 3110 'timedposts' => true, 3111 'postcount' => 0, 3112 'replycount' => 1, 3113 ], 3114 'Timed discussion; Single post; Posted 1 week ago; timeend passed' => [ 3115 'discussion' => [ 3116 'timecreated' => - WEEKSECS, 3117 'timeend' => - DAYSECS, 3118 ], 3119 'timedposts' => true, 3120 'postcount' => 0, 3121 'replycount' => 0, 3122 ], 3123 3124 'Previously mailed; Untimed discussion; Single post; maxeditingtime not expired' => [ 3125 'discussion' => [ 3126 'mailed' => 1, 3127 ], 3128 'timedposts' => false, 3129 'postcount' => 0, 3130 'replycount' => 0, 3131 ], 3132 3133 'Previously mailed; Untimed discussion; Single post; maxeditingtime expired' => [ 3134 'discussion' => [ 3135 'timecreated' => - DAYSECS, 3136 'mailed' => 1, 3137 ], 3138 'timedposts' => false, 3139 'postcount' => 0, 3140 'replycount' => 1, 3141 ], 3142 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime not expired' => [ 3143 'discussion' => [ 3144 'timecreated' => - WEEKSECS, 3145 'timestart' => 0, 3146 'mailed' => 1, 3147 ], 3148 'timedposts' => true, 3149 'postcount' => 0, 3150 'replycount' => 0, 3151 ], 3152 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired' => [ 3153 'discussion' => [ 3154 'timecreated' => - WEEKSECS, 3155 'timestart' => - DAYSECS, 3156 'mailed' => 1, 3157 ], 3158 'timedposts' => true, 3159 'postcount' => 0, 3160 'replycount' => 1, 3161 ], 3162 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend not reached' => [ 3163 'discussion' => [ 3164 'timecreated' => - WEEKSECS, 3165 'timestart' => - DAYSECS, 3166 'timeend' => + DAYSECS, 3167 'mailed' => 1, 3168 ], 3169 'timedposts' => true, 3170 'postcount' => 0, 3171 'replycount' => 1, 3172 ], 3173 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend passed' => [ 3174 'discussion' => [ 3175 'timecreated' => - WEEKSECS, 3176 'timestart' => - DAYSECS, 3177 'timeend' => - HOURSECS, 3178 'mailed' => 1, 3179 ], 3180 'timedposts' => true, 3181 'postcount' => 0, 3182 'replycount' => 0, 3183 ], 3184 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timeend not reached' => [ 3185 'discussion' => [ 3186 'timecreated' => - WEEKSECS, 3187 'timeend' => + DAYSECS, 3188 'mailed' => 1, 3189 ], 3190 'timedposts' => true, 3191 'postcount' => 0, 3192 'replycount' => 1, 3193 ], 3194 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timeend passed' => [ 3195 'discussion' => [ 3196 'timecreated' => - WEEKSECS, 3197 'timeend' => - DAYSECS, 3198 'mailed' => 1, 3199 ], 3200 'timedposts' => true, 3201 'postcount' => 0, 3202 'replycount' => 0, 3203 ], 3204 ]; 3205 } 3206 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |