Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace mod_forum; 18 19 use mod_forum\local\container; 20 use mod_forum\local\entities\forum; 21 use mod_forum\local\managers\capability as capability_manager; 22 use mod_forum_tests_generator_trait; 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 global $CFG; 27 require_once (__DIR__ . '/generator_trait.php'); 28 29 /** 30 * The capability manager tests. 31 * 32 * @package mod_forum 33 * @copyright 2019 Ryan Wyllie <ryan@moodle.com> 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 * @coversDefaultClass \mod_forum\local\managers\capability 36 */ 37 class managers_capability_test extends \advanced_testcase { 38 // Make use of the test generator trait. 39 use mod_forum_tests_generator_trait; 40 41 /** @var stdClass */ 42 private $user; 43 44 /** @var \mod_forum\local\factories\entity */ 45 private $entityfactory; 46 47 /** @var \mod_forum\local\factories\manager */ 48 private $managerfactory; 49 50 /** @var stdClass */ 51 private $course; 52 53 /** @var stdClass */ 54 private $forumrecord; 55 56 /** @var stdClass */ 57 private $coursemodule; 58 59 /** @var context */ 60 private $context; 61 62 /** @var int */ 63 private $roleid; 64 65 /** @var \mod_forum\local\entities\discussion */ 66 private $discussion; 67 68 /** @var stdClass */ 69 private $discussionrecord; 70 71 /** @var \mod_forum\local\entities\post */ 72 private $post; 73 74 /** @var stdClass */ 75 private $postrecord; 76 77 /** 78 * Setup function before each test. 79 */ 80 public function setUp(): void { 81 global $DB; 82 83 // We must clear the subscription caches. This has to be done both before each test, and after in case of other 84 // tests using these functions. 85 \mod_forum\subscriptions::reset_forum_cache(); 86 87 $datagenerator = $this->getDataGenerator(); 88 $this->user = $datagenerator->create_user(); 89 $this->managerfactory = container::get_manager_factory(); 90 $this->entityfactory = container::get_entity_factory(); 91 $this->course = $datagenerator->create_course(); 92 $this->forumrecord = $datagenerator->create_module('forum', ['course' => $this->course->id]); 93 $this->coursemodule = get_coursemodule_from_instance('forum', $this->forumrecord->id); 94 $this->context = \context_module::instance($this->coursemodule->id); 95 $this->roleid = $DB->get_field('role', 'id', ['shortname' => 'teacher'], MUST_EXIST); 96 97 $datagenerator->enrol_user($this->user->id, $this->course->id, 'teacher'); 98 [$discussion, $post] = $this->helper_post_to_forum($this->forumrecord, $this->user, ['timemodified' => time() - 100]); 99 $this->discussion = $this->entityfactory->get_discussion_from_stdClass($discussion); 100 $this->discussionrecord = $discussion; 101 $this->post = $this->entityfactory->get_post_from_stdClass( 102 (object) array_merge((array) $post, ['timecreated' => time() - 100]) 103 ); 104 $this->postrecord = $post; 105 106 $this->setUser($this->user); 107 } 108 109 /** 110 * Tear down function after each test. 111 */ 112 public function tearDown(): void { 113 // We must clear the subscription caches. This has to be done both before each test, and after in case of other 114 // tests using these functions. 115 \mod_forum\subscriptions::reset_forum_cache(); 116 } 117 118 /** 119 * Helper function to create a forum entity. 120 * 121 * @param array $forumproperties List of properties to override the prebuilt forum 122 * @return forum 123 */ 124 private function create_forum(array $forumproperties = []) { 125 $forumrecord = (object) array_merge((array) $this->forumrecord, $forumproperties); 126 return $this->entityfactory->get_forum_from_stdClass( 127 $forumrecord, 128 $this->context, 129 $this->coursemodule, 130 $this->course 131 ); 132 } 133 134 /** 135 * Helper function to assign a capability to the prebuilt role (teacher). 136 * 137 * @param string $capability Name of the capability 138 * @param context|null $context The context to assign the capability in 139 */ 140 private function give_capability($capability, $context = null) { 141 $context = $context ?? $this->context; 142 assign_capability($capability, CAP_ALLOW, $this->roleid, $context->id, true); 143 } 144 145 /** 146 * Helper function to prevent a capability to the prebuilt role (teacher). 147 * 148 * @param string $capability Name of the capability 149 * @param context|null $context The context to assign the capability in 150 */ 151 private function prevent_capability($capability, $context = null) { 152 $context = $context ?? $this->context; 153 assign_capability($capability, CAP_PREVENT, $this->roleid, $context->id, true); 154 } 155 156 /** 157 * Test can_subscribe_to_forum. 158 * 159 * @covers ::can_subscribe_to_forum 160 */ 161 public function test_can_subscribe_to_forum() { 162 $this->resetAfterTest(); 163 164 $forum = $this->create_forum(); 165 $guestuser = $this->getDataGenerator()->create_user(); 166 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 167 168 $this->assertFalse($capabilitymanager->can_subscribe_to_forum($guestuser)); 169 $this->assertTrue($capabilitymanager->can_subscribe_to_forum($this->user)); 170 } 171 172 /** 173 * Test can_create_discussions. 174 * 175 * @covers ::can_create_discussions 176 */ 177 public function test_can_create_discussions() { 178 $this->resetAfterTest(); 179 180 $forum = $this->create_forum(); 181 $guestuser = $this->getDataGenerator()->create_user(); 182 $user = $this->user; 183 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 184 185 $this->assertFalse($capabilitymanager->can_create_discussions($guestuser)); 186 187 $this->prevent_capability('mod/forum:startdiscussion'); 188 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 189 190 $this->give_capability('mod/forum:startdiscussion'); 191 $this->assertTrue($capabilitymanager->can_create_discussions($user)); 192 193 $forum = $this->create_forum(['type' => 'news']); 194 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 195 196 $this->prevent_capability('mod/forum:addnews'); 197 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 198 199 $this->give_capability('mod/forum:addnews'); 200 $this->assertTrue($capabilitymanager->can_create_discussions($user)); 201 202 $forum = $this->create_forum(['type' => 'qanda']); 203 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 204 205 $this->prevent_capability('mod/forum:addquestion'); 206 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 207 208 $this->give_capability('mod/forum:addquestion'); 209 $this->assertTrue($capabilitymanager->can_create_discussions($user)); 210 211 // Test a forum in group mode. 212 $forumrecord = $this->getDataGenerator()->create_module( 213 'forum', 214 ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS] 215 ); 216 $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id); 217 $context = \context_module::instance($coursemodule->id); 218 $forum = $this->entityfactory->get_forum_from_stdClass( 219 $forumrecord, 220 $context, 221 $coursemodule, 222 $this->course 223 ); 224 225 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 226 227 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 228 229 $this->give_capability('moodle/site:accessallgroups', $context); 230 $this->assertTrue($capabilitymanager->can_create_discussions($user)); 231 232 $this->prevent_capability('moodle/site:accessallgroups', $context); 233 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 234 235 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 236 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 237 238 $this->assertTrue($capabilitymanager->can_create_discussions($user, $group->id)); 239 240 // Test if cut off date is reached. 241 $now = time(); 242 $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 5, 'blockperiod' => 86400]); 243 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 244 $this->prevent_capability('mod/forum:postwithoutthrottling'); 245 $this->assertTrue($capabilitymanager->can_create_discussions($user)); 246 247 $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 1, 'blockperiod' => 86400]); 248 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 249 $this->prevent_capability('mod/forum:postwithoutthrottling'); 250 $this->assertFalse($capabilitymanager->can_create_discussions($user)); 251 } 252 253 /** 254 * Test can_access_all_groups. 255 * 256 * @covers ::can_access_all_groups 257 */ 258 public function test_can_access_all_groups() { 259 $this->resetAfterTest(); 260 261 $forum = $this->create_forum(); 262 $user = $this->user; 263 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 264 265 $this->prevent_capability('moodle/site:accessallgroups'); 266 $this->assertFalse($capabilitymanager->can_access_all_groups($user)); 267 268 $this->give_capability('moodle/site:accessallgroups'); 269 $this->assertTrue($capabilitymanager->can_access_all_groups($user)); 270 } 271 272 /** 273 * Test can_access_group. 274 * 275 * @covers ::can_access_group 276 */ 277 public function test_can_access_group() { 278 $this->resetAfterTest(); 279 280 $forum = $this->create_forum(); 281 $user = $this->user; 282 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 283 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 284 285 $this->prevent_capability('moodle/site:accessallgroups'); 286 $this->assertFalse($capabilitymanager->can_access_group($user, $group->id)); 287 288 $this->give_capability('moodle/site:accessallgroups'); 289 $this->assertTrue($capabilitymanager->can_access_group($user, $group->id)); 290 291 $this->prevent_capability('moodle/site:accessallgroups'); 292 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 293 $this->assertTrue($capabilitymanager->can_access_group($user, $group->id)); 294 } 295 296 /** 297 * Test can_view_discussions. 298 * 299 * @covers ::can_view_discussions 300 */ 301 public function test_can_view_discussions() { 302 $this->resetAfterTest(); 303 304 $forum = $this->create_forum(); 305 $user = $this->user; 306 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 307 308 $this->prevent_capability('mod/forum:viewdiscussion'); 309 $this->assertFalse($capabilitymanager->can_view_discussions($user)); 310 311 $this->give_capability('mod/forum:viewdiscussion'); 312 $this->assertTrue($capabilitymanager->can_view_discussions($user)); 313 } 314 315 /** 316 * Test can_move_discussions. 317 * 318 * @covers ::can_move_discussions 319 */ 320 public function test_can_move_discussions() { 321 $this->resetAfterTest(); 322 323 $forum = $this->create_forum(); 324 $user = $this->user; 325 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 326 327 $this->prevent_capability('mod/forum:movediscussions'); 328 $this->assertFalse($capabilitymanager->can_move_discussions($user)); 329 330 $this->give_capability('mod/forum:movediscussions'); 331 $this->assertTrue($capabilitymanager->can_move_discussions($user)); 332 333 $forum = $this->create_forum(['type' => 'single']); 334 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 335 336 $this->assertFalse($capabilitymanager->can_move_discussions($user)); 337 } 338 339 /** 340 * Test can_pin_discussions. 341 * 342 * @covers ::can_pin_discussions 343 */ 344 public function test_can_pin_discussions() { 345 $this->resetAfterTest(); 346 347 $forum = $this->create_forum(); 348 $user = $this->user; 349 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 350 351 $this->prevent_capability('mod/forum:pindiscussions'); 352 $this->assertFalse($capabilitymanager->can_pin_discussions($user)); 353 354 $this->give_capability('mod/forum:pindiscussions'); 355 $this->assertTrue($capabilitymanager->can_pin_discussions($user)); 356 } 357 358 /** 359 * Test can_split_discussions. 360 * 361 * @covers ::can_split_discussions 362 */ 363 public function test_can_split_discussions() { 364 $this->resetAfterTest(); 365 366 $forum = $this->create_forum(); 367 $user = $this->user; 368 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 369 370 $this->prevent_capability('mod/forum:splitdiscussions'); 371 $this->assertFalse($capabilitymanager->can_split_discussions($user)); 372 373 $this->give_capability('mod/forum:splitdiscussions'); 374 $this->assertTrue($capabilitymanager->can_split_discussions($user)); 375 376 $forum = $this->create_forum(['type' => 'single']); 377 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 378 379 $this->assertFalse($capabilitymanager->can_split_discussions($user)); 380 } 381 382 /** 383 * Test can_export_discussions. 384 * 385 * @covers ::can_export_discussions 386 */ 387 public function test_can_export_discussions() { 388 global $CFG; 389 $this->resetAfterTest(); 390 391 $CFG->enableportfolios = true; 392 $forum = $this->create_forum(); 393 $user = $this->user; 394 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 395 396 $this->prevent_capability('mod/forum:exportdiscussion'); 397 $this->assertFalse($capabilitymanager->can_export_discussions($user)); 398 399 $this->give_capability('mod/forum:exportdiscussion'); 400 $this->assertTrue($capabilitymanager->can_export_discussions($user)); 401 402 $CFG->enableportfolios = false; 403 404 $this->assertFalse($capabilitymanager->can_export_discussions($user)); 405 } 406 407 /** 408 * Test can_manually_control_post_read_status. 409 * 410 * @covers ::can_manually_control_post_read_status 411 */ 412 public function test_can_manually_control_post_read_status() { 413 global $CFG, $DB; 414 $this->resetAfterTest(); 415 416 $CFG->forum_usermarksread = true; 417 $forum = $this->create_forum(); 418 $user = $this->user; 419 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 420 $cache = \cache::make('mod_forum', 'forum_is_tracked'); 421 422 $user->trackforums = true; 423 $prefid = $DB->insert_record('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forum->get_id()]); 424 $this->assertFalse($capabilitymanager->can_manually_control_post_read_status($user)); 425 $cache->purge(); 426 427 $DB->delete_records('forum_track_prefs', ['id' => $prefid]); 428 $this->assertTrue($capabilitymanager->can_manually_control_post_read_status($user)); 429 $cache->purge(); 430 431 $CFG->forum_usermarksread = false; 432 433 $this->assertFalse($capabilitymanager->can_manually_control_post_read_status($user)); 434 } 435 436 /** 437 * Test must_post_before_viewing_discussion. 438 * 439 * @covers ::must_post_before_viewing_discussion 440 */ 441 public function test_must_post_before_viewing_discussion() { 442 $this->resetAfterTest(); 443 444 $forum = $this->create_forum(); 445 $user = $this->user; 446 $discussion = $this->discussion; 447 $newuser = $this->getDataGenerator()->create_user(); 448 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 449 $this->getDataGenerator()->enrol_user($newuser->id, $this->course->id, 'teacher'); 450 451 $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion)); 452 453 $forum = $this->create_forum(['type' => 'qanda']); 454 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 455 456 $this->prevent_capability('mod/forum:viewqandawithoutposting'); 457 $this->assertTrue($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion)); 458 459 $this->give_capability('mod/forum:viewqandawithoutposting'); 460 $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion)); 461 462 $this->prevent_capability('mod/forum:viewqandawithoutposting'); 463 // The pre-generated user has a pre-generated post in the disussion already. 464 $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($user, $discussion)); 465 } 466 467 /** 468 * Test can_subscribe_to_discussion. 469 * 470 * @covers ::can_subscribe_to_discussion 471 */ 472 public function test_can_subscribe_to_discussion() { 473 $this->resetAfterTest(); 474 475 $forum = $this->create_forum(); 476 $discussion = $this->discussion; 477 $guestuser = $this->getDataGenerator()->create_user(); 478 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 479 480 $this->assertFalse($capabilitymanager->can_subscribe_to_discussion($guestuser, $discussion)); 481 $this->assertTrue($capabilitymanager->can_subscribe_to_discussion($this->user, $discussion)); 482 } 483 484 /** 485 * Test can_move_discussion. 486 * 487 * @covers ::can_move_discussion 488 */ 489 public function test_can_move_discussion() { 490 $this->resetAfterTest(); 491 492 $forum = $this->create_forum(); 493 $discussion = $this->discussion; 494 $user = $this->user; 495 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 496 497 $this->prevent_capability('mod/forum:movediscussions'); 498 $this->assertFalse($capabilitymanager->can_move_discussion($user, $discussion)); 499 500 $this->give_capability('mod/forum:movediscussions'); 501 $this->assertTrue($capabilitymanager->can_move_discussion($user, $discussion)); 502 503 $forum = $this->create_forum(['type' => 'single']); 504 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 505 506 $this->assertFalse($capabilitymanager->can_move_discussion($user, $discussion)); 507 } 508 509 /** 510 * Test can_pin_discussion. 511 * 512 * @covers ::can_pin_discussion 513 */ 514 public function test_can_pin_discussion() { 515 $this->resetAfterTest(); 516 517 $forum = $this->create_forum(); 518 $discussion = $this->discussion; 519 $user = $this->user; 520 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 521 522 $this->prevent_capability('mod/forum:pindiscussions'); 523 $this->assertFalse($capabilitymanager->can_pin_discussion($user, $discussion)); 524 525 $this->give_capability('mod/forum:pindiscussions'); 526 $this->assertTrue($capabilitymanager->can_pin_discussion($user, $discussion)); 527 } 528 529 /** 530 * Test can_post_in_discussion. 531 * 532 * @covers ::can_post_in_discussion 533 */ 534 public function test_can_post_in_discussion() { 535 $this->resetAfterTest(); 536 537 $discussion = $this->discussion; 538 $user = $this->user; 539 540 // Locked discussions. 541 $lockedforum = $this->create_forum(['lockdiscussionafter' => 1]); 542 $capabilitymanager = $this->managerfactory->get_capability_manager($lockedforum); 543 544 $this->give_capability('mod/forum:canoverridediscussionlock'); 545 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 546 547 $this->prevent_capability('mod/forum:canoverridediscussionlock'); 548 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 549 550 // News forum. 551 $newsforum = $this->create_forum(['type' => 'news']); 552 $capabilitymanager = $this->managerfactory->get_capability_manager($newsforum); 553 554 $this->give_capability('mod/forum:replynews'); 555 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 556 557 $this->prevent_capability('mod/forum:replynews'); 558 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 559 560 // General forum. 561 $forum = $this->create_forum(); 562 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 563 564 $this->give_capability('mod/forum:replypost'); 565 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 566 567 $this->prevent_capability('mod/forum:replypost'); 568 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 569 570 // Forum in separate group mode. 571 $forumrecord = $this->getDataGenerator()->create_module( 572 'forum', 573 ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS] 574 ); 575 $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id); 576 $context = \context_module::instance($coursemodule->id); 577 $forum = $this->entityfactory->get_forum_from_stdClass( 578 $forumrecord, 579 $context, 580 $coursemodule, 581 $this->course 582 ); 583 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 584 585 $this->give_capability('moodle/site:accessallgroups', $context); 586 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 587 588 $this->prevent_capability('moodle/site:accessallgroups', $context); 589 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 590 591 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 592 $discussion = $this->entityfactory->get_discussion_from_stdClass( 593 (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id]) 594 ); 595 596 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 597 598 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 599 600 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 601 602 // Forum in visible group mode. 603 $forumrecord = $this->getDataGenerator()->create_module( 604 'forum', 605 ['course' => $this->course->id, 'groupmode' => VISIBLEGROUPS] 606 ); 607 $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id); 608 $context = \context_module::instance($coursemodule->id); 609 $forum = $this->entityfactory->get_forum_from_stdClass( 610 $forumrecord, 611 $context, 612 $coursemodule, 613 $this->course 614 ); 615 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 616 617 $this->give_capability('moodle/site:accessallgroups', $context); 618 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 619 620 $this->prevent_capability('moodle/site:accessallgroups', $context); 621 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 622 623 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 624 $discussion = $this->entityfactory->get_discussion_from_stdClass( 625 (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id]) 626 ); 627 628 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 629 630 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 631 632 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 633 634 $now = time(); 635 $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 5, 'blockperiod' => 86400]); 636 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 637 $this->prevent_capability('mod/forum:postwithoutthrottling'); 638 $this->give_capability('mod/forum:replypost'); 639 $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion)); 640 641 $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 1, 'blockperiod' => 86400]); 642 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 643 $this->prevent_capability('mod/forum:postwithoutthrottling'); 644 $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion)); 645 } 646 647 /** 648 * Test can_edit_post. 649 * 650 * @covers ::can_edit_post 651 */ 652 public function test_can_edit_post() { 653 global $CFG; 654 655 $this->resetAfterTest(); 656 657 $forum = $this->create_forum(); 658 $discussion = $this->discussion; 659 // The generated post is created 100 seconds in the past. 660 $post = $this->post; 661 $user = $this->user; 662 $otheruser = $this->getDataGenerator()->create_user(); 663 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 664 665 $this->prevent_capability('mod/forum:editanypost'); 666 667 // 200 seconds to edit. 668 $CFG->maxeditingtime = 200; 669 $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post)); 670 671 // 10 seconds to edit. No longer in editing time. 672 $CFG->maxeditingtime = 10; 673 $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post)); 674 675 // Can edit outside of editing time with this capability. 676 $this->give_capability('mod/forum:editanypost'); 677 $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post)); 678 679 $CFG->maxeditingtime = 200; 680 $this->assertFalse($capabilitymanager->can_edit_post($otheruser, $discussion, $post)); 681 682 $this->prevent_capability('mod/forum:editanypost'); 683 684 // News forum. 685 $forum = $this->create_forum(['type' => 'news']); 686 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 687 // Discussion hasn't started yet. 688 $discussion = $this->entityfactory->get_discussion_from_stdClass( 689 (object) array_merge((array) $this->discussionrecord, ['timestart' => time() + 100]) 690 ); 691 692 $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post)); 693 694 // Back to a discussion that has started. 695 $discussion = $this->discussion; 696 // Post is a reply. 697 $post = $this->entityfactory->get_post_from_stdClass( 698 (object) array_merge((array) $this->postrecord, ['parent' => 5]) 699 ); 700 701 $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post)); 702 703 $post = $this->post; 704 // Discussion has started and post isn't a reply so we can edit it. 705 $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post)); 706 707 // Single forum. 708 $forum = $this->create_forum(['type' => 'single']); 709 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 710 711 // Create a new post that definitely isn't the first post of the discussion. 712 // Only the author, and a user with editanypost can edit it. 713 $post = $this->entityfactory->get_post_from_stdClass( 714 (object) array_merge((array) $this->postrecord, ['id' => $post->get_id() + 100]) 715 ); 716 $this->give_capability('mod/forum:editanypost'); 717 $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post)); 718 $this->assertFalse($capabilitymanager->can_edit_post($otheruser, $discussion, $post)); 719 720 $post = $this->post; 721 // Set the first post of the discussion to our post. 722 $discussion = $this->entityfactory->get_discussion_from_stdClass( 723 (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id()]) 724 ); 725 726 $this->prevent_capability('moodle/course:manageactivities'); 727 $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post)); 728 729 $this->give_capability('moodle/course:manageactivities'); 730 $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post)); 731 } 732 733 /** 734 * Test can_delete_post. 735 * 736 * @covers ::can_delete_post 737 */ 738 public function test_can_delete_post() { 739 global $CFG; 740 741 $this->resetAfterTest(); 742 743 // Single forum. 744 $forum = $this->create_forum(['type' => 'single']); 745 // The generated post is created 100 seconds in the past. 746 $post = $this->post; 747 $user = $this->user; 748 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 749 750 // Set the first post of the discussion to our post. 751 $discussion = $this->entityfactory->get_discussion_from_stdClass( 752 (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id()]) 753 ); 754 755 // Can't delete the first post of a single discussion forum. 756 $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post)); 757 758 // Set the first post of the discussion to something else. 759 $discussion = $this->entityfactory->get_discussion_from_stdClass( 760 (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id() - 1]) 761 ); 762 763 $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post)); 764 765 // Back to a general forum. 766 $forum = $this->create_forum(); 767 $this->prevent_capability('mod/forum:deleteanypost'); 768 $this->give_capability('mod/forum:deleteownpost'); 769 // 200 second editing time to make sure our post is still within it. 770 $CFG->maxeditingtime = 200; 771 772 // Make the post owned by someone else. 773 $post = $this->entityfactory->get_post_from_stdClass( 774 (object) array_merge((array) $this->postrecord, ['userid' => $user->id - 1]) 775 ); 776 777 // Can't delete someone else's post. 778 $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post)); 779 // Back to our post. 780 $post = $this->post; 781 782 // Not in editing time. 783 $CFG->maxeditingtime = 10; 784 $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post)); 785 786 $CFG->maxeditingtime = 200; 787 // Remove the capability to delete own post. 788 $this->prevent_capability('mod/forum:deleteownpost'); 789 $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post)); 790 791 $this->give_capability('mod/forum:deleteownpost'); 792 $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post)); 793 794 $this->give_capability('mod/forum:deleteanypost'); 795 $CFG->maxeditingtime = 10; 796 $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post)); 797 } 798 799 /** 800 * Test can_split_post. 801 * 802 * @covers ::can_split_post 803 */ 804 public function test_can_split_post() { 805 $this->resetAfterTest(); 806 807 $forum = $this->create_forum(); 808 $user = $this->user; 809 $discussion = $this->discussion; 810 $post = $this->post; 811 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 812 813 // Make the post a reply. 814 $post = $this->entityfactory->get_post_from_stdClass( 815 (object) array_merge((array) $this->postrecord, ['parent' => 5]) 816 ); 817 818 $this->prevent_capability('mod/forum:splitdiscussions'); 819 $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post)); 820 821 $this->give_capability('mod/forum:splitdiscussions'); 822 $this->assertTrue($capabilitymanager->can_split_post($user, $discussion, $post)); 823 824 // Make the post have no parent. 825 $post = $this->entityfactory->get_post_from_stdClass( 826 (object) array_merge((array) $this->postrecord, ['parent' => 0]) 827 ); 828 829 $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post)); 830 831 $forum = $this->create_forum(['type' => 'single']); 832 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 833 // Make the post a reply. 834 $post = $this->entityfactory->get_post_from_stdClass( 835 (object) array_merge((array) $this->postrecord, ['parent' => 5]) 836 ); 837 838 // Can't split a single discussion forum. 839 $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post)); 840 841 // Make the post a private reply. 842 $post = $this->entityfactory->get_post_from_stdClass( 843 (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id]) 844 ); 845 846 // Can't split at a private reply. 847 $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post)); 848 } 849 850 /** 851 * Test can_reply_to_post. 852 * 853 * @covers ::can_reply_to_post 854 */ 855 public function test_can_reply_to_post() { 856 $this->resetAfterTest(); 857 858 $discussion = $this->discussion; 859 $user = $this->user; 860 $post = $this->post; 861 862 // Locked discussions. 863 $lockedforum = $this->create_forum(['lockdiscussionafter' => 1]); 864 $capabilitymanager = $this->managerfactory->get_capability_manager($lockedforum); 865 866 $this->give_capability('mod/forum:canoverridediscussionlock'); 867 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 868 869 $this->prevent_capability('mod/forum:canoverridediscussionlock'); 870 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 871 872 // News forum. 873 $newsforum = $this->create_forum(['type' => 'news']); 874 $capabilitymanager = $this->managerfactory->get_capability_manager($newsforum); 875 876 $this->give_capability('mod/forum:replynews'); 877 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 878 879 $this->prevent_capability('mod/forum:replynews'); 880 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 881 882 // General forum. 883 $forum = $this->create_forum(); 884 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 885 886 $this->give_capability('mod/forum:replypost'); 887 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 888 889 $this->prevent_capability('mod/forum:replypost'); 890 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 891 892 // Forum in separate group mode. 893 $forumrecord = $this->getDataGenerator()->create_module( 894 'forum', 895 ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS] 896 ); 897 $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id); 898 $context = \context_module::instance($coursemodule->id); 899 $forum = $this->entityfactory->get_forum_from_stdClass( 900 $forumrecord, 901 $context, 902 $coursemodule, 903 $this->course 904 ); 905 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 906 907 $this->give_capability('moodle/site:accessallgroups', $context); 908 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 909 910 $this->prevent_capability('moodle/site:accessallgroups', $context); 911 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 912 913 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 914 $discussion = $this->entityfactory->get_discussion_from_stdClass( 915 (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id]) 916 ); 917 918 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 919 920 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 921 922 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 923 924 // Forum in visible group mode. 925 $forumrecord = $this->getDataGenerator()->create_module( 926 'forum', 927 ['course' => $this->course->id, 'groupmode' => VISIBLEGROUPS] 928 ); 929 $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id); 930 $context = \context_module::instance($coursemodule->id); 931 $forum = $this->entityfactory->get_forum_from_stdClass( 932 $forumrecord, 933 $context, 934 $coursemodule, 935 $this->course 936 ); 937 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 938 939 $this->give_capability('moodle/site:accessallgroups', $context); 940 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 941 942 $this->prevent_capability('moodle/site:accessallgroups', $context); 943 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 944 945 $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]); 946 $discussion = $this->entityfactory->get_discussion_from_stdClass( 947 (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id]) 948 ); 949 950 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 951 952 $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]); 953 954 $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 955 956 // Make the post a private reply. 957 $post = $this->entityfactory->get_post_from_stdClass( 958 (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id]) 959 ); 960 961 // Can't reply to a a private reply. 962 $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post)); 963 } 964 965 /** 966 * Test for \mod_forum\local\managers\capability::can_reply_to_post() involving Q & A forums. 967 */ 968 public function test_can_reply_to_post_in_qanda_forum() { 969 global $CFG; 970 971 $this->resetAfterTest(); 972 973 // Set max editing time to 10 seconds. 974 $CFG->maxeditingtime = 10; 975 976 $qandaforum = $this->create_forum(['type' => 'qanda']); 977 $datagenerator = $this->getDataGenerator(); 978 $capabilitymanager = $this->managerfactory->get_capability_manager($qandaforum); 979 980 // Student 1. 981 $student1 = $datagenerator->create_user(['firstname' => 'S1']); 982 $datagenerator->enrol_user($student1->id, $this->course->id, 'student'); 983 // Confirm Student 1 can reply to the question. 984 $this->assertTrue($capabilitymanager->can_reply_to_post($student1, $this->discussion, $this->post)); 985 986 // Student 2. 987 $student2 = $datagenerator->create_user(['firstname' => 'S2']); 988 $datagenerator->enrol_user($student2->id, $this->course->id, 'student'); 989 // Confirm Student 2 can reply to the question. 990 $this->assertTrue($capabilitymanager->can_reply_to_post($student2, $this->discussion, $this->post)); 991 992 // Reply to the question as student 1. 993 $now = time(); 994 $options = ['parent' => $this->post->get_id(), 'created' => $now - 100]; 995 $student1post = $this->helper_post_to_discussion($this->forumrecord, $this->discussionrecord, $student1, $options); 996 $student1postentity = $this->entityfactory->get_post_from_stdClass($student1post); 997 998 // Confirm Student 2 cannot reply student 1's answer yet. 999 $this->assertFalse($capabilitymanager->can_reply_to_post($student2, $this->discussion, $student1postentity)); 1000 1001 // Reply to the question as student 2. 1002 $this->helper_post_to_discussion($this->forumrecord, $this->discussionrecord, $student2, $options); 1003 1004 // Reinitialise capability manager first to ensure we don't return cached values. 1005 $capabilitymanager = $this->managerfactory->get_capability_manager($qandaforum); 1006 1007 // Confirm Student 2 can now reply to student 1's answer. 1008 $this->assertTrue($capabilitymanager->can_reply_to_post($student2, $this->discussion, $student1postentity)); 1009 } 1010 1011 /** 1012 * Ensure that can_reply_privately_to_post works as expected. 1013 * 1014 * @covers ::can_reply_privately_to_post 1015 */ 1016 public function test_can_reply_privately_to_post() { 1017 $this->resetAfterTest(); 1018 1019 $forum = $this->create_forum(); 1020 $discussion = $this->discussion; 1021 $user = $this->user; 1022 $post = $this->post; 1023 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1024 1025 // Without the capability, and with a standard post, it is not possible to reply privately. 1026 $this->prevent_capability('mod/forum:postprivatereply'); 1027 $this->assertFalse($capabilitymanager->can_reply_privately_to_post($this->user, $post)); 1028 1029 // With the capability, and a standard post, it is possible to reply privately. 1030 $this->give_capability('mod/forum:postprivatereply'); 1031 $this->assertTrue($capabilitymanager->can_reply_privately_to_post($this->user, $post)); 1032 1033 // Make the post a private reply. 1034 $post = $this->entityfactory->get_post_from_stdClass( 1035 (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id]) 1036 ); 1037 1038 // Can't ever reply to a a private reply. 1039 $this->assertFalse($capabilitymanager->can_reply_privately_to_post($user, $post)); 1040 } 1041 1042 /** 1043 * Ensure that can_view_post works as expected. 1044 * 1045 * @covers ::can_view_post 1046 */ 1047 public function test_can_view_post() { 1048 $this->resetAfterTest(); 1049 1050 $forum = $this->create_forum(); 1051 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1052 1053 $user = $this->user; 1054 $otheruser = $this->getDataGenerator()->create_user(); 1055 1056 $discussion = $this->discussion; 1057 $post = $this->post; 1058 1059 $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $otheruser->id]; 1060 $privatepost = $this->entityfactory->get_post_from_stdClass( 1061 (object) array_merge((array) $this->postrecord, $postproperties) 1062 ); 1063 1064 $this->prevent_capability('mod/forum:readprivatereplies'); 1065 $this->assertFalse($capabilitymanager->can_view_post($user, $discussion, $privatepost)); 1066 } 1067 1068 /** 1069 * Ensure that can_view_post_shell considers private replies correctly. 1070 * 1071 * @covers ::can_view_post_shell 1072 */ 1073 public function test_can_view_post_shell() { 1074 $this->resetAfterTest(); 1075 1076 $forum = $this->create_forum(); 1077 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1078 1079 $user = $this->user; 1080 $otheruser = $this->getDataGenerator()->create_user(); 1081 1082 $discussion = $this->discussion; 1083 $post = $this->post; 1084 1085 $postproperties = ['parent' => $post->get_id(), 'userid' => $user->id, 'privatereplyto' => $user->id]; 1086 $privatepostfrommetome = $this->entityfactory->get_post_from_stdClass( 1087 (object) array_merge((array) $this->postrecord, $postproperties) 1088 ); 1089 1090 $postproperties = ['parent' => $post->get_id(), 'userid' => $user->id, 'privatereplyto' => $otheruser->id]; 1091 $privatepostfrommetoother = $this->entityfactory->get_post_from_stdClass( 1092 (object) array_merge((array) $this->postrecord, $postproperties) 1093 ); 1094 1095 $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $user->id]; 1096 $privatepostfromothertome = $this->entityfactory->get_post_from_stdClass( 1097 (object) array_merge((array) $this->postrecord, $postproperties) 1098 ); 1099 1100 $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $otheruser->id]; 1101 $privatepostfromothertoother = $this->entityfactory->get_post_from_stdClass( 1102 (object) array_merge((array) $this->postrecord, $postproperties) 1103 ); 1104 1105 // Can always view public replies, and private replies by me or to me. 1106 $this->prevent_capability('mod/forum:readprivatereplies'); 1107 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $post)); 1108 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetome)); 1109 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetoother)); 1110 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertome)); 1111 $this->assertFalse($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertoother)); 1112 1113 $this->give_capability('mod/forum:readprivatereplies'); 1114 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $post)); 1115 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetome)); 1116 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetoother)); 1117 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertome)); 1118 $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertoother)); 1119 } 1120 1121 /** 1122 * Test can_export_post. 1123 * 1124 * @covers ::can_export_post 1125 */ 1126 public function test_can_export_post() { 1127 global $CFG; 1128 $this->resetAfterTest(); 1129 1130 $forum = $this->create_forum(); 1131 $post = $this->post; 1132 $user = $this->user; 1133 $otheruser = $this->getDataGenerator()->create_user(); 1134 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1135 1136 $this->getDataGenerator()->enrol_user($otheruser->id, $this->course->id, 'teacher'); 1137 1138 $CFG->enableportfolios = true; 1139 $this->give_capability('mod/forum:exportpost'); 1140 1141 $this->assertTrue($capabilitymanager->can_export_post($otheruser, $post)); 1142 1143 $CFG->enableportfolios = false; 1144 $this->assertFalse($capabilitymanager->can_export_post($otheruser, $post)); 1145 1146 $CFG->enableportfolios = true; 1147 $this->prevent_capability('mod/forum:exportpost'); 1148 // Can't export another user's post without the exportpost capavility. 1149 $this->assertFalse($capabilitymanager->can_export_post($otheruser, $post)); 1150 1151 $this->give_capability('mod/forum:exportownpost'); 1152 // Can export own post with the exportownpost capability. 1153 $this->assertTrue($capabilitymanager->can_export_post($user, $post)); 1154 1155 $this->prevent_capability('mod/forum:exportownpost'); 1156 $this->assertFalse($capabilitymanager->can_export_post($user, $post)); 1157 } 1158 1159 /** 1160 * Test can_view_participants. 1161 * 1162 * @covers ::can_view_participants 1163 */ 1164 public function test_can_view_participants() { 1165 $this->resetAfterTest(); 1166 1167 $discussion = $this->discussion; 1168 $user = $this->user; 1169 $otheruser = $this->getDataGenerator()->create_user(); 1170 1171 $this->getDataGenerator()->enrol_user($otheruser->id, $this->course->id, 'teacher'); 1172 1173 $this->prevent_capability('moodle/course:viewparticipants'); 1174 $this->prevent_capability('moodle/course:enrolreview'); 1175 $this->prevent_capability('mod/forum:viewqandawithoutposting'); 1176 1177 $forum = $this->create_forum(); 1178 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1179 1180 $this->assertFalse($capabilitymanager->can_view_participants($otheruser, $discussion)); 1181 1182 $this->give_capability('moodle/course:viewparticipants'); 1183 $this->assertTrue($capabilitymanager->can_view_participants($otheruser, $discussion)); 1184 1185 $this->prevent_capability('moodle/course:viewparticipants'); 1186 $this->give_capability('moodle/course:enrolreview'); 1187 $this->assertTrue($capabilitymanager->can_view_participants($otheruser, $discussion)); 1188 1189 $forum = $this->create_forum(['type' => 'qanda']); 1190 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1191 1192 // Q and A forum requires the user to post before they can view it. 1193 $this->prevent_capability('mod/forum:viewqandawithoutposting'); 1194 $this->assertFalse($capabilitymanager->can_view_participants($otheruser, $discussion)); 1195 1196 // This user has posted. 1197 $this->assertTrue($capabilitymanager->can_view_participants($user, $discussion)); 1198 } 1199 1200 /** 1201 * Test can_view_hidden_posts. 1202 * 1203 * @covers ::can_view_hidden_posts 1204 */ 1205 public function test_can_view_hidden_posts() { 1206 $this->resetAfterTest(); 1207 1208 $forum = $this->create_forum(); 1209 $user = $this->user; 1210 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1211 1212 $this->prevent_capability('mod/forum:viewhiddentimedposts'); 1213 $this->assertFalse($capabilitymanager->can_view_hidden_posts($user)); 1214 1215 $this->give_capability('mod/forum:viewhiddentimedposts'); 1216 $this->assertTrue($capabilitymanager->can_view_hidden_posts($user)); 1217 } 1218 1219 /** 1220 * Test can_manage_forum. 1221 * 1222 * @covers ::can_manage_forum 1223 */ 1224 public function test_can_manage_forum() { 1225 $this->resetAfterTest(); 1226 1227 $forum = $this->create_forum(); 1228 $user = $this->user; 1229 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1230 1231 $this->prevent_capability('moodle/course:manageactivities'); 1232 $this->assertFalse($capabilitymanager->can_manage_forum($user)); 1233 1234 $this->give_capability('moodle/course:manageactivities'); 1235 $this->assertTrue($capabilitymanager->can_manage_forum($user)); 1236 } 1237 1238 /** 1239 * Test can_manage_tags. 1240 * 1241 * @covers ::can_manage_tags 1242 */ 1243 public function test_can_manage_tags() { 1244 global $DB; 1245 $this->resetAfterTest(); 1246 1247 $forum = $this->create_forum(); 1248 $user = $this->user; 1249 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1250 $context = \context_system::instance(); 1251 $roleid = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST); 1252 1253 assign_capability('moodle/tag:manage', CAP_PREVENT, $roleid, $context->id, true); 1254 $this->assertFalse($capabilitymanager->can_manage_tags($user)); 1255 1256 assign_capability('moodle/tag:manage', CAP_ALLOW, $roleid, $context->id, true); 1257 $this->assertTrue($capabilitymanager->can_manage_tags($user)); 1258 } 1259 1260 /** 1261 * Ensure that the can_view_any_private_reply works as expected. 1262 * 1263 * @covers ::can_view_any_private_reply 1264 */ 1265 public function test_can_view_any_private_reply() { 1266 $this->resetAfterTest(); 1267 1268 $forum = $this->create_forum(); 1269 $capabilitymanager = $this->managerfactory->get_capability_manager($forum); 1270 1271 $this->give_capability('mod/forum:readprivatereplies'); 1272 $this->assertTrue($capabilitymanager->can_view_any_private_reply($this->user)); 1273 $this->prevent_capability('mod/forum:readprivatereplies'); 1274 $this->assertFalse($capabilitymanager->can_view_any_private_reply($this->user)); 1275 } 1276 1277 1278 /** 1279 * Test delete a post with ratings. 1280 */ 1281 public function test_validate_delete_post_with_ratings() { 1282 global $DB; 1283 $this->resetAfterTest(true); 1284 1285 // Setup test data. 1286 $course = $this->getDataGenerator()->create_course(); 1287 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 1288 $user = $this->getDataGenerator()->create_user(); 1289 $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 1290 self::getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 1291 1292 // Add a discussion. 1293 $record = new \stdClass(); 1294 $record->course = $course->id; 1295 $record->userid = $user->id; 1296 $record->forum = $forum->id; 1297 $record->created = 1298 $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 1299 1300 // Add rating. 1301 $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 1302 $post->totalscore = 80; 1303 $DB->update_record('forum_posts', $post); 1304 1305 $vaultfactory = container::get_vault_factory(); 1306 $forumvault = $vaultfactory->get_forum_vault(); 1307 $discussionvault = $vaultfactory->get_discussion_vault(); 1308 $postvault = $vaultfactory->get_post_vault(); 1309 1310 $postentity = $postvault->get_from_id($post->id); 1311 $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id()); 1312 $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id()); 1313 $capabilitymanager = $this->managerfactory->get_capability_manager($forumentity); 1314 1315 $this->setUser($user); 1316 $this->expectExceptionMessage(get_string('couldnotdeleteratings', 'rating')); 1317 $capabilitymanager->validate_delete_post($user, $discussionentity, $postentity, false); 1318 } 1319 1320 /** 1321 * Test delete a post with replies. 1322 */ 1323 public function test_validate_delete_post_with_replies() { 1324 global $DB; 1325 $this->resetAfterTest(true); 1326 1327 // Setup test data. 1328 $course = $this->getDataGenerator()->create_course(); 1329 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); 1330 $user = $this->getDataGenerator()->create_user(); 1331 $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); 1332 self::getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 1333 1334 // Add a discussion. 1335 $record = new \stdClass(); 1336 $record->course = $course->id; 1337 $record->userid = $user->id; 1338 $record->forum = $forum->id; 1339 $record->created = 1340 $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); 1341 1342 $parentpost = $DB->get_record('forum_posts', array('discussion' => $discussion->id)); 1343 // Add a post. 1344 $record = new \stdClass(); 1345 $record->course = $course->id; 1346 $record->userid = $user->id; 1347 $record->forum = $forum->id; 1348 $record->discussion = $discussion->id; 1349 $record->parent = $parentpost->id; 1350 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); 1351 1352 $vaultfactory = container::get_vault_factory(); 1353 $forumvault = $vaultfactory->get_forum_vault(); 1354 $discussionvault = $vaultfactory->get_discussion_vault(); 1355 $postvault = $vaultfactory->get_post_vault(); 1356 1357 $postentity = $postvault->get_from_id($parentpost->id); 1358 $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id()); 1359 $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id()); 1360 $capabilitymanager = $this->managerfactory->get_capability_manager($forumentity); 1361 1362 $this->setUser($user); 1363 // Get reply count. 1364 $replycount = $postvault->get_reply_count_for_post_id_in_discussion_id( 1365 $user, $postentity->get_id(), $discussionentity->get_id(), true); 1366 $this->expectExceptionMessage(get_string('couldnotdeletereplies', 'forum')); 1367 $capabilitymanager->validate_delete_post($user, $discussionentity, $postentity, $replycount); 1368 } 1369 1370 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body