Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 402] [Versions 311 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  /**
  18   * Tests for forum events.
  19   *
  20   * @package    mod_forum
  21   * @category   test
  22   * @copyright  2014 Dan Poltawski <dan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace mod_forum\event;
  27  
  28  /**
  29   * Tests for forum events.
  30   *
  31   * @package    mod_forum
  32   * @category   test
  33   * @copyright  2014 Dan Poltawski <dan@moodle.com>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class events_test extends \advanced_testcase {
  37  
  38      /**
  39       * Tests set up.
  40       */
  41      public function setUp(): void {
  42          // We must clear the subscription caches. This has to be done both before each test, and after in case of other
  43          // tests using these functions.
  44          \mod_forum\subscriptions::reset_forum_cache();
  45  
  46          $this->resetAfterTest();
  47      }
  48  
  49      public function tearDown(): void {
  50          // We must clear the subscription caches. This has to be done both before each test, and after in case of other
  51          // tests using these functions.
  52          \mod_forum\subscriptions::reset_forum_cache();
  53      }
  54  
  55      /**
  56       * Ensure course_searched event validates that searchterm is set.
  57       */
  58      public function test_course_searched_searchterm_validation() {
  59          $course = $this->getDataGenerator()->create_course();
  60          $coursectx = \context_course::instance($course->id);
  61          $params = array(
  62              'context' => $coursectx,
  63          );
  64  
  65          $this->expectException(\coding_exception::class);
  66          $this->expectExceptionMessage("The 'searchterm' value must be set in other.");
  67          \mod_forum\event\course_searched::create($params);
  68      }
  69  
  70      /**
  71       * Ensure course_searched event validates that context is the correct level.
  72       */
  73      public function test_course_searched_context_validation() {
  74          $course = $this->getDataGenerator()->create_course();
  75          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
  76          $context = \context_module::instance($forum->cmid);
  77          $params = array(
  78              'context' => $context,
  79              'other' => array('searchterm' => 'testing'),
  80          );
  81  
  82          $this->expectException(\coding_exception::class);
  83          $this->expectExceptionMessage('Context level must be CONTEXT_COURSE.');
  84          \mod_forum\event\course_searched::create($params);
  85      }
  86  
  87      /**
  88       * Test course_searched event.
  89       */
  90      public function test_course_searched() {
  91  
  92          // Setup test data.
  93          $course = $this->getDataGenerator()->create_course();
  94          $coursectx = \context_course::instance($course->id);
  95          $searchterm = 'testing123';
  96  
  97          $params = array(
  98              'context' => $coursectx,
  99              'other' => array('searchterm' => $searchterm),
 100          );
 101  
 102          // Create event.
 103          $event = \mod_forum\event\course_searched::create($params);
 104  
 105          // Trigger and capture the event.
 106          $sink = $this->redirectEvents();
 107          $event->trigger();
 108          $events = $sink->get_events();
 109          $this->assertCount(1, $events);
 110          $event = reset($events);
 111  
 112           // Checking that the event contains the expected values.
 113          $this->assertInstanceOf('\mod_forum\event\course_searched', $event);
 114          $this->assertEquals($coursectx, $event->get_context());
 115          $expected = array($course->id, 'forum', 'search', "search.php?id={$course->id}&amp;search={$searchterm}", $searchterm);
 116          $this->assertEventLegacyLogData($expected, $event);
 117          $this->assertEventContextNotUsed($event);
 118  
 119          $this->assertNotEmpty($event->get_name());
 120      }
 121  
 122      /**
 123       * Ensure discussion_created event validates that forumid is set.
 124       */
 125      public function test_discussion_created_forumid_validation() {
 126          $course = $this->getDataGenerator()->create_course();
 127          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 128          $context = \context_module::instance($forum->cmid);
 129  
 130          $params = array(
 131              'context' => $context,
 132          );
 133  
 134          $this->expectException(\coding_exception::class);
 135          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 136          \mod_forum\event\discussion_created::create($params);
 137      }
 138  
 139      /**
 140       * Ensure discussion_created event validates that the context is the correct level.
 141       */
 142      public function test_discussion_created_context_validation() {
 143          $course = $this->getDataGenerator()->create_course();
 144          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 145  
 146          $params = array(
 147              'context' => \context_system::instance(),
 148              'other' => array('forumid' => $forum->id),
 149          );
 150  
 151          $this->expectException(\coding_exception::class);
 152          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 153          \mod_forum\event\discussion_created::create($params);
 154      }
 155  
 156      /**
 157       * Test discussion_created event.
 158       */
 159      public function test_discussion_created() {
 160  
 161          // Setup test data.
 162          $course = $this->getDataGenerator()->create_course();
 163          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 164          $user = $this->getDataGenerator()->create_user();
 165  
 166          // Add a discussion.
 167          $record = array();
 168          $record['course'] = $course->id;
 169          $record['forum'] = $forum->id;
 170          $record['userid'] = $user->id;
 171          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 172  
 173          $context = \context_module::instance($forum->cmid);
 174  
 175          $params = array(
 176              'context' => $context,
 177              'objectid' => $discussion->id,
 178              'other' => array('forumid' => $forum->id),
 179          );
 180  
 181          // Create the event.
 182          $event = \mod_forum\event\discussion_created::create($params);
 183  
 184          // Trigger and capturing the event.
 185          $sink = $this->redirectEvents();
 186          $event->trigger();
 187          $events = $sink->get_events();
 188          $this->assertCount(1, $events);
 189          $event = reset($events);
 190  
 191          // Check that the event contains the expected values.
 192          $this->assertInstanceOf('\mod_forum\event\discussion_created', $event);
 193          $this->assertEquals($context, $event->get_context());
 194          $expected = array($course->id, 'forum', 'add discussion', "discuss.php?d={$discussion->id}", $discussion->id, $forum->cmid);
 195          $this->assertEventLegacyLogData($expected, $event);
 196          $this->assertEventContextNotUsed($event);
 197  
 198          $this->assertNotEmpty($event->get_name());
 199      }
 200  
 201      /**
 202       * Ensure discussion_updated event validates that forumid is set.
 203       */
 204      public function test_discussion_updated_forumid_validation() {
 205          $course = $this->getDataGenerator()->create_course();
 206          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 207          $context = \context_module::instance($forum->cmid);
 208  
 209          $params = array(
 210              'context' => $context,
 211          );
 212  
 213          $this->expectException(\coding_exception::class);
 214          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 215          \mod_forum\event\discussion_updated::create($params);
 216      }
 217  
 218      /**
 219       * Ensure discussion_created event validates that the context is the correct level.
 220       */
 221      public function test_discussion_updated_context_validation() {
 222          $course = $this->getDataGenerator()->create_course();
 223          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 224  
 225          $params = array(
 226              'context' => \context_system::instance(),
 227              'other' => array('forumid' => $forum->id),
 228          );
 229  
 230          $this->expectException(\coding_exception::class);
 231          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 232          \mod_forum\event\discussion_updated::create($params);
 233      }
 234  
 235      /**
 236       * Test discussion_created event.
 237       */
 238      public function test_discussion_updated() {
 239  
 240          // Setup test data.
 241          $course = $this->getDataGenerator()->create_course();
 242          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 243          $user = $this->getDataGenerator()->create_user();
 244  
 245          // Add a discussion.
 246          $record = array();
 247          $record['course'] = $course->id;
 248          $record['forum'] = $forum->id;
 249          $record['userid'] = $user->id;
 250          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 251  
 252          $context = \context_module::instance($forum->cmid);
 253  
 254          $params = array(
 255              'context' => $context,
 256              'objectid' => $discussion->id,
 257              'other' => array('forumid' => $forum->id),
 258          );
 259  
 260          // Create the event.
 261          $event = \mod_forum\event\discussion_updated::create($params);
 262  
 263          // Trigger and capturing the event.
 264          $sink = $this->redirectEvents();
 265          $event->trigger();
 266          $events = $sink->get_events();
 267          $this->assertCount(1, $events);
 268          $event = reset($events);
 269  
 270          // Check that the event contains the expected values.
 271          $this->assertInstanceOf('\mod_forum\event\discussion_updated', $event);
 272          $this->assertEquals($context, $event->get_context());
 273          $this->assertEventContextNotUsed($event);
 274  
 275          $this->assertNotEmpty($event->get_name());
 276      }
 277  
 278      /**
 279       * Ensure discussion_deleted event validates that forumid is set.
 280       */
 281      public function test_discussion_deleted_forumid_validation() {
 282          $course = $this->getDataGenerator()->create_course();
 283          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 284          $context = \context_module::instance($forum->cmid);
 285  
 286          $params = array(
 287              'context' => $context,
 288          );
 289  
 290          $this->expectException(\coding_exception::class);
 291          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 292          \mod_forum\event\discussion_deleted::create($params);
 293      }
 294  
 295      /**
 296       * Ensure discussion_deleted event validates that context is of the correct level.
 297       */
 298      public function test_discussion_deleted_context_validation() {
 299          $course = $this->getDataGenerator()->create_course();
 300          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 301  
 302          $params = array(
 303              'context' => \context_system::instance(),
 304              'other' => array('forumid' => $forum->id),
 305          );
 306  
 307          $this->expectException(\coding_exception::class);
 308          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 309          \mod_forum\event\discussion_deleted::create($params);
 310      }
 311  
 312      /**
 313       * Test discussion_deleted event.
 314       */
 315      public function test_discussion_deleted() {
 316  
 317          // Setup test data.
 318          $course = $this->getDataGenerator()->create_course();
 319          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 320          $user = $this->getDataGenerator()->create_user();
 321  
 322          // Add a discussion.
 323          $record = array();
 324          $record['course'] = $course->id;
 325          $record['forum'] = $forum->id;
 326          $record['userid'] = $user->id;
 327          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 328  
 329          $context = \context_module::instance($forum->cmid);
 330  
 331          $params = array(
 332              'context' => $context,
 333              'objectid' => $discussion->id,
 334              'other' => array('forumid' => $forum->id),
 335          );
 336  
 337          $event = \mod_forum\event\discussion_deleted::create($params);
 338  
 339          // Trigger and capture the event.
 340          $sink = $this->redirectEvents();
 341          $event->trigger();
 342          $events = $sink->get_events();
 343          $this->assertCount(1, $events);
 344          $event = reset($events);
 345  
 346          // Checking that the event contains the expected values.
 347          $this->assertInstanceOf('\mod_forum\event\discussion_deleted', $event);
 348          $this->assertEquals($context, $event->get_context());
 349          $expected = array($course->id, 'forum', 'delete discussion', "view.php?id={$forum->cmid}", $forum->id, $forum->cmid);
 350          $this->assertEventLegacyLogData($expected, $event);
 351          $this->assertEventContextNotUsed($event);
 352  
 353          $this->assertNotEmpty($event->get_name());
 354      }
 355  
 356      /**
 357       * Ensure discussion_moved event validates that fromforumid is set.
 358       */
 359      public function test_discussion_moved_fromforumid_validation() {
 360          $course = $this->getDataGenerator()->create_course();
 361          $toforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 362  
 363          $context = \context_module::instance($toforum->cmid);
 364  
 365          $params = array(
 366              'context' => $context,
 367              'other' => array('toforumid' => $toforum->id)
 368          );
 369  
 370          $this->expectException(\coding_exception::class);
 371          $this->expectExceptionMessage("The 'fromforumid' value must be set in other.");
 372          \mod_forum\event\discussion_moved::create($params);
 373      }
 374  
 375      /**
 376       * Ensure discussion_moved event validates that toforumid is set.
 377       */
 378      public function test_discussion_moved_toforumid_validation() {
 379          $course = $this->getDataGenerator()->create_course();
 380          $fromforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 381          $toforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 382          $context = \context_module::instance($toforum->cmid);
 383  
 384          $params = array(
 385              'context' => $context,
 386              'other' => array('fromforumid' => $fromforum->id)
 387          );
 388  
 389          $this->expectException(\coding_exception::class);
 390          $this->expectExceptionMessage("The 'toforumid' value must be set in other.");
 391          \mod_forum\event\discussion_moved::create($params);
 392      }
 393  
 394      /**
 395       * Ensure discussion_moved event validates that the context level is correct.
 396       */
 397      public function test_discussion_moved_context_validation() {
 398          $course = $this->getDataGenerator()->create_course();
 399          $fromforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 400          $toforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 401          $user = $this->getDataGenerator()->create_user();
 402  
 403          // Add a discussion.
 404          $record = array();
 405          $record['course'] = $course->id;
 406          $record['forum'] = $fromforum->id;
 407          $record['userid'] = $user->id;
 408          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 409  
 410          $params = array(
 411              'context' => \context_system::instance(),
 412              'objectid' => $discussion->id,
 413              'other' => array('fromforumid' => $fromforum->id, 'toforumid' => $toforum->id)
 414          );
 415  
 416          $this->expectException(\coding_exception::class);
 417          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 418          \mod_forum\event\discussion_moved::create($params);
 419      }
 420  
 421      /**
 422       * Test discussion_moved event.
 423       */
 424      public function test_discussion_moved() {
 425          // Setup test data.
 426          $course = $this->getDataGenerator()->create_course();
 427          $fromforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 428          $toforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 429          $user = $this->getDataGenerator()->create_user();
 430  
 431          // Add a discussion.
 432          $record = array();
 433          $record['course'] = $course->id;
 434          $record['forum'] = $fromforum->id;
 435          $record['userid'] = $user->id;
 436          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 437  
 438          $context = \context_module::instance($toforum->cmid);
 439  
 440          $params = array(
 441              'context' => $context,
 442              'objectid' => $discussion->id,
 443              'other' => array('fromforumid' => $fromforum->id, 'toforumid' => $toforum->id)
 444          );
 445  
 446          $event = \mod_forum\event\discussion_moved::create($params);
 447  
 448          // Trigger and capture the event.
 449          $sink = $this->redirectEvents();
 450          $event->trigger();
 451          $events = $sink->get_events();
 452          $this->assertCount(1, $events);
 453          $event = reset($events);
 454  
 455          // Checking that the event contains the expected values.
 456          $this->assertInstanceOf('\mod_forum\event\discussion_moved', $event);
 457          $this->assertEquals($context, $event->get_context());
 458          $expected = array($course->id, 'forum', 'move discussion', "discuss.php?d={$discussion->id}",
 459              $discussion->id, $toforum->cmid);
 460          $this->assertEventLegacyLogData($expected, $event);
 461          $this->assertEventContextNotUsed($event);
 462  
 463          $this->assertNotEmpty($event->get_name());
 464      }
 465  
 466  
 467      /**
 468       * Ensure discussion_viewed event validates that the contextlevel is correct.
 469       */
 470      public function test_discussion_viewed_context_validation() {
 471          $course = $this->getDataGenerator()->create_course();
 472          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 473          $user = $this->getDataGenerator()->create_user();
 474  
 475          // Add a discussion.
 476          $record = array();
 477          $record['course'] = $course->id;
 478          $record['forum'] = $forum->id;
 479          $record['userid'] = $user->id;
 480          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 481  
 482          $params = array(
 483              'context' => \context_system::instance(),
 484              'objectid' => $discussion->id,
 485          );
 486  
 487          $this->expectException(\coding_exception::class);
 488          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 489          \mod_forum\event\discussion_viewed::create($params);
 490      }
 491  
 492      /**
 493       * Test discussion_viewed event.
 494       */
 495      public function test_discussion_viewed() {
 496          // Setup test data.
 497          $course = $this->getDataGenerator()->create_course();
 498          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 499          $user = $this->getDataGenerator()->create_user();
 500  
 501          // Add a discussion.
 502          $record = array();
 503          $record['course'] = $course->id;
 504          $record['forum'] = $forum->id;
 505          $record['userid'] = $user->id;
 506          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
 507  
 508          $context = \context_module::instance($forum->cmid);
 509  
 510          $params = array(
 511              'context' => $context,
 512              'objectid' => $discussion->id,
 513          );
 514  
 515          $event = \mod_forum\event\discussion_viewed::create($params);
 516  
 517          // Trigger and capture the event.
 518          $sink = $this->redirectEvents();
 519          $event->trigger();
 520          $events = $sink->get_events();
 521          $this->assertCount(1, $events);
 522          $event = reset($events);
 523  
 524          // Checking that the event contains the expected values.
 525          $this->assertInstanceOf('\mod_forum\event\discussion_viewed', $event);
 526          $this->assertEquals($context, $event->get_context());
 527          $expected = array($course->id, 'forum', 'view discussion', "discuss.php?d={$discussion->id}",
 528              $discussion->id, $forum->cmid);
 529          $this->assertEventLegacyLogData($expected, $event);
 530          $this->assertEventContextNotUsed($event);
 531  
 532          $this->assertNotEmpty($event->get_name());
 533      }
 534  
 535      /**
 536       * Ensure course_module_viewed event validates that the contextlevel is correct.
 537       */
 538      public function test_course_module_viewed_context_validation() {
 539          $course = $this->getDataGenerator()->create_course();
 540          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 541  
 542          $params = array(
 543              'context' => \context_system::instance(),
 544              'objectid' => $forum->id,
 545          );
 546  
 547          $this->expectException(\coding_exception::class);
 548          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 549          \mod_forum\event\course_module_viewed::create($params);
 550      }
 551  
 552      /**
 553       * Test the course_module_viewed event.
 554       */
 555      public function test_course_module_viewed() {
 556          // Setup test data.
 557          $course = $this->getDataGenerator()->create_course();
 558          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 559  
 560          $context = \context_module::instance($forum->cmid);
 561  
 562          $params = array(
 563              'context' => $context,
 564              'objectid' => $forum->id,
 565          );
 566  
 567          $event = \mod_forum\event\course_module_viewed::create($params);
 568  
 569          // Trigger and capture the event.
 570          $sink = $this->redirectEvents();
 571          $event->trigger();
 572          $events = $sink->get_events();
 573          $this->assertCount(1, $events);
 574          $event = reset($events);
 575  
 576          // Checking that the event contains the expected values.
 577          $this->assertInstanceOf('\mod_forum\event\course_module_viewed', $event);
 578          $this->assertEquals($context, $event->get_context());
 579          $expected = array($course->id, 'forum', 'view forum', "view.php?f={$forum->id}", $forum->id, $forum->cmid);
 580          $this->assertEventLegacyLogData($expected, $event);
 581          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
 582          $this->assertEquals($url, $event->get_url());
 583          $this->assertEventContextNotUsed($event);
 584  
 585          $this->assertNotEmpty($event->get_name());
 586      }
 587  
 588      /**
 589       * Ensure subscription_created event validates that the forumid is set.
 590       */
 591      public function test_subscription_created_forumid_validation() {
 592          $user = $this->getDataGenerator()->create_user();
 593          $course = $this->getDataGenerator()->create_course();
 594          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 595  
 596          $params = array(
 597              'context' => \context_module::instance($forum->cmid),
 598              'relateduserid' => $user->id,
 599          );
 600  
 601          $this->expectException(\coding_exception::class);
 602          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 603          \mod_forum\event\subscription_created::create($params);
 604      }
 605  
 606      /**
 607       * Ensure subscription_created event validates that the relateduserid is set.
 608       */
 609      public function test_subscription_created_relateduserid_validation() {
 610          $course = $this->getDataGenerator()->create_course();
 611          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 612  
 613          $params = array(
 614              'context' => \context_module::instance($forum->cmid),
 615              'objectid' => $forum->id,
 616          );
 617  
 618          $this->expectException(\coding_exception::class);
 619          $this->expectExceptionMessage("The 'relateduserid' must be set.");
 620          \mod_forum\event\subscription_created::create($params);
 621      }
 622  
 623      /**
 624       * Ensure subscription_created event validates that the contextlevel is correct.
 625       */
 626      public function test_subscription_created_contextlevel_validation() {
 627          $user = $this->getDataGenerator()->create_user();
 628          $course = $this->getDataGenerator()->create_course();
 629          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 630  
 631          $params = array(
 632              'context' => \context_system::instance(),
 633              'other' => array('forumid' => $forum->id),
 634              'relateduserid' => $user->id,
 635          );
 636  
 637          $this->expectException(\coding_exception::class);
 638          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 639          \mod_forum\event\subscription_created::create($params);
 640      }
 641  
 642      /**
 643       * Test the subscription_created event.
 644       */
 645      public function test_subscription_created() {
 646          // Setup test data.
 647          $user = $this->getDataGenerator()->create_user();
 648          $course = $this->getDataGenerator()->create_course();
 649          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 650          $user = $this->getDataGenerator()->create_user();
 651          $context = \context_module::instance($forum->cmid);
 652  
 653          // Add a subscription.
 654          $record = array();
 655          $record['course'] = $course->id;
 656          $record['forum'] = $forum->id;
 657          $record['userid'] = $user->id;
 658          $subscription = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_subscription($record);
 659  
 660          $params = array(
 661              'context' => $context,
 662              'objectid' => $subscription->id,
 663              'other' => array('forumid' => $forum->id),
 664              'relateduserid' => $user->id,
 665          );
 666  
 667          $event = \mod_forum\event\subscription_created::create($params);
 668  
 669          // Trigger and capturing the event.
 670          $sink = $this->redirectEvents();
 671          $event->trigger();
 672          $events = $sink->get_events();
 673          $this->assertCount(1, $events);
 674          $event = reset($events);
 675  
 676          // Checking that the event contains the expected values.
 677          $this->assertInstanceOf('\mod_forum\event\subscription_created', $event);
 678          $this->assertEquals($context, $event->get_context());
 679          $expected = array($course->id, 'forum', 'subscribe', "view.php?f={$forum->id}", $forum->id, $forum->cmid);
 680          $this->assertEventLegacyLogData($expected, $event);
 681          $url = new \moodle_url('/mod/forum/subscribers.php', array('id' => $forum->id));
 682          $this->assertEquals($url, $event->get_url());
 683          $this->assertEventContextNotUsed($event);
 684  
 685          $this->assertNotEmpty($event->get_name());
 686      }
 687  
 688      /**
 689       * Ensure subscription_deleted event validates that the forumid is set.
 690       */
 691      public function test_subscription_deleted_forumid_validation() {
 692          $user = $this->getDataGenerator()->create_user();
 693          $course = $this->getDataGenerator()->create_course();
 694          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 695  
 696          $params = array(
 697              'context' => \context_module::instance($forum->cmid),
 698              'relateduserid' => $user->id,
 699          );
 700  
 701          $this->expectException(\coding_exception::class);
 702          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 703          \mod_forum\event\subscription_deleted::create($params);
 704      }
 705  
 706      /**
 707       * Ensure subscription_deleted event validates that the relateduserid is set.
 708       */
 709      public function test_subscription_deleted_relateduserid_validation() {
 710          $course = $this->getDataGenerator()->create_course();
 711          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 712  
 713          $params = array(
 714              'context' => \context_module::instance($forum->cmid),
 715              'objectid' => $forum->id,
 716          );
 717  
 718          $this->expectException(\coding_exception::class);
 719          $this->expectExceptionMessage("The 'relateduserid' must be set.");
 720          \mod_forum\event\subscription_deleted::create($params);
 721      }
 722  
 723      /**
 724       * Ensure subscription_deleted event validates that the contextlevel is correct.
 725       */
 726      public function test_subscription_deleted_contextlevel_validation() {
 727          $user = $this->getDataGenerator()->create_user();
 728          $course = $this->getDataGenerator()->create_course();
 729          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 730  
 731          $params = array(
 732              'context' => \context_system::instance(),
 733              'other' => array('forumid' => $forum->id),
 734              'relateduserid' => $user->id,
 735          );
 736  
 737          $this->expectException(\coding_exception::class);
 738          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 739          \mod_forum\event\subscription_deleted::create($params);
 740      }
 741  
 742      /**
 743       * Test the subscription_deleted event.
 744       */
 745      public function test_subscription_deleted() {
 746          // Setup test data.
 747          $user = $this->getDataGenerator()->create_user();
 748          $course = $this->getDataGenerator()->create_course();
 749          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 750          $user = $this->getDataGenerator()->create_user();
 751          $context = \context_module::instance($forum->cmid);
 752  
 753          // Add a subscription.
 754          $record = array();
 755          $record['course'] = $course->id;
 756          $record['forum'] = $forum->id;
 757          $record['userid'] = $user->id;
 758          $subscription = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_subscription($record);
 759  
 760          $params = array(
 761              'context' => $context,
 762              'objectid' => $subscription->id,
 763              'other' => array('forumid' => $forum->id),
 764              'relateduserid' => $user->id,
 765          );
 766  
 767          $event = \mod_forum\event\subscription_deleted::create($params);
 768  
 769          // Trigger and capturing the event.
 770          $sink = $this->redirectEvents();
 771          $event->trigger();
 772          $events = $sink->get_events();
 773          $this->assertCount(1, $events);
 774          $event = reset($events);
 775  
 776          // Checking that the event contains the expected values.
 777          $this->assertInstanceOf('\mod_forum\event\subscription_deleted', $event);
 778          $this->assertEquals($context, $event->get_context());
 779          $expected = array($course->id, 'forum', 'unsubscribe', "view.php?f={$forum->id}", $forum->id, $forum->cmid);
 780          $this->assertEventLegacyLogData($expected, $event);
 781          $url = new \moodle_url('/mod/forum/subscribers.php', array('id' => $forum->id));
 782          $this->assertEquals($url, $event->get_url());
 783          $this->assertEventContextNotUsed($event);
 784  
 785          $this->assertNotEmpty($event->get_name());
 786      }
 787  
 788      /**
 789       * Ensure readtracking_enabled event validates that the forumid is set.
 790       */
 791      public function test_readtracking_enabled_forumid_validation() {
 792          $user = $this->getDataGenerator()->create_user();
 793          $course = $this->getDataGenerator()->create_course();
 794          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 795  
 796          $params = array(
 797              'context' => \context_module::instance($forum->cmid),
 798              'relateduserid' => $user->id,
 799          );
 800  
 801          $this->expectException(\coding_exception::class);
 802          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 803          \mod_forum\event\readtracking_enabled::create($params);
 804      }
 805  
 806      /**
 807       * Ensure readtracking_enabled event validates that the relateduserid is set.
 808       */
 809      public function test_readtracking_enabled_relateduserid_validation() {
 810          $course = $this->getDataGenerator()->create_course();
 811          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 812  
 813          $params = array(
 814              'context' => \context_module::instance($forum->cmid),
 815              'objectid' => $forum->id,
 816          );
 817  
 818          $this->expectException(\coding_exception::class);
 819          $this->expectExceptionMessage("The 'relateduserid' must be set.");
 820          \mod_forum\event\readtracking_enabled::create($params);
 821      }
 822  
 823      /**
 824       * Ensure readtracking_enabled event validates that the contextlevel is correct.
 825       */
 826      public function test_readtracking_enabled_contextlevel_validation() {
 827          $user = $this->getDataGenerator()->create_user();
 828          $course = $this->getDataGenerator()->create_course();
 829          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 830  
 831          $params = array(
 832              'context' => \context_system::instance(),
 833              'other' => array('forumid' => $forum->id),
 834              'relateduserid' => $user->id,
 835          );
 836  
 837          $this->expectException(\coding_exception::class);
 838          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 839          \mod_forum\event\readtracking_enabled::create($params);
 840      }
 841  
 842      /**
 843       * Test the readtracking_enabled event.
 844       */
 845      public function test_readtracking_enabled() {
 846          // Setup test data.
 847          $user = $this->getDataGenerator()->create_user();
 848          $course = $this->getDataGenerator()->create_course();
 849          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 850          $context = \context_module::instance($forum->cmid);
 851  
 852          $params = array(
 853              'context' => $context,
 854              'other' => array('forumid' => $forum->id),
 855              'relateduserid' => $user->id,
 856          );
 857  
 858          $event = \mod_forum\event\readtracking_enabled::create($params);
 859  
 860          // Trigger and capture the event.
 861          $sink = $this->redirectEvents();
 862          $event->trigger();
 863          $events = $sink->get_events();
 864          $this->assertCount(1, $events);
 865          $event = reset($events);
 866  
 867          // Checking that the event contains the expected values.
 868          $this->assertInstanceOf('\mod_forum\event\readtracking_enabled', $event);
 869          $this->assertEquals($context, $event->get_context());
 870          $expected = array($course->id, 'forum', 'start tracking', "view.php?f={$forum->id}", $forum->id, $forum->cmid);
 871          $this->assertEventLegacyLogData($expected, $event);
 872          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
 873          $this->assertEquals($url, $event->get_url());
 874          $this->assertEventContextNotUsed($event);
 875  
 876          $this->assertNotEmpty($event->get_name());
 877      }
 878  
 879      /**
 880       *  Ensure readtracking_disabled event validates that the forumid is set.
 881       */
 882      public function test_readtracking_disabled_forumid_validation() {
 883          $user = $this->getDataGenerator()->create_user();
 884          $course = $this->getDataGenerator()->create_course();
 885          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 886  
 887          $params = array(
 888              'context' => \context_module::instance($forum->cmid),
 889              'relateduserid' => $user->id,
 890          );
 891  
 892          $this->expectException(\coding_exception::class);
 893          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 894          \mod_forum\event\readtracking_disabled::create($params);
 895      }
 896  
 897      /**
 898       *  Ensure readtracking_disabled event validates that the relateduserid is set.
 899       */
 900      public function test_readtracking_disabled_relateduserid_validation() {
 901          $course = $this->getDataGenerator()->create_course();
 902          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 903  
 904          $params = array(
 905              'context' => \context_module::instance($forum->cmid),
 906              'objectid' => $forum->id,
 907          );
 908  
 909          $this->expectException(\coding_exception::class);
 910          $this->expectExceptionMessage("The 'relateduserid' must be set.");
 911          \mod_forum\event\readtracking_disabled::create($params);
 912      }
 913  
 914      /**
 915       *  Ensure readtracking_disabled event validates that the contextlevel is correct
 916       */
 917      public function test_readtracking_disabled_contextlevel_validation() {
 918          $user = $this->getDataGenerator()->create_user();
 919          $course = $this->getDataGenerator()->create_course();
 920          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 921  
 922          $params = array(
 923              'context' => \context_system::instance(),
 924              'other' => array('forumid' => $forum->id),
 925              'relateduserid' => $user->id,
 926          );
 927  
 928          $this->expectException(\coding_exception::class);
 929          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
 930          \mod_forum\event\readtracking_disabled::create($params);
 931      }
 932  
 933      /**
 934       *  Test the readtracking_disabled event.
 935       */
 936      public function test_readtracking_disabled() {
 937          // Setup test data.
 938          $user = $this->getDataGenerator()->create_user();
 939          $course = $this->getDataGenerator()->create_course();
 940          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 941          $context = \context_module::instance($forum->cmid);
 942  
 943          $params = array(
 944              'context' => $context,
 945              'other' => array('forumid' => $forum->id),
 946              'relateduserid' => $user->id,
 947          );
 948  
 949          $event = \mod_forum\event\readtracking_disabled::create($params);
 950  
 951          // Trigger and capture the event.
 952          $sink = $this->redirectEvents();
 953          $event->trigger();
 954          $events = $sink->get_events();
 955          $this->assertCount(1, $events);
 956          $event = reset($events);
 957  
 958          // Checking that the event contains the expected values.
 959          $this->assertInstanceOf('\mod_forum\event\readtracking_disabled', $event);
 960          $this->assertEquals($context, $event->get_context());
 961          $expected = array($course->id, 'forum', 'stop tracking', "view.php?f={$forum->id}", $forum->id, $forum->cmid);
 962          $this->assertEventLegacyLogData($expected, $event);
 963          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
 964          $this->assertEquals($url, $event->get_url());
 965          $this->assertEventContextNotUsed($event);
 966  
 967          $this->assertNotEmpty($event->get_name());
 968      }
 969  
 970      /**
 971       *  Ensure subscribers_viewed event validates that the forumid is set.
 972       */
 973      public function test_subscribers_viewed_forumid_validation() {
 974          $user = $this->getDataGenerator()->create_user();
 975          $course = $this->getDataGenerator()->create_course();
 976          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 977  
 978          $params = array(
 979              'context' => \context_module::instance($forum->cmid),
 980              'relateduserid' => $user->id,
 981          );
 982  
 983          $this->expectException(\coding_exception::class);
 984          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
 985          \mod_forum\event\subscribers_viewed::create($params);
 986      }
 987  
 988      /**
 989       *  Ensure subscribers_viewed event validates that the contextlevel is correct.
 990       */
 991      public function test_subscribers_viewed_contextlevel_validation() {
 992          $user = $this->getDataGenerator()->create_user();
 993          $course = $this->getDataGenerator()->create_course();
 994          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
 995  
 996          $params = array(
 997              'context' => \context_system::instance(),
 998              'other' => array('forumid' => $forum->id),
 999              'relateduserid' => $user->id,
1000          );
1001  
1002          $this->expectException(\coding_exception::class);
1003          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
1004          \mod_forum\event\subscribers_viewed::create($params);
1005      }
1006  
1007      /**
1008       *  Test the subscribers_viewed event.
1009       */
1010      public function test_subscribers_viewed() {
1011          // Setup test data.
1012          $course = $this->getDataGenerator()->create_course();
1013          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1014          $context = \context_module::instance($forum->cmid);
1015  
1016          $params = array(
1017              'context' => $context,
1018              'other' => array('forumid' => $forum->id),
1019          );
1020  
1021          $event = \mod_forum\event\subscribers_viewed::create($params);
1022  
1023          // Trigger and capture the event.
1024          $sink = $this->redirectEvents();
1025          $event->trigger();
1026          $events = $sink->get_events();
1027          $this->assertCount(1, $events);
1028          $event = reset($events);
1029  
1030          // Checking that the event contains the expected values.
1031          $this->assertInstanceOf('\mod_forum\event\subscribers_viewed', $event);
1032          $this->assertEquals($context, $event->get_context());
1033          $expected = array($course->id, 'forum', 'view subscribers', "subscribers.php?id={$forum->id}", $forum->id, $forum->cmid);
1034          $this->assertEventLegacyLogData($expected, $event);
1035          $this->assertEventContextNotUsed($event);
1036  
1037          $this->assertNotEmpty($event->get_name());
1038      }
1039  
1040      /**
1041       * Ensure user_report_viewed event validates that the reportmode is set.
1042       */
1043      public function test_user_report_viewed_reportmode_validation() {
1044          $user = $this->getDataGenerator()->create_user();
1045          $course = $this->getDataGenerator()->create_course();
1046  
1047          $params = array(
1048              'context' => \context_course::instance($course->id),
1049              'relateduserid' => $user->id,
1050          );
1051  
1052          $this->expectException(\coding_exception::class);
1053          $this->expectExceptionMessage("The 'reportmode' value must be set in other.");
1054          \mod_forum\event\user_report_viewed::create($params);
1055      }
1056  
1057      /**
1058       * Ensure user_report_viewed event validates that the contextlevel is correct.
1059       */
1060      public function test_user_report_viewed_contextlevel_validation() {
1061          $user = $this->getDataGenerator()->create_user();
1062          $course = $this->getDataGenerator()->create_course();
1063          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1064  
1065          $params = array(
1066              'context' => \context_module::instance($forum->cmid),
1067              'other' => array('reportmode' => 'posts'),
1068              'relateduserid' => $user->id,
1069          );
1070  
1071          $this->expectException(\coding_exception::class);
1072          $this->expectExceptionMessage('Context level must be either CONTEXT_SYSTEM, CONTEXT_COURSE or CONTEXT_USER.');
1073          \mod_forum\event\user_report_viewed::create($params);
1074      }
1075  
1076      /**
1077       *  Ensure user_report_viewed event validates that the relateduserid is set.
1078       */
1079      public function test_user_report_viewed_relateduserid_validation() {
1080  
1081          $params = array(
1082              'context' => \context_system::instance(),
1083              'other' => array('reportmode' => 'posts'),
1084          );
1085  
1086          $this->expectException(\coding_exception::class);
1087          $this->expectExceptionMessage("The 'relateduserid' must be set.");
1088          \mod_forum\event\user_report_viewed::create($params);
1089      }
1090  
1091      /**
1092       * Test the user_report_viewed event.
1093       */
1094      public function test_user_report_viewed() {
1095          // Setup test data.
1096          $user = $this->getDataGenerator()->create_user();
1097          $course = $this->getDataGenerator()->create_course();
1098          $context = \context_course::instance($course->id);
1099  
1100          $params = array(
1101              'context' => $context,
1102              'relateduserid' => $user->id,
1103              'other' => array('reportmode' => 'discussions'),
1104          );
1105  
1106          $event = \mod_forum\event\user_report_viewed::create($params);
1107  
1108          // Trigger and capture the event.
1109          $sink = $this->redirectEvents();
1110          $event->trigger();
1111          $events = $sink->get_events();
1112          $this->assertCount(1, $events);
1113          $event = reset($events);
1114  
1115          // Checking that the event contains the expected values.
1116          $this->assertInstanceOf('\mod_forum\event\user_report_viewed', $event);
1117          $this->assertEquals($context, $event->get_context());
1118          $expected = array($course->id, 'forum', 'user report',
1119              "user.php?id={$user->id}&amp;mode=discussions&amp;course={$course->id}", $user->id);
1120          $this->assertEventLegacyLogData($expected, $event);
1121          $this->assertEventContextNotUsed($event);
1122  
1123          $this->assertNotEmpty($event->get_name());
1124      }
1125  
1126      /**
1127       *  Ensure post_created event validates that the postid is set.
1128       */
1129      public function test_post_created_postid_validation() {
1130          $course = $this->getDataGenerator()->create_course();
1131          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1132          $user = $this->getDataGenerator()->create_user();
1133  
1134          // Add a discussion.
1135          $record = array();
1136          $record['course'] = $course->id;
1137          $record['forum'] = $forum->id;
1138          $record['userid'] = $user->id;
1139          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1140  
1141          $params = array(
1142              'context' => \context_module::instance($forum->cmid),
1143              'other' => array('forumid' => $forum->id, 'forumtype' => $forum->type, 'discussionid' => $discussion->id)
1144          );
1145  
1146          \mod_forum\event\post_created::create($params);
1147      }
1148  
1149      /**
1150       * Ensure post_created event validates that the discussionid is set.
1151       */
1152      public function test_post_created_discussionid_validation() {
1153          $course = $this->getDataGenerator()->create_course();
1154          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1155          $user = $this->getDataGenerator()->create_user();
1156  
1157          // Add a discussion.
1158          $record = array();
1159          $record['course'] = $course->id;
1160          $record['forum'] = $forum->id;
1161          $record['userid'] = $user->id;
1162          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1163  
1164          // Add a post.
1165          $record = array();
1166          $record['discussion'] = $discussion->id;
1167          $record['userid'] = $user->id;
1168          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1169  
1170          $params = array(
1171              'context' => \context_module::instance($forum->cmid),
1172              'objectid' => $post->id,
1173              'other' => array('forumid' => $forum->id, 'forumtype' => $forum->type)
1174          );
1175  
1176          $this->expectException(\coding_exception::class);
1177          $this->expectExceptionMessage("The 'discussionid' value must be set in other.");
1178          \mod_forum\event\post_created::create($params);
1179      }
1180  
1181      /**
1182       *  Ensure post_created event validates that the forumid is set.
1183       */
1184      public function test_post_created_forumid_validation() {
1185          $course = $this->getDataGenerator()->create_course();
1186          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1187          $user = $this->getDataGenerator()->create_user();
1188  
1189          // Add a discussion.
1190          $record = array();
1191          $record['course'] = $course->id;
1192          $record['forum'] = $forum->id;
1193          $record['userid'] = $user->id;
1194          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1195  
1196          // Add a post.
1197          $record = array();
1198          $record['discussion'] = $discussion->id;
1199          $record['userid'] = $user->id;
1200          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1201  
1202          $params = array(
1203              'context' => \context_module::instance($forum->cmid),
1204              'objectid' => $post->id,
1205              'other' => array('discussionid' => $discussion->id, 'forumtype' => $forum->type)
1206          );
1207  
1208          $this->expectException(\coding_exception::class);
1209          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
1210          \mod_forum\event\post_created::create($params);
1211      }
1212  
1213      /**
1214       * Ensure post_created event validates that the forumtype is set.
1215       */
1216      public function test_post_created_forumtype_validation() {
1217          $course = $this->getDataGenerator()->create_course();
1218          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1219          $user = $this->getDataGenerator()->create_user();
1220  
1221          // Add a discussion.
1222          $record = array();
1223          $record['course'] = $course->id;
1224          $record['forum'] = $forum->id;
1225          $record['userid'] = $user->id;
1226          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1227  
1228          // Add a post.
1229          $record = array();
1230          $record['discussion'] = $discussion->id;
1231          $record['userid'] = $user->id;
1232          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1233  
1234          $params = array(
1235              'context' => \context_module::instance($forum->cmid),
1236              'objectid' => $post->id,
1237              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id)
1238          );
1239  
1240          $this->expectException(\coding_exception::class);
1241          $this->expectExceptionMessage("The 'forumtype' value must be set in other.");
1242          \mod_forum\event\post_created::create($params);
1243      }
1244  
1245      /**
1246       *  Ensure post_created event validates that the contextlevel is correct.
1247       */
1248      public function test_post_created_context_validation() {
1249          $course = $this->getDataGenerator()->create_course();
1250          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1251          $user = $this->getDataGenerator()->create_user();
1252  
1253          // Add a discussion.
1254          $record = array();
1255          $record['course'] = $course->id;
1256          $record['forum'] = $forum->id;
1257          $record['userid'] = $user->id;
1258          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1259  
1260          // Add a post.
1261          $record = array();
1262          $record['discussion'] = $discussion->id;
1263          $record['userid'] = $user->id;
1264          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1265  
1266          $params = array(
1267              'context' => \context_system::instance(),
1268              'objectid' => $post->id,
1269              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1270          );
1271  
1272          $this->expectException(\coding_exception::class);
1273          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
1274          \mod_forum\event\post_created::create($params);
1275      }
1276  
1277      /**
1278       * Test the post_created event.
1279       */
1280      public function test_post_created() {
1281          // Setup test data.
1282          $course = $this->getDataGenerator()->create_course();
1283          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1284          $user = $this->getDataGenerator()->create_user();
1285  
1286          // Add a discussion.
1287          $record = array();
1288          $record['course'] = $course->id;
1289          $record['forum'] = $forum->id;
1290          $record['userid'] = $user->id;
1291          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1292  
1293          // Add a post.
1294          $record = array();
1295          $record['discussion'] = $discussion->id;
1296          $record['userid'] = $user->id;
1297          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1298  
1299          $context = \context_module::instance($forum->cmid);
1300  
1301          $params = array(
1302              'context' => $context,
1303              'objectid' => $post->id,
1304              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1305          );
1306  
1307          $event = \mod_forum\event\post_created::create($params);
1308  
1309          // Trigger and capturing the event.
1310          $sink = $this->redirectEvents();
1311          $event->trigger();
1312          $events = $sink->get_events();
1313          $this->assertCount(1, $events);
1314          $event = reset($events);
1315  
1316          // Checking that the event contains the expected values.
1317          $this->assertInstanceOf('\mod_forum\event\post_created', $event);
1318          $this->assertEquals($context, $event->get_context());
1319          $expected = array($course->id, 'forum', 'add post', "discuss.php?d={$discussion->id}#p{$post->id}",
1320              $forum->id, $forum->cmid);
1321          $this->assertEventLegacyLogData($expected, $event);
1322          $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id));
1323          $url->set_anchor('p'.$event->objectid);
1324          $this->assertEquals($url, $event->get_url());
1325          $this->assertEventContextNotUsed($event);
1326  
1327          $this->assertNotEmpty($event->get_name());
1328      }
1329  
1330      /**
1331       * Test the post_created event for a single discussion forum.
1332       */
1333      public function test_post_created_single() {
1334          // Setup test data.
1335          $course = $this->getDataGenerator()->create_course();
1336          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'single'));
1337          $user = $this->getDataGenerator()->create_user();
1338  
1339          // Add a discussion.
1340          $record = array();
1341          $record['course'] = $course->id;
1342          $record['forum'] = $forum->id;
1343          $record['userid'] = $user->id;
1344          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1345  
1346          // Add a post.
1347          $record = array();
1348          $record['discussion'] = $discussion->id;
1349          $record['userid'] = $user->id;
1350          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1351  
1352          $context = \context_module::instance($forum->cmid);
1353  
1354          $params = array(
1355              'context' => $context,
1356              'objectid' => $post->id,
1357              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1358          );
1359  
1360          $event = \mod_forum\event\post_created::create($params);
1361  
1362          // Trigger and capturing the event.
1363          $sink = $this->redirectEvents();
1364          $event->trigger();
1365          $events = $sink->get_events();
1366          $this->assertCount(1, $events);
1367          $event = reset($events);
1368  
1369          // Checking that the event contains the expected values.
1370          $this->assertInstanceOf('\mod_forum\event\post_created', $event);
1371          $this->assertEquals($context, $event->get_context());
1372          $expected = array($course->id, 'forum', 'add post', "view.php?f={$forum->id}#p{$post->id}",
1373              $forum->id, $forum->cmid);
1374          $this->assertEventLegacyLogData($expected, $event);
1375          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
1376          $url->set_anchor('p'.$event->objectid);
1377          $this->assertEquals($url, $event->get_url());
1378          $this->assertEventContextNotUsed($event);
1379  
1380          $this->assertNotEmpty($event->get_name());
1381      }
1382  
1383      /**
1384       *  Ensure post_deleted event validates that the postid is set.
1385       */
1386      public function test_post_deleted_postid_validation() {
1387          $course = $this->getDataGenerator()->create_course();
1388          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1389          $user = $this->getDataGenerator()->create_user();
1390  
1391          // Add a discussion.
1392          $record = array();
1393          $record['course'] = $course->id;
1394          $record['forum'] = $forum->id;
1395          $record['userid'] = $user->id;
1396          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1397  
1398          $params = array(
1399              'context' => \context_module::instance($forum->cmid),
1400              'other' => array('forumid' => $forum->id, 'forumtype' => $forum->type, 'discussionid' => $discussion->id)
1401          );
1402  
1403          \mod_forum\event\post_deleted::create($params);
1404      }
1405  
1406      /**
1407       * Ensure post_deleted event validates that the discussionid is set.
1408       */
1409      public function test_post_deleted_discussionid_validation() {
1410          $course = $this->getDataGenerator()->create_course();
1411          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1412          $user = $this->getDataGenerator()->create_user();
1413  
1414          // Add a discussion.
1415          $record = array();
1416          $record['course'] = $course->id;
1417          $record['forum'] = $forum->id;
1418          $record['userid'] = $user->id;
1419          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1420  
1421          // Add a post.
1422          $record = array();
1423          $record['discussion'] = $discussion->id;
1424          $record['userid'] = $user->id;
1425          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1426  
1427          $params = array(
1428              'context' => \context_module::instance($forum->cmid),
1429              'objectid' => $post->id,
1430              'other' => array('forumid' => $forum->id, 'forumtype' => $forum->type)
1431          );
1432  
1433          $this->expectException(\coding_exception::class);
1434          $this->expectExceptionMessage("The 'discussionid' value must be set in other.");
1435          \mod_forum\event\post_deleted::create($params);
1436      }
1437  
1438      /**
1439       *  Ensure post_deleted event validates that the forumid is set.
1440       */
1441      public function test_post_deleted_forumid_validation() {
1442          $course = $this->getDataGenerator()->create_course();
1443          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1444          $user = $this->getDataGenerator()->create_user();
1445  
1446          // Add a discussion.
1447          $record = array();
1448          $record['course'] = $course->id;
1449          $record['forum'] = $forum->id;
1450          $record['userid'] = $user->id;
1451          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1452  
1453          // Add a post.
1454          $record = array();
1455          $record['discussion'] = $discussion->id;
1456          $record['userid'] = $user->id;
1457          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1458  
1459          $params = array(
1460              'context' => \context_module::instance($forum->cmid),
1461              'objectid' => $post->id,
1462              'other' => array('discussionid' => $discussion->id, 'forumtype' => $forum->type)
1463          );
1464  
1465          $this->expectException(\coding_exception::class);
1466          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
1467          \mod_forum\event\post_deleted::create($params);
1468      }
1469  
1470      /**
1471       * Ensure post_deleted event validates that the forumtype is set.
1472       */
1473      public function test_post_deleted_forumtype_validation() {
1474          $course = $this->getDataGenerator()->create_course();
1475          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1476          $user = $this->getDataGenerator()->create_user();
1477  
1478          // Add a discussion.
1479          $record = array();
1480          $record['course'] = $course->id;
1481          $record['forum'] = $forum->id;
1482          $record['userid'] = $user->id;
1483          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1484  
1485          // Add a post.
1486          $record = array();
1487          $record['discussion'] = $discussion->id;
1488          $record['userid'] = $user->id;
1489          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1490  
1491          $params = array(
1492              'context' => \context_module::instance($forum->cmid),
1493              'objectid' => $post->id,
1494              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id)
1495          );
1496  
1497          $this->expectException(\coding_exception::class);
1498          $this->expectExceptionMessage("The 'forumtype' value must be set in other.");
1499          \mod_forum\event\post_deleted::create($params);
1500      }
1501  
1502      /**
1503       *  Ensure post_deleted event validates that the contextlevel is correct.
1504       */
1505      public function test_post_deleted_context_validation() {
1506          $course = $this->getDataGenerator()->create_course();
1507          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1508          $user = $this->getDataGenerator()->create_user();
1509  
1510          // Add a discussion.
1511          $record = array();
1512          $record['course'] = $course->id;
1513          $record['forum'] = $forum->id;
1514          $record['userid'] = $user->id;
1515          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1516  
1517          // Add a post.
1518          $record = array();
1519          $record['discussion'] = $discussion->id;
1520          $record['userid'] = $user->id;
1521          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1522  
1523          $params = array(
1524              'context' => \context_system::instance(),
1525              'objectid' => $post->id,
1526              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1527          );
1528  
1529          $this->expectException(\coding_exception::class);
1530          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
1531          \mod_forum\event\post_deleted::create($params);
1532      }
1533  
1534      /**
1535       * Test post_deleted event.
1536       */
1537      public function test_post_deleted() {
1538          global $DB;
1539  
1540          // Setup test data.
1541          $course = $this->getDataGenerator()->create_course();
1542          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1543          $user = $this->getDataGenerator()->create_user();
1544          $cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course);
1545  
1546          // Add a discussion.
1547          $record = array();
1548          $record['course'] = $course->id;
1549          $record['forum'] = $forum->id;
1550          $record['userid'] = $user->id;
1551          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1552  
1553          // When creating a discussion we also create a post, so get the post.
1554          $discussionpost = $DB->get_records('forum_posts');
1555          // Will only be one here.
1556          $discussionpost = reset($discussionpost);
1557  
1558          // Add a few posts.
1559          $record = array();
1560          $record['discussion'] = $discussion->id;
1561          $record['userid'] = $user->id;
1562          $posts = array();
1563          $posts[$discussionpost->id] = $discussionpost;
1564          for ($i = 0; $i < 3; $i++) {
1565              $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1566              $posts[$post->id] = $post;
1567          }
1568  
1569          // Delete the last post and capture the event.
1570          $lastpost = end($posts);
1571          $sink = $this->redirectEvents();
1572          forum_delete_post($lastpost, true, $course, $cm, $forum);
1573          $events = $sink->get_events();
1574          $this->assertCount(1, $events);
1575          $event = reset($events);
1576  
1577          // Check that the events contain the expected values.
1578          $this->assertInstanceOf('\mod_forum\event\post_deleted', $event);
1579          $this->assertEquals(\context_module::instance($forum->cmid), $event->get_context());
1580          $expected = array($course->id, 'forum', 'delete post', "discuss.php?d={$discussion->id}", $lastpost->id, $forum->cmid);
1581          $this->assertEventLegacyLogData($expected, $event);
1582          $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id));
1583          $this->assertEquals($url, $event->get_url());
1584          $this->assertEventContextNotUsed($event);
1585          $this->assertNotEmpty($event->get_name());
1586  
1587          // Delete the whole discussion and capture the events.
1588          $sink = $this->redirectEvents();
1589          forum_delete_discussion($discussion, true, $course, $cm, $forum);
1590          $events = $sink->get_events();
1591          // We will have 4 events. One for the discussion, another one for the discussion topic post, and two for the posts.
1592          $this->assertCount(4, $events);
1593  
1594          // Loop through the events and check they are valid.
1595          foreach ($events as $event) {
1596              if ($event instanceof \mod_forum\event\discussion_deleted) {
1597                  // Check that the event contains the expected values.
1598                  $this->assertEquals($event->objectid, $discussion->id);
1599                  $this->assertEquals(\context_module::instance($forum->cmid), $event->get_context());
1600                  $expected = array($course->id, 'forum', 'delete discussion', "view.php?id={$forum->cmid}",
1601                      $forum->id, $forum->cmid);
1602                  $this->assertEventLegacyLogData($expected, $event);
1603                  $url = new \moodle_url('/mod/forum/view.php', array('id' => $forum->cmid));
1604                  $this->assertEquals($url, $event->get_url());
1605                  $this->assertEventContextNotUsed($event);
1606                  $this->assertNotEmpty($event->get_name());
1607              } else {
1608                  $post = $posts[$event->objectid];
1609                  // Check that the event contains the expected values.
1610                  $this->assertInstanceOf('\mod_forum\event\post_deleted', $event);
1611                  $this->assertEquals($event->objectid, $post->id);
1612                  $this->assertEquals(\context_module::instance($forum->cmid), $event->get_context());
1613                  $expected = array($course->id, 'forum', 'delete post', "discuss.php?d={$discussion->id}", $post->id, $forum->cmid);
1614                  $this->assertEventLegacyLogData($expected, $event);
1615                  $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id));
1616                  $this->assertEquals($url, $event->get_url());
1617                  $this->assertEventContextNotUsed($event);
1618                  $this->assertNotEmpty($event->get_name());
1619              }
1620          }
1621      }
1622  
1623      /**
1624       * Test post_deleted event for a single discussion forum.
1625       */
1626      public function test_post_deleted_single() {
1627          // Setup test data.
1628          $course = $this->getDataGenerator()->create_course();
1629          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'single'));
1630          $user = $this->getDataGenerator()->create_user();
1631  
1632          // Add a discussion.
1633          $record = array();
1634          $record['course'] = $course->id;
1635          $record['forum'] = $forum->id;
1636          $record['userid'] = $user->id;
1637          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1638  
1639          // Add a post.
1640          $record = array();
1641          $record['discussion'] = $discussion->id;
1642          $record['userid'] = $user->id;
1643          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1644  
1645          $context = \context_module::instance($forum->cmid);
1646  
1647          $params = array(
1648              'context' => $context,
1649              'objectid' => $post->id,
1650              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1651          );
1652  
1653          $event = \mod_forum\event\post_deleted::create($params);
1654  
1655          // Trigger and capture the event.
1656          $sink = $this->redirectEvents();
1657          $event->trigger();
1658          $events = $sink->get_events();
1659          $this->assertCount(1, $events);
1660          $event = reset($events);
1661  
1662          // Checking that the event contains the expected values.
1663          $this->assertInstanceOf('\mod_forum\event\post_deleted', $event);
1664          $this->assertEquals($context, $event->get_context());
1665          $expected = array($course->id, 'forum', 'delete post', "view.php?f={$forum->id}", $post->id, $forum->cmid);
1666          $this->assertEventLegacyLogData($expected, $event);
1667          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
1668          $this->assertEquals($url, $event->get_url());
1669          $this->assertEventContextNotUsed($event);
1670  
1671          $this->assertNotEmpty($event->get_name());
1672      }
1673  
1674      /**
1675       * Ensure post_updated event validates that the discussionid is set.
1676       */
1677      public function test_post_updated_discussionid_validation() {
1678          $course = $this->getDataGenerator()->create_course();
1679          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1680          $user = $this->getDataGenerator()->create_user();
1681  
1682          // Add a discussion.
1683          $record = array();
1684          $record['course'] = $course->id;
1685          $record['forum'] = $forum->id;
1686          $record['userid'] = $user->id;
1687          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1688  
1689          // Add a post.
1690          $record = array();
1691          $record['discussion'] = $discussion->id;
1692          $record['userid'] = $user->id;
1693          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1694  
1695          $params = array(
1696              'context' => \context_module::instance($forum->cmid),
1697              'objectid' => $post->id,
1698              'other' => array('forumid' => $forum->id, 'forumtype' => $forum->type)
1699          );
1700  
1701          $this->expectException(\coding_exception::class);
1702          $this->expectExceptionMessage("The 'discussionid' value must be set in other.");
1703          \mod_forum\event\post_updated::create($params);
1704      }
1705  
1706      /**
1707       * Ensure post_updated event validates that the forumid is set.
1708       */
1709      public function test_post_updated_forumid_validation() {
1710          $course = $this->getDataGenerator()->create_course();
1711          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1712          $user = $this->getDataGenerator()->create_user();
1713  
1714          // Add a discussion.
1715          $record = array();
1716          $record['course'] = $course->id;
1717          $record['forum'] = $forum->id;
1718          $record['userid'] = $user->id;
1719          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1720  
1721          // Add a post.
1722          $record = array();
1723          $record['discussion'] = $discussion->id;
1724          $record['userid'] = $user->id;
1725          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1726  
1727          $params = array(
1728              'context' => \context_module::instance($forum->cmid),
1729              'objectid' => $post->id,
1730              'other' => array('discussionid' => $discussion->id, 'forumtype' => $forum->type)
1731          );
1732  
1733          $this->expectException(\coding_exception::class);
1734          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
1735          \mod_forum\event\post_updated::create($params);
1736      }
1737  
1738      /**
1739       * Ensure post_updated event validates that the forumtype is set.
1740       */
1741      public function test_post_updated_forumtype_validation() {
1742          $course = $this->getDataGenerator()->create_course();
1743          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1744          $user = $this->getDataGenerator()->create_user();
1745  
1746          // Add a discussion.
1747          $record = array();
1748          $record['course'] = $course->id;
1749          $record['forum'] = $forum->id;
1750          $record['userid'] = $user->id;
1751          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1752  
1753          // Add a post.
1754          $record = array();
1755          $record['discussion'] = $discussion->id;
1756          $record['userid'] = $user->id;
1757          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1758  
1759          $params = array(
1760              'context' => \context_module::instance($forum->cmid),
1761              'objectid' => $post->id,
1762              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id)
1763          );
1764  
1765          $this->expectException(\coding_exception::class);
1766          $this->expectExceptionMessage("The 'forumtype' value must be set in other.");
1767          \mod_forum\event\post_updated::create($params);
1768      }
1769  
1770      /**
1771       *  Ensure post_updated event validates that the contextlevel is correct.
1772       */
1773      public function test_post_updated_context_validation() {
1774          $course = $this->getDataGenerator()->create_course();
1775          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1776          $user = $this->getDataGenerator()->create_user();
1777  
1778          // Add a discussion.
1779          $record = array();
1780          $record['course'] = $course->id;
1781          $record['forum'] = $forum->id;
1782          $record['userid'] = $user->id;
1783          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1784  
1785          // Add a post.
1786          $record = array();
1787          $record['discussion'] = $discussion->id;
1788          $record['userid'] = $user->id;
1789          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1790  
1791          $params = array(
1792              'context' => \context_system::instance(),
1793              'objectid' => $post->id,
1794              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1795          );
1796  
1797          $this->expectException(\coding_exception::class);
1798          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
1799          \mod_forum\event\post_updated::create($params);
1800      }
1801  
1802      /**
1803       * Test post_updated event.
1804       */
1805      public function test_post_updated() {
1806          // Setup test data.
1807          $course = $this->getDataGenerator()->create_course();
1808          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1809          $user = $this->getDataGenerator()->create_user();
1810  
1811          // Add a discussion.
1812          $record = array();
1813          $record['course'] = $course->id;
1814          $record['forum'] = $forum->id;
1815          $record['userid'] = $user->id;
1816          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1817  
1818          // Add a post.
1819          $record = array();
1820          $record['discussion'] = $discussion->id;
1821          $record['userid'] = $user->id;
1822          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1823  
1824          $context = \context_module::instance($forum->cmid);
1825  
1826          $params = array(
1827              'context' => $context,
1828              'objectid' => $post->id,
1829              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1830          );
1831  
1832          $event = \mod_forum\event\post_updated::create($params);
1833  
1834          // Trigger and capturing the event.
1835          $sink = $this->redirectEvents();
1836          $event->trigger();
1837          $events = $sink->get_events();
1838          $this->assertCount(1, $events);
1839          $event = reset($events);
1840  
1841          // Checking that the event contains the expected values.
1842          $this->assertInstanceOf('\mod_forum\event\post_updated', $event);
1843          $this->assertEquals($context, $event->get_context());
1844          $expected = array($course->id, 'forum', 'update post', "discuss.php?d={$discussion->id}#p{$post->id}",
1845              $post->id, $forum->cmid);
1846          $this->assertEventLegacyLogData($expected, $event);
1847          $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id));
1848          $url->set_anchor('p'.$event->objectid);
1849          $this->assertEquals($url, $event->get_url());
1850          $this->assertEventContextNotUsed($event);
1851  
1852          $this->assertNotEmpty($event->get_name());
1853      }
1854  
1855      /**
1856       * Test post_updated event.
1857       */
1858      public function test_post_updated_single() {
1859          // Setup test data.
1860          $course = $this->getDataGenerator()->create_course();
1861          $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'single'));
1862          $user = $this->getDataGenerator()->create_user();
1863  
1864          // Add a discussion.
1865          $record = array();
1866          $record['course'] = $course->id;
1867          $record['forum'] = $forum->id;
1868          $record['userid'] = $user->id;
1869          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1870  
1871          // Add a post.
1872          $record = array();
1873          $record['discussion'] = $discussion->id;
1874          $record['userid'] = $user->id;
1875          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1876  
1877          $context = \context_module::instance($forum->cmid);
1878  
1879          $params = array(
1880              'context' => $context,
1881              'objectid' => $post->id,
1882              'other' => array('discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type)
1883          );
1884  
1885          $event = \mod_forum\event\post_updated::create($params);
1886  
1887          // Trigger and capturing the event.
1888          $sink = $this->redirectEvents();
1889          $event->trigger();
1890          $events = $sink->get_events();
1891          $this->assertCount(1, $events);
1892          $event = reset($events);
1893  
1894          // Checking that the event contains the expected values.
1895          $this->assertInstanceOf('\mod_forum\event\post_updated', $event);
1896          $this->assertEquals($context, $event->get_context());
1897          $expected = array($course->id, 'forum', 'update post', "view.php?f={$forum->id}#p{$post->id}",
1898              $post->id, $forum->cmid);
1899          $this->assertEventLegacyLogData($expected, $event);
1900          $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
1901          $url->set_anchor('p'.$post->id);
1902          $this->assertEquals($url, $event->get_url());
1903          $this->assertEventContextNotUsed($event);
1904  
1905          $this->assertNotEmpty($event->get_name());
1906      }
1907  
1908      /**
1909       * Test discussion_subscription_created event.
1910       */
1911      public function test_discussion_subscription_created() {
1912          global $CFG;
1913          require_once($CFG->dirroot . '/mod/forum/lib.php');
1914  
1915          // Setup test data.
1916          $course = $this->getDataGenerator()->create_course();
1917          $user = $this->getDataGenerator()->create_user();
1918          $this->getDataGenerator()->enrol_user($user->id, $course->id);
1919  
1920          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1921          $forum = $this->getDataGenerator()->create_module('forum', $options);
1922  
1923          // Add a discussion.
1924          $record = array();
1925          $record['course'] = $course->id;
1926          $record['forum'] = $forum->id;
1927          $record['userid'] = $user->id;
1928          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1929  
1930          // Add a post.
1931          $record = array();
1932          $record['discussion'] = $discussion->id;
1933          $record['userid'] = $user->id;
1934          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1935  
1936          // Trigger and capturing the event.
1937          $sink = $this->redirectEvents();
1938  
1939          // Trigger the event by subscribing the user to the forum discussion.
1940          \mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion);
1941  
1942          $events = $sink->get_events();
1943          $this->assertCount(1, $events);
1944          $event = reset($events);
1945  
1946          // Checking that the event contains the expected values.
1947          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_created', $event);
1948  
1949          $cm = get_coursemodule_from_instance('forum', $discussion->forum);
1950          $context = \context_module::instance($cm->id);
1951          $this->assertEquals($context, $event->get_context());
1952  
1953          $url = new \moodle_url('/mod/forum/subscribe.php', array(
1954              'id' => $forum->id,
1955              'd' => $discussion->id
1956          ));
1957  
1958          $this->assertEquals($url, $event->get_url());
1959          $this->assertEventContextNotUsed($event);
1960          $this->assertNotEmpty($event->get_name());
1961      }
1962  
1963      /**
1964       * Test validation of discussion_subscription_created event.
1965       */
1966      public function test_discussion_subscription_created_validation() {
1967          global $CFG, $DB;
1968          require_once($CFG->dirroot . '/mod/forum/lib.php');
1969  
1970          // Setup test data.
1971          $course = $this->getDataGenerator()->create_course();
1972          $user = $this->getDataGenerator()->create_user();
1973          $this->getDataGenerator()->enrol_user($user->id, $course->id);
1974  
1975          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
1976          $forum = $this->getDataGenerator()->create_module('forum', $options);
1977  
1978          // Add a discussion.
1979          $record = array();
1980          $record['course'] = $course->id;
1981          $record['forum'] = $forum->id;
1982          $record['userid'] = $user->id;
1983          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
1984  
1985          // Add a post.
1986          $record = array();
1987          $record['discussion'] = $discussion->id;
1988          $record['userid'] = $user->id;
1989          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
1990  
1991          // The user is not subscribed to the forum. Insert a new discussion subscription.
1992          $subscription = new \stdClass();
1993          $subscription->userid  = $user->id;
1994          $subscription->forum = $forum->id;
1995          $subscription->discussion = $discussion->id;
1996          $subscription->preference = time();
1997  
1998          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
1999  
2000          $context = \context_module::instance($forum->cmid);
2001  
2002          $params = array(
2003              'context' => $context,
2004              'objectid' => $subscription->id,
2005              'relateduserid' => $user->id,
2006              'other' => array(
2007                  'forumid' => $forum->id,
2008                  'discussion' => $discussion->id,
2009              )
2010          );
2011  
2012          $event = \mod_forum\event\discussion_subscription_created::create($params);
2013  
2014          // Trigger and capturing the event.
2015          $sink = $this->redirectEvents();
2016          $event->trigger();
2017          $events = $sink->get_events();
2018          $this->assertCount(1, $events);
2019          $event = reset($events);
2020      }
2021  
2022      /**
2023       * Test contextlevel validation of discussion_subscription_created event.
2024       */
2025      public function test_discussion_subscription_created_validation_contextlevel() {
2026          global $CFG, $DB;
2027          require_once($CFG->dirroot . '/mod/forum/lib.php');
2028  
2029          // Setup test data.
2030          $course = $this->getDataGenerator()->create_course();
2031          $user = $this->getDataGenerator()->create_user();
2032          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2033  
2034          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2035          $forum = $this->getDataGenerator()->create_module('forum', $options);
2036  
2037          // Add a discussion.
2038          $record = array();
2039          $record['course'] = $course->id;
2040          $record['forum'] = $forum->id;
2041          $record['userid'] = $user->id;
2042          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2043  
2044          // Add a post.
2045          $record = array();
2046          $record['discussion'] = $discussion->id;
2047          $record['userid'] = $user->id;
2048          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2049  
2050          // The user is not subscribed to the forum. Insert a new discussion subscription.
2051          $subscription = new \stdClass();
2052          $subscription->userid  = $user->id;
2053          $subscription->forum = $forum->id;
2054          $subscription->discussion = $discussion->id;
2055          $subscription->preference = time();
2056  
2057          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2058  
2059          $context = \context_module::instance($forum->cmid);
2060  
2061          $params = array(
2062              'context' => \context_course::instance($course->id),
2063              'objectid' => $subscription->id,
2064              'relateduserid' => $user->id,
2065              'other' => array(
2066                  'forumid' => $forum->id,
2067                  'discussion' => $discussion->id,
2068              )
2069          );
2070  
2071          // Without an invalid context.
2072          $this->expectException(\coding_exception::class);
2073          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
2074          \mod_forum\event\discussion_subscription_created::create($params);
2075      }
2076  
2077      /**
2078       * Test discussion validation of discussion_subscription_created event.
2079       */
2080      public function test_discussion_subscription_created_validation_discussion() {
2081          global $CFG, $DB;
2082          require_once($CFG->dirroot . '/mod/forum/lib.php');
2083  
2084          // Setup test data.
2085          $course = $this->getDataGenerator()->create_course();
2086          $user = $this->getDataGenerator()->create_user();
2087          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2088  
2089          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2090          $forum = $this->getDataGenerator()->create_module('forum', $options);
2091  
2092          // Add a discussion.
2093          $record = array();
2094          $record['course'] = $course->id;
2095          $record['forum'] = $forum->id;
2096          $record['userid'] = $user->id;
2097          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2098  
2099          // Add a post.
2100          $record = array();
2101          $record['discussion'] = $discussion->id;
2102          $record['userid'] = $user->id;
2103          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2104  
2105          // The user is not subscribed to the forum. Insert a new discussion subscription.
2106          $subscription = new \stdClass();
2107          $subscription->userid  = $user->id;
2108          $subscription->forum = $forum->id;
2109          $subscription->discussion = $discussion->id;
2110          $subscription->preference = time();
2111  
2112          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2113  
2114          // Without the discussion.
2115          $params = array(
2116              'context' => \context_module::instance($forum->cmid),
2117              'objectid' => $subscription->id,
2118              'relateduserid' => $user->id,
2119              'other' => array(
2120                  'forumid' => $forum->id,
2121              )
2122          );
2123  
2124          $this->expectException(\coding_exception::class);
2125          $this->expectExceptionMessage("The 'discussion' value must be set in other.");
2126          \mod_forum\event\discussion_subscription_created::create($params);
2127      }
2128  
2129      /**
2130       * Test forumid validation of discussion_subscription_created event.
2131       */
2132      public function test_discussion_subscription_created_validation_forumid() {
2133          global $CFG, $DB;
2134          require_once($CFG->dirroot . '/mod/forum/lib.php');
2135  
2136          // Setup test data.
2137          $course = $this->getDataGenerator()->create_course();
2138          $user = $this->getDataGenerator()->create_user();
2139          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2140  
2141          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2142          $forum = $this->getDataGenerator()->create_module('forum', $options);
2143  
2144          // Add a discussion.
2145          $record = array();
2146          $record['course'] = $course->id;
2147          $record['forum'] = $forum->id;
2148          $record['userid'] = $user->id;
2149          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2150  
2151          // Add a post.
2152          $record = array();
2153          $record['discussion'] = $discussion->id;
2154          $record['userid'] = $user->id;
2155          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2156  
2157          // The user is not subscribed to the forum. Insert a new discussion subscription.
2158          $subscription = new \stdClass();
2159          $subscription->userid  = $user->id;
2160          $subscription->forum = $forum->id;
2161          $subscription->discussion = $discussion->id;
2162          $subscription->preference = time();
2163  
2164          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2165  
2166          // Without the forumid.
2167          $params = array(
2168              'context' => \context_module::instance($forum->cmid),
2169              'objectid' => $subscription->id,
2170              'relateduserid' => $user->id,
2171              'other' => array(
2172                  'discussion' => $discussion->id,
2173              )
2174          );
2175  
2176          $this->expectException(\coding_exception::class);
2177          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
2178          \mod_forum\event\discussion_subscription_created::create($params);
2179      }
2180  
2181      /**
2182       * Test relateduserid validation of discussion_subscription_created event.
2183       */
2184      public function test_discussion_subscription_created_validation_relateduserid() {
2185          global $CFG, $DB;
2186          require_once($CFG->dirroot . '/mod/forum/lib.php');
2187  
2188          // Setup test data.
2189          $course = $this->getDataGenerator()->create_course();
2190          $user = $this->getDataGenerator()->create_user();
2191          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2192  
2193          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2194          $forum = $this->getDataGenerator()->create_module('forum', $options);
2195  
2196          // Add a discussion.
2197          $record = array();
2198          $record['course'] = $course->id;
2199          $record['forum'] = $forum->id;
2200          $record['userid'] = $user->id;
2201          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2202  
2203          // Add a post.
2204          $record = array();
2205          $record['discussion'] = $discussion->id;
2206          $record['userid'] = $user->id;
2207          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2208  
2209          // The user is not subscribed to the forum. Insert a new discussion subscription.
2210          $subscription = new \stdClass();
2211          $subscription->userid  = $user->id;
2212          $subscription->forum = $forum->id;
2213          $subscription->discussion = $discussion->id;
2214          $subscription->preference = time();
2215  
2216          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2217  
2218          $context = \context_module::instance($forum->cmid);
2219  
2220          // Without the relateduserid.
2221          $params = array(
2222              'context' => \context_module::instance($forum->cmid),
2223              'objectid' => $subscription->id,
2224              'other' => array(
2225                  'forumid' => $forum->id,
2226                  'discussion' => $discussion->id,
2227              )
2228          );
2229  
2230          $this->expectException(\coding_exception::class);
2231          $this->expectExceptionMessage("The 'relateduserid' must be set.");
2232          \mod_forum\event\discussion_subscription_created::create($params);
2233      }
2234  
2235      /**
2236       * Test discussion_subscription_deleted event.
2237       */
2238      public function test_discussion_subscription_deleted() {
2239          global $CFG;
2240          require_once($CFG->dirroot . '/mod/forum/lib.php');
2241  
2242          // Setup test data.
2243          $course = $this->getDataGenerator()->create_course();
2244          $user = $this->getDataGenerator()->create_user();
2245          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2246  
2247          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
2248          $forum = $this->getDataGenerator()->create_module('forum', $options);
2249  
2250          // Add a discussion.
2251          $record = array();
2252          $record['course'] = $course->id;
2253          $record['forum'] = $forum->id;
2254          $record['userid'] = $user->id;
2255          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2256  
2257          // Add a post.
2258          $record = array();
2259          $record['discussion'] = $discussion->id;
2260          $record['userid'] = $user->id;
2261          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2262  
2263          // Trigger and capturing the event.
2264          $sink = $this->redirectEvents();
2265  
2266          // Trigger the event by unsubscribing the user to the forum discussion.
2267          \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
2268  
2269          $events = $sink->get_events();
2270          $this->assertCount(1, $events);
2271          $event = reset($events);
2272  
2273          // Checking that the event contains the expected values.
2274          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_deleted', $event);
2275  
2276          $cm = get_coursemodule_from_instance('forum', $discussion->forum);
2277          $context = \context_module::instance($cm->id);
2278          $this->assertEquals($context, $event->get_context());
2279  
2280          $url = new \moodle_url('/mod/forum/subscribe.php', array(
2281              'id' => $forum->id,
2282              'd' => $discussion->id
2283          ));
2284  
2285          $this->assertEquals($url, $event->get_url());
2286          $this->assertEventContextNotUsed($event);
2287          $this->assertNotEmpty($event->get_name());
2288      }
2289  
2290      /**
2291       * Test validation of discussion_subscription_deleted event.
2292       */
2293      public function test_discussion_subscription_deleted_validation() {
2294          global $CFG, $DB;
2295          require_once($CFG->dirroot . '/mod/forum/lib.php');
2296  
2297          // Setup test data.
2298          $course = $this->getDataGenerator()->create_course();
2299          $user = $this->getDataGenerator()->create_user();
2300          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2301  
2302          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
2303          $forum = $this->getDataGenerator()->create_module('forum', $options);
2304  
2305          // Add a discussion.
2306          $record = array();
2307          $record['course'] = $course->id;
2308          $record['forum'] = $forum->id;
2309          $record['userid'] = $user->id;
2310          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2311  
2312          // Add a post.
2313          $record = array();
2314          $record['discussion'] = $discussion->id;
2315          $record['userid'] = $user->id;
2316          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2317  
2318          // The user is not subscribed to the forum. Insert a new discussion subscription.
2319          $subscription = new \stdClass();
2320          $subscription->userid  = $user->id;
2321          $subscription->forum = $forum->id;
2322          $subscription->discussion = $discussion->id;
2323          $subscription->preference = \mod_forum\subscriptions::FORUM_DISCUSSION_UNSUBSCRIBED;
2324  
2325          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2326  
2327          $context = \context_module::instance($forum->cmid);
2328  
2329          $params = array(
2330              'context' => $context,
2331              'objectid' => $subscription->id,
2332              'relateduserid' => $user->id,
2333              'other' => array(
2334                  'forumid' => $forum->id,
2335                  'discussion' => $discussion->id,
2336              )
2337          );
2338  
2339          $event = \mod_forum\event\discussion_subscription_deleted::create($params);
2340  
2341          // Trigger and capturing the event.
2342          $sink = $this->redirectEvents();
2343          $event->trigger();
2344          $events = $sink->get_events();
2345          $this->assertCount(1, $events);
2346          $event = reset($events);
2347  
2348          // Without an invalid context.
2349          $params['context'] = \context_course::instance($course->id);
2350          $this->expectException('coding_exception');
2351          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
2352          \mod_forum\event\discussion_deleted::create($params);
2353  
2354          // Without the discussion.
2355          unset($params['discussion']);
2356          $this->expectException('coding_exception');
2357          $this->expectExceptionMessage('The \'discussion\' value must be set in other.');
2358          \mod_forum\event\discussion_deleted::create($params);
2359  
2360          // Without the forumid.
2361          unset($params['forumid']);
2362          $this->expectException('coding_exception');
2363          $this->expectExceptionMessage('The \'forumid\' value must be set in other.');
2364          \mod_forum\event\discussion_deleted::create($params);
2365  
2366          // Without the relateduserid.
2367          unset($params['relateduserid']);
2368          $this->expectException('coding_exception');
2369          $this->expectExceptionMessage('The \'relateduserid\' value must be set in other.');
2370          \mod_forum\event\discussion_deleted::create($params);
2371      }
2372  
2373      /**
2374       * Test contextlevel validation of discussion_subscription_deleted event.
2375       */
2376      public function test_discussion_subscription_deleted_validation_contextlevel() {
2377          global $CFG, $DB;
2378          require_once($CFG->dirroot . '/mod/forum/lib.php');
2379  
2380          // Setup test data.
2381          $course = $this->getDataGenerator()->create_course();
2382          $user = $this->getDataGenerator()->create_user();
2383          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2384  
2385          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2386          $forum = $this->getDataGenerator()->create_module('forum', $options);
2387  
2388          // Add a discussion.
2389          $record = array();
2390          $record['course'] = $course->id;
2391          $record['forum'] = $forum->id;
2392          $record['userid'] = $user->id;
2393          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2394  
2395          // Add a post.
2396          $record = array();
2397          $record['discussion'] = $discussion->id;
2398          $record['userid'] = $user->id;
2399          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2400  
2401          // The user is not subscribed to the forum. Insert a new discussion subscription.
2402          $subscription = new \stdClass();
2403          $subscription->userid  = $user->id;
2404          $subscription->forum = $forum->id;
2405          $subscription->discussion = $discussion->id;
2406          $subscription->preference = time();
2407  
2408          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2409  
2410          $context = \context_module::instance($forum->cmid);
2411  
2412          $params = array(
2413              'context' => \context_course::instance($course->id),
2414              'objectid' => $subscription->id,
2415              'relateduserid' => $user->id,
2416              'other' => array(
2417                  'forumid' => $forum->id,
2418                  'discussion' => $discussion->id,
2419              )
2420          );
2421  
2422          // Without an invalid context.
2423          $this->expectException(\coding_exception::class);
2424          $this->expectExceptionMessage('Context level must be CONTEXT_MODULE.');
2425          \mod_forum\event\discussion_subscription_deleted::create($params);
2426      }
2427  
2428      /**
2429       * Test discussion validation of discussion_subscription_deleted event.
2430       */
2431      public function test_discussion_subscription_deleted_validation_discussion() {
2432          global $CFG, $DB;
2433          require_once($CFG->dirroot . '/mod/forum/lib.php');
2434  
2435          // Setup test data.
2436          $course = $this->getDataGenerator()->create_course();
2437          $user = $this->getDataGenerator()->create_user();
2438          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2439  
2440          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2441          $forum = $this->getDataGenerator()->create_module('forum', $options);
2442  
2443          // Add a discussion.
2444          $record = array();
2445          $record['course'] = $course->id;
2446          $record['forum'] = $forum->id;
2447          $record['userid'] = $user->id;
2448          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2449  
2450          // Add a post.
2451          $record = array();
2452          $record['discussion'] = $discussion->id;
2453          $record['userid'] = $user->id;
2454          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2455  
2456          // The user is not subscribed to the forum. Insert a new discussion subscription.
2457          $subscription = new \stdClass();
2458          $subscription->userid  = $user->id;
2459          $subscription->forum = $forum->id;
2460          $subscription->discussion = $discussion->id;
2461          $subscription->preference = time();
2462  
2463          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2464  
2465          // Without the discussion.
2466          $params = array(
2467              'context' => \context_module::instance($forum->cmid),
2468              'objectid' => $subscription->id,
2469              'relateduserid' => $user->id,
2470              'other' => array(
2471                  'forumid' => $forum->id,
2472              )
2473          );
2474  
2475          $this->expectException(\coding_exception::class);
2476          $this->expectExceptionMessage("The 'discussion' value must be set in other.");
2477          \mod_forum\event\discussion_subscription_deleted::create($params);
2478      }
2479  
2480      /**
2481       * Test forumid validation of discussion_subscription_deleted event.
2482       */
2483      public function test_discussion_subscription_deleted_validation_forumid() {
2484          global $CFG, $DB;
2485          require_once($CFG->dirroot . '/mod/forum/lib.php');
2486  
2487          // Setup test data.
2488          $course = $this->getDataGenerator()->create_course();
2489          $user = $this->getDataGenerator()->create_user();
2490          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2491  
2492          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2493          $forum = $this->getDataGenerator()->create_module('forum', $options);
2494  
2495          // Add a discussion.
2496          $record = array();
2497          $record['course'] = $course->id;
2498          $record['forum'] = $forum->id;
2499          $record['userid'] = $user->id;
2500          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2501  
2502          // Add a post.
2503          $record = array();
2504          $record['discussion'] = $discussion->id;
2505          $record['userid'] = $user->id;
2506          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2507  
2508          // The user is not subscribed to the forum. Insert a new discussion subscription.
2509          $subscription = new \stdClass();
2510          $subscription->userid  = $user->id;
2511          $subscription->forum = $forum->id;
2512          $subscription->discussion = $discussion->id;
2513          $subscription->preference = time();
2514  
2515          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2516  
2517          // Without the forumid.
2518          $params = array(
2519              'context' => \context_module::instance($forum->cmid),
2520              'objectid' => $subscription->id,
2521              'relateduserid' => $user->id,
2522              'other' => array(
2523                  'discussion' => $discussion->id,
2524              )
2525          );
2526  
2527          $this->expectException(\coding_exception::class);
2528          $this->expectExceptionMessage("The 'forumid' value must be set in other.");
2529          \mod_forum\event\discussion_subscription_deleted::create($params);
2530      }
2531  
2532      /**
2533       * Test relateduserid validation of discussion_subscription_deleted event.
2534       */
2535      public function test_discussion_subscription_deleted_validation_relateduserid() {
2536          global $CFG, $DB;
2537          require_once($CFG->dirroot . '/mod/forum/lib.php');
2538  
2539          // Setup test data.
2540          $course = $this->getDataGenerator()->create_course();
2541          $user = $this->getDataGenerator()->create_user();
2542          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2543  
2544          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2545          $forum = $this->getDataGenerator()->create_module('forum', $options);
2546  
2547          // Add a discussion.
2548          $record = array();
2549          $record['course'] = $course->id;
2550          $record['forum'] = $forum->id;
2551          $record['userid'] = $user->id;
2552          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2553  
2554          // Add a post.
2555          $record = array();
2556          $record['discussion'] = $discussion->id;
2557          $record['userid'] = $user->id;
2558          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2559  
2560          // The user is not subscribed to the forum. Insert a new discussion subscription.
2561          $subscription = new \stdClass();
2562          $subscription->userid  = $user->id;
2563          $subscription->forum = $forum->id;
2564          $subscription->discussion = $discussion->id;
2565          $subscription->preference = time();
2566  
2567          $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription);
2568  
2569          $context = \context_module::instance($forum->cmid);
2570  
2571          // Without the relateduserid.
2572          $params = array(
2573              'context' => \context_module::instance($forum->cmid),
2574              'objectid' => $subscription->id,
2575              'other' => array(
2576                  'forumid' => $forum->id,
2577                  'discussion' => $discussion->id,
2578              )
2579          );
2580  
2581          $this->expectException(\coding_exception::class);
2582          $this->expectExceptionMessage("The 'relateduserid' must be set.");
2583          \mod_forum\event\discussion_subscription_deleted::create($params);
2584      }
2585  
2586      /**
2587       * Test that the correct context is used in the events when subscribing
2588       * users.
2589       */
2590      public function test_forum_subscription_page_context_valid() {
2591          global $CFG, $PAGE;
2592          require_once($CFG->dirroot . '/mod/forum/lib.php');
2593  
2594          // Setup test data.
2595          $course = $this->getDataGenerator()->create_course();
2596          $user = $this->getDataGenerator()->create_user();
2597          $this->getDataGenerator()->enrol_user($user->id, $course->id);
2598  
2599          $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
2600          $forum = $this->getDataGenerator()->create_module('forum', $options);
2601          $quiz = $this->getDataGenerator()->create_module('quiz', $options);
2602  
2603          // Add a discussion.
2604          $record = array();
2605          $record['course'] = $course->id;
2606          $record['forum'] = $forum->id;
2607          $record['userid'] = $user->id;
2608          $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2609  
2610          // Add a post.
2611          $record = array();
2612          $record['discussion'] = $discussion->id;
2613          $record['userid'] = $user->id;
2614          $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
2615  
2616          // Set up the default page event to use this forum.
2617          $PAGE = new \moodle_page();
2618          $cm = get_coursemodule_from_instance('forum', $discussion->forum);
2619          $context = \context_module::instance($cm->id);
2620          $PAGE->set_context($context);
2621          $PAGE->set_cm($cm, $course, $forum);
2622  
2623          // Trigger and capturing the event.
2624          $sink = $this->redirectEvents();
2625  
2626          // Trigger the event by subscribing the user to the forum.
2627          \mod_forum\subscriptions::subscribe_user($user->id, $forum);
2628  
2629          $events = $sink->get_events();
2630          $sink->clear();
2631          $this->assertCount(1, $events);
2632          $event = reset($events);
2633  
2634          // Checking that the event contains the expected values.
2635          $this->assertInstanceOf('\mod_forum\event\subscription_created', $event);
2636          $this->assertEquals($context, $event->get_context());
2637  
2638          // Trigger the event by unsubscribing the user to the forum.
2639          \mod_forum\subscriptions::unsubscribe_user($user->id, $forum);
2640  
2641          $events = $sink->get_events();
2642          $sink->clear();
2643          $this->assertCount(1, $events);
2644          $event = reset($events);
2645  
2646          // Checking that the event contains the expected values.
2647          $this->assertInstanceOf('\mod_forum\event\subscription_deleted', $event);
2648          $this->assertEquals($context, $event->get_context());
2649  
2650          // Trigger the event by subscribing the user to the discussion.
2651          \mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion);
2652  
2653          $events = $sink->get_events();
2654          $sink->clear();
2655          $this->assertCount(1, $events);
2656          $event = reset($events);
2657  
2658          // Checking that the event contains the expected values.
2659          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_created', $event);
2660          $this->assertEquals($context, $event->get_context());
2661  
2662          // Trigger the event by unsubscribing the user from the discussion.
2663          \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
2664  
2665          $events = $sink->get_events();
2666          $sink->clear();
2667          $this->assertCount(1, $events);
2668          $event = reset($events);
2669  
2670          // Checking that the event contains the expected values.
2671          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_deleted', $event);
2672          $this->assertEquals($context, $event->get_context());
2673  
2674          // Now try with the context for a different module (quiz).
2675          $PAGE = new \moodle_page();
2676          $cm = get_coursemodule_from_instance('quiz', $quiz->id);
2677          $quizcontext = \context_module::instance($cm->id);
2678          $PAGE->set_context($quizcontext);
2679          $PAGE->set_cm($cm, $course, $quiz);
2680  
2681          // Trigger and capturing the event.
2682          $sink = $this->redirectEvents();
2683  
2684          // Trigger the event by subscribing the user to the forum.
2685          \mod_forum\subscriptions::subscribe_user($user->id, $forum);
2686  
2687          $events = $sink->get_events();
2688          $sink->clear();
2689          $this->assertCount(1, $events);
2690          $event = reset($events);
2691  
2692          // Checking that the event contains the expected values.
2693          $this->assertInstanceOf('\mod_forum\event\subscription_created', $event);
2694          $this->assertEquals($context, $event->get_context());
2695  
2696          // Trigger the event by unsubscribing the user to the forum.
2697          \mod_forum\subscriptions::unsubscribe_user($user->id, $forum);
2698  
2699          $events = $sink->get_events();
2700          $sink->clear();
2701          $this->assertCount(1, $events);
2702          $event = reset($events);
2703  
2704          // Checking that the event contains the expected values.
2705          $this->assertInstanceOf('\mod_forum\event\subscription_deleted', $event);
2706          $this->assertEquals($context, $event->get_context());
2707  
2708          // Trigger the event by subscribing the user to the discussion.
2709          \mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion);
2710  
2711          $events = $sink->get_events();
2712          $sink->clear();
2713          $this->assertCount(1, $events);
2714          $event = reset($events);
2715  
2716          // Checking that the event contains the expected values.
2717          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_created', $event);
2718          $this->assertEquals($context, $event->get_context());
2719  
2720          // Trigger the event by unsubscribing the user from the discussion.
2721          \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
2722  
2723          $events = $sink->get_events();
2724          $sink->clear();
2725          $this->assertCount(1, $events);
2726          $event = reset($events);
2727  
2728          // Checking that the event contains the expected values.
2729          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_deleted', $event);
2730          $this->assertEquals($context, $event->get_context());
2731  
2732          // Now try with the course context - the module context should still be used.
2733          $PAGE = new \moodle_page();
2734          $coursecontext = \context_course::instance($course->id);
2735          $PAGE->set_context($coursecontext);
2736  
2737          // Trigger the event by subscribing the user to the forum.
2738          \mod_forum\subscriptions::subscribe_user($user->id, $forum);
2739  
2740          $events = $sink->get_events();
2741          $sink->clear();
2742          $this->assertCount(1, $events);
2743          $event = reset($events);
2744  
2745          // Checking that the event contains the expected values.
2746          $this->assertInstanceOf('\mod_forum\event\subscription_created', $event);
2747          $this->assertEquals($context, $event->get_context());
2748  
2749          // Trigger the event by unsubscribing the user to the forum.
2750          \mod_forum\subscriptions::unsubscribe_user($user->id, $forum);
2751  
2752          $events = $sink->get_events();
2753          $sink->clear();
2754          $this->assertCount(1, $events);
2755          $event = reset($events);
2756  
2757          // Checking that the event contains the expected values.
2758          $this->assertInstanceOf('\mod_forum\event\subscription_deleted', $event);
2759          $this->assertEquals($context, $event->get_context());
2760  
2761          // Trigger the event by subscribing the user to the discussion.
2762          \mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion);
2763  
2764          $events = $sink->get_events();
2765          $sink->clear();
2766          $this->assertCount(1, $events);
2767          $event = reset($events);
2768  
2769          // Checking that the event contains the expected values.
2770          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_created', $event);
2771          $this->assertEquals($context, $event->get_context());
2772  
2773          // Trigger the event by unsubscribing the user from the discussion.
2774          \mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion);
2775  
2776          $events = $sink->get_events();
2777          $sink->clear();
2778          $this->assertCount(1, $events);
2779          $event = reset($events);
2780  
2781          // Checking that the event contains the expected values.
2782          $this->assertInstanceOf('\mod_forum\event\discussion_subscription_deleted', $event);
2783          $this->assertEquals($context, $event->get_context());
2784  
2785      }
2786  
2787      /**
2788       * Test mod_forum_observer methods.
2789       */
2790      public function test_observers() {
2791          global $DB, $CFG;
2792  
2793          require_once($CFG->dirroot . '/mod/forum/lib.php');
2794  
2795          $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
2796  
2797          $course = $this->getDataGenerator()->create_course();
2798          $trackedrecord = array('course' => $course->id, 'type' => 'general', 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
2799          $untrackedrecord = array('course' => $course->id, 'type' => 'general');
2800          $trackedforum = $this->getDataGenerator()->create_module('forum', $trackedrecord);
2801          $untrackedforum = $this->getDataGenerator()->create_module('forum', $untrackedrecord);
2802  
2803          // Used functions don't require these settings; adding
2804          // them just in case there are APIs changes in future.
2805          $user = $this->getDataGenerator()->create_user(array(
2806              'maildigest' => 1,
2807              'trackforums' => 1
2808          ));
2809  
2810          $manplugin = enrol_get_plugin('manual');
2811          $manualenrol = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual'));
2812          $student = $DB->get_record('role', array('shortname' => 'student'));
2813  
2814          // The role_assign observer does it's job adding the forum_subscriptions record.
2815          $manplugin->enrol_user($manualenrol, $user->id, $student->id);
2816  
2817          // They are not required, but in a real environment they are supposed to be required;
2818          // adding them just in case there are APIs changes in future.
2819          set_config('forum_trackingtype', 1);
2820          set_config('forum_trackreadposts', 1);
2821  
2822          $record = array();
2823          $record['course'] = $course->id;
2824          $record['forum'] = $trackedforum->id;
2825          $record['userid'] = $user->id;
2826          $discussion = $forumgen->create_discussion($record);
2827  
2828          $record = array();
2829          $record['discussion'] = $discussion->id;
2830          $record['userid'] = $user->id;
2831          $post = $forumgen->create_post($record);
2832  
2833          forum_tp_add_read_record($user->id, $post->id);
2834          forum_set_user_maildigest($trackedforum, 2, $user);
2835          forum_tp_stop_tracking($untrackedforum->id, $user->id);
2836  
2837          $this->assertEquals(1, $DB->count_records('forum_subscriptions'));
2838          $this->assertEquals(1, $DB->count_records('forum_digests'));
2839          $this->assertEquals(1, $DB->count_records('forum_track_prefs'));
2840          $this->assertEquals(1, $DB->count_records('forum_read'));
2841  
2842          // The course_module_created observer does it's job adding a subscription.
2843          $forumrecord = array('course' => $course->id, 'type' => 'general', 'forcesubscribe' => FORUM_INITIALSUBSCRIBE);
2844          $extraforum = $this->getDataGenerator()->create_module('forum', $forumrecord);
2845          $this->assertEquals(2, $DB->count_records('forum_subscriptions'));
2846  
2847          $manplugin->unenrol_user($manualenrol, $user->id);
2848  
2849          $this->assertEquals(0, $DB->count_records('forum_digests'));
2850          $this->assertEquals(0, $DB->count_records('forum_subscriptions'));
2851          $this->assertEquals(0, $DB->count_records('forum_track_prefs'));
2852          $this->assertEquals(0, $DB->count_records('forum_read'));
2853      }
2854  
2855  }