Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 311 and 403] [Versions 400 and 403] [Versions 401 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   * Events tests.
  19   *
  20   * @package    core_blog
  21   * @category   test
  22   * @copyright  2016 Stephen Bourget
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace core_blog\event;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  global $CFG;
  31  require_once($CFG->dirroot . '/blog/locallib.php');
  32  require_once($CFG->dirroot . '/blog/lib.php');
  33  
  34  /**
  35   * Unit tests for the blog events.
  36   *
  37   * @copyright  2016 Stephen Bourget
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class events_test extends \advanced_testcase {
  41  
  42      /** @var $courseid */
  43      private $courseid;
  44  
  45      /** @var $cmid */
  46      private $cmid;
  47  
  48      /** @var $groupid */
  49      private $groupid;
  50  
  51      /** @var $userid */
  52      private $userid;
  53  
  54      /** @var $tagid */
  55      private $tagid;
  56  
  57      /** @var $postid */
  58      private $postid;
  59  
  60      /**
  61       * Setup the tests.
  62       */
  63      protected function setUp(): void {
  64          global $DB;
  65          parent::setUp();
  66  
  67          $this->resetAfterTest();
  68  
  69          // Create default course.
  70          $course = $this->getDataGenerator()->create_course(array('category' => 1, 'shortname' => 'ANON'));
  71          $this->assertNotEmpty($course);
  72          $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id));
  73          $this->assertNotEmpty($page);
  74  
  75          // Create default group.
  76          $group = new \stdClass();
  77          $group->courseid = $course->id;
  78          $group->name = 'ANON';
  79          $group->id = $DB->insert_record('groups', $group);
  80  
  81          // Create default user.
  82          $user = $this->getDataGenerator()->create_user(array(
  83                  'username' => 'testuser',
  84                  'firstname' => 'Jimmy',
  85                  'lastname' => 'Kinnon'
  86          ));
  87  
  88          // Create default tag.
  89          $tag = $this->getDataGenerator()->create_tag(array('userid' => $user->id,
  90              'rawname' => 'Testtagname', 'isstandard' => 1));
  91  
  92          // Create default post.
  93          $post = new \stdClass();
  94          $post->userid = $user->id;
  95          $post->groupid = $group->id;
  96          $post->content = 'test post content text';
  97          $post->module = 'blog';
  98          $post->id = $DB->insert_record('post', $post);
  99  
 100          // Grab important ids.
 101          $this->courseid = $course->id;
 102          $this->cmid = $page->cmid;
 103          $this->groupid  = $group->id;
 104          $this->userid  = $user->id;
 105          $this->tagid  = $tag->id;
 106          $this->postid = $post->id;
 107      }
 108  
 109      /**
 110       * Test various blog related events.
 111       */
 112      public function test_blog_entry_created_event() {
 113          global $USER;
 114  
 115          $this->setAdminUser();
 116          $this->resetAfterTest();
 117  
 118          // Create a blog entry for another user as Admin.
 119          $sink = $this->redirectEvents();
 120          $blog = new \blog_entry();
 121          $blog->subject = "Subject of blog";
 122          $blog->userid = $this->userid;
 123          $states = \blog_entry::get_applicable_publish_states();
 124          $blog->publishstate = reset($states);
 125          $blog->add();
 126          $events = $sink->get_events();
 127          $sink->close();
 128          $event = reset($events);
 129          $sitecontext = \context_system::instance();
 130  
 131          // Validate event data.
 132          $this->assertInstanceOf('\core\event\blog_entry_created', $event);
 133          $url = new \moodle_url('/blog/index.php', array('entryid' => $event->objectid));
 134          $this->assertEquals($url, $event->get_url());
 135          $this->assertEquals($sitecontext->id, $event->contextid);
 136          $this->assertEquals($blog->id, $event->objectid);
 137          $this->assertEquals($USER->id, $event->userid);
 138          $this->assertEquals($this->userid, $event->relateduserid);
 139          $this->assertEquals("post", $event->objecttable);
 140          $this->assertEventContextNotUsed($event);
 141      }
 142  
 143      /**
 144       * Tests for event blog_entry_updated.
 145       */
 146      public function test_blog_entry_updated_event() {
 147          global $USER;
 148  
 149          $this->setAdminUser();
 150          $this->resetAfterTest();
 151          $sitecontext = \context_system::instance();
 152  
 153          // Edit a blog entry as Admin.
 154          $blog = new \blog_entry($this->postid);
 155          $sink = $this->redirectEvents();
 156          $blog->summary_editor = array('text' => 'Something', 'format' => FORMAT_MOODLE);
 157          $blog->edit(array(), null, array(), array());
 158          $events = $sink->get_events();
 159          $event = array_pop($events);
 160          $sink->close();
 161  
 162          // Validate event data.
 163          $this->assertInstanceOf('\core\event\blog_entry_updated', $event);
 164          $url = new \moodle_url('/blog/index.php', array('entryid' => $event->objectid));
 165          $this->assertEquals($url, $event->get_url());
 166          $this->assertEquals($sitecontext->id, $event->contextid);
 167          $this->assertEquals($blog->id, $event->objectid);
 168          $this->assertEquals($USER->id, $event->userid);
 169          $this->assertEquals($this->userid, $event->relateduserid);
 170          $this->assertEquals("post", $event->objecttable);
 171          $this->assertEventContextNotUsed($event);
 172      }
 173  
 174      /**
 175       * Tests for event blog_entry_deleted.
 176       */
 177      public function test_blog_entry_deleted_event() {
 178          global $USER, $DB;
 179  
 180          $this->setAdminUser();
 181          $this->resetAfterTest();
 182          $sitecontext = \context_system::instance();
 183  
 184          // Delete a user blog entry as Admin.
 185          $blog = new \blog_entry($this->postid);
 186          $sink = $this->redirectEvents();
 187          $record = $DB->get_record('post', array('id' => $blog->id));
 188          $blog->delete();
 189          $events = $sink->get_events();
 190          $event = array_pop($events);
 191          $sink->close();
 192  
 193          // Validate event data.
 194          $this->assertInstanceOf('\core\event\blog_entry_deleted', $event);
 195          $this->assertEquals(null, $event->get_url());
 196          $this->assertEquals($sitecontext->id, $event->contextid);
 197          $this->assertEquals($blog->id, $event->objectid);
 198          $this->assertEquals($USER->id, $event->userid);
 199          $this->assertEquals($this->userid, $event->relateduserid);
 200          $this->assertEquals("post", $event->objecttable);
 201          $this->assertEquals($record, $event->get_record_snapshot("post", $blog->id));
 202          $this->assertEventContextNotUsed($event);
 203      }
 204  
 205      /**
 206       * Tests for event blog_association_deleted.
 207       */
 208      public function test_blog_association_deleted_event() {
 209          global $USER;
 210  
 211          $this->setAdminUser();
 212          $this->resetAfterTest();
 213          $sitecontext = \context_system::instance();
 214          $coursecontext = \context_course::instance($this->courseid);
 215          $contextmodule = \context_module::instance($this->cmid);
 216  
 217          // Add blog associations with a course.
 218          $blog = new \blog_entry($this->postid);
 219          $blog->add_association($coursecontext->id);
 220  
 221          $sink = $this->redirectEvents();
 222          $blog->remove_associations();
 223          $events = $sink->get_events();
 224          $event = reset($events);
 225          $sink->close();
 226  
 227          // Validate event data.
 228          $this->assertInstanceOf('\core\event\blog_association_deleted', $event);
 229          $this->assertEquals($sitecontext->id, $event->contextid);
 230          $this->assertEquals($blog->id, $event->other['blogid']);
 231          $this->assertEquals($USER->id, $event->userid);
 232          $this->assertEquals($this->userid, $event->relateduserid);
 233          $this->assertEquals('blog_association', $event->objecttable);
 234  
 235          // Add blog associations with a module.
 236          $blog = new \blog_entry($this->postid);
 237          $blog->add_association($contextmodule->id);
 238          $sink = $this->redirectEvents();
 239          $blog->remove_associations();
 240          $events = $sink->get_events();
 241          $event = reset($events);
 242          $sink->close();
 243  
 244          // Validate event data.
 245          $this->assertEquals($blog->id, $event->other['blogid']);
 246          $this->assertEquals($USER->id, $event->userid);
 247          $this->assertEventContextNotUsed($event);
 248      }
 249  
 250      /**
 251       * Tests for event blog_association_created.
 252       */
 253      public function test_blog_association_created_event() {
 254          global $USER;
 255  
 256          $this->setAdminUser();
 257          $this->resetAfterTest();
 258          $sitecontext = \context_system::instance();
 259          $coursecontext = \context_course::instance($this->courseid);
 260          $contextmodule = \context_module::instance($this->cmid);
 261  
 262          // Add blog associations with a course.
 263          $blog = new \blog_entry($this->postid);
 264          $sink = $this->redirectEvents();
 265          $blog->add_association($coursecontext->id);
 266          $events = $sink->get_events();
 267          $event = reset($events);
 268          $sink->close();
 269  
 270          // Validate event data.
 271          $this->assertInstanceOf('\core\event\blog_association_created', $event);
 272          $this->assertEquals($sitecontext->id, $event->contextid);
 273          $url = new \moodle_url('/blog/index.php', array('entryid' => $event->other['blogid']));
 274          $this->assertEquals($url, $event->get_url());
 275          $this->assertEquals($blog->id, $event->other['blogid']);
 276          $this->assertEquals($this->courseid, $event->other['associateid']);
 277          $this->assertEquals('course', $event->other['associatetype']);
 278          $this->assertEquals($blog->subject, $event->other['subject']);
 279          $this->assertEquals($USER->id, $event->userid);
 280          $this->assertEquals($this->userid, $event->relateduserid);
 281          $this->assertEquals('blog_association', $event->objecttable);
 282  
 283          // Add blog associations with a module.
 284          $blog = new \blog_entry($this->postid);
 285          $sink = $this->redirectEvents();
 286          $blog->add_association($contextmodule->id);
 287          $events = $sink->get_events();
 288          $event = reset($events);
 289          $sink->close();
 290  
 291          // Validate event data.
 292          $this->assertEquals($blog->id, $event->other['blogid']);
 293          $this->assertEquals($this->cmid, $event->other['associateid']);
 294          $this->assertEquals('coursemodule', $event->other['associatetype']);
 295          $this->assertEventContextNotUsed($event);
 296      }
 297  
 298      /**
 299       * Tests for event blog_association_created validations.
 300       */
 301      public function test_blog_association_created_event_validations() {
 302  
 303          $this->resetAfterTest();
 304  
 305           // Make sure associatetype validations work.
 306          try {
 307              \core\event\blog_association_created::create(array(
 308                  'contextid' => 1,
 309                  'objectid' => 3,
 310                  'relateduserid' => 2,
 311                  'other' => array('associateid' => 2 , 'blogid' => 3, 'subject' => 'blog subject')));
 312          } catch (\coding_exception $e) {
 313              $this->assertStringContainsString('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
 314          }
 315          try {
 316              \core\event\blog_association_created::create(array(
 317                  'contextid' => 1,
 318                  'objectid' => 3,
 319                  'relateduserid' => 2,
 320                  'other' => array('associateid' => 2 , 'blogid' => 3, 'associatetype' => 'random', 'subject' => 'blog subject')));
 321          } catch (\coding_exception $e) {
 322              $this->assertStringContainsString('The \'associatetype\' value must be set in other and be a valid type.', $e->getMessage());
 323          }
 324          // Make sure associateid validations work.
 325          try {
 326              \core\event\blog_association_created::create(array(
 327                  'contextid' => 1,
 328                  'objectid' => 3,
 329                  'relateduserid' => 2,
 330                  'other' => array('blogid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
 331          } catch (\coding_exception $e) {
 332              $this->assertStringContainsString('The \'associateid\' value must be set in other.', $e->getMessage());
 333          }
 334          // Make sure blogid validations work.
 335          try {
 336              \core\event\blog_association_created::create(array(
 337                  'contextid' => 1,
 338                  'objectid' => 3,
 339                  'relateduserid' => 2,
 340                  'other' => array('associateid' => 3, 'associatetype' => 'course', 'subject' => 'blog subject')));
 341          } catch (\coding_exception $e) {
 342              $this->assertStringContainsString('The \'blogid\' value must be set in other.', $e->getMessage());
 343          }
 344          // Make sure blogid validations work.
 345          try {
 346              \core\event\blog_association_created::create(array(
 347                  'contextid' => 1,
 348                  'objectid' => 3,
 349                  'relateduserid' => 2,
 350                  'other' => array('blogid' => 3, 'associateid' => 3, 'associatetype' => 'course')));
 351          } catch (\coding_exception $e) {
 352              $this->assertStringContainsString('The \'subject\' value must be set in other.', $e->getMessage());
 353          }
 354      }
 355  
 356      /**
 357       * Tests for event blog_entries_viewed.
 358       */
 359      public function test_blog_entries_viewed_event() {
 360  
 361          $this->setAdminUser();
 362  
 363          $other = array('entryid' => $this->postid, 'tagid' => $this->tagid, 'userid' => $this->userid, 'modid' => $this->cmid,
 364                         'groupid' => $this->groupid, 'courseid' => $this->courseid, 'search' => 'search', 'fromstart' => 2);
 365  
 366          // Trigger event.
 367          $sink = $this->redirectEvents();
 368          $eventparams = array('other' => $other);
 369          $eventinst = \core\event\blog_entries_viewed::create($eventparams);
 370          $eventinst->trigger();
 371          $events = $sink->get_events();
 372          $event = reset($events);
 373          $sink->close();
 374  
 375          // Validate event data.
 376          $url = new \moodle_url('/blog/index.php', $other);
 377          $this->assertEquals($url, $event->get_url());
 378          $this->assertEventContextNotUsed($event);
 379      }
 380  
 381      /**
 382       * Test comment_created event.
 383       */
 384      public function test_blog_comment_created_event() {
 385          global $USER, $CFG;
 386  
 387          $this->setAdminUser();
 388  
 389          require_once($CFG->dirroot . '/comment/lib.php');
 390          $context = \context_user::instance($USER->id);
 391  
 392          $cmt = new \stdClass();
 393          $cmt->context = $context;
 394          $cmt->courseid = $this->courseid;
 395          $cmt->area = 'format_blog';
 396          $cmt->itemid = $this->postid;
 397          $cmt->showcount = 1;
 398          $cmt->component = 'blog';
 399          $manager = new \comment($cmt);
 400  
 401          // Triggering and capturing the event.
 402          $sink = $this->redirectEvents();
 403          $manager->add("New comment");
 404          $events = $sink->get_events();
 405          $this->assertCount(1, $events);
 406          $event = reset($events);
 407  
 408          // Checking that the event contains the expected values.
 409          $this->assertInstanceOf('\core\event\blog_comment_created', $event);
 410          $this->assertEquals($context, $event->get_context());
 411          $this->assertEquals($this->postid, $event->other['itemid']);
 412          $url = new \moodle_url('/blog/index.php', array('entryid' => $this->postid));
 413          $this->assertEquals($url, $event->get_url());
 414          $this->assertEventContextNotUsed($event);
 415      }
 416  
 417      /**
 418       * Test comment_deleted event.
 419       */
 420      public function test_blog_comment_deleted_event() {
 421          global $USER, $CFG;
 422  
 423          $this->setAdminUser();
 424  
 425          require_once($CFG->dirroot . '/comment/lib.php');
 426          $context = \context_user::instance($USER->id);
 427  
 428          $cmt = new \stdClass();
 429          $cmt->context = $context;
 430          $cmt->courseid = $this->courseid;
 431          $cmt->area = 'format_blog';
 432          $cmt->itemid = $this->postid;
 433          $cmt->showcount = 1;
 434          $cmt->component = 'blog';
 435          $manager = new \comment($cmt);
 436          $newcomment = $manager->add("New comment");
 437  
 438          // Triggering and capturing the event.
 439          $sink = $this->redirectEvents();
 440          $manager->delete($newcomment->id);
 441          $events = $sink->get_events();
 442          $this->assertCount(1, $events);
 443          $event = reset($events);
 444  
 445          // Checking that the event contains the expected values.
 446          $this->assertInstanceOf('\core\event\blog_comment_deleted', $event);
 447          $this->assertEquals($context, $event->get_context());
 448          $this->assertEquals($this->postid, $event->other['itemid']);
 449          $url = new \moodle_url('/blog/index.php', array('entryid' => $this->postid));
 450          $this->assertEquals($url, $event->get_url());
 451          $this->assertEventContextNotUsed($event);
 452      }
 453  
 454      /**
 455       * Test external blog added event.
 456       *
 457       * There is no external API for this, so the unit test will simply
 458       * create and trigger the event and ensure data is returned as expected.
 459       */
 460      public function test_external_blog_added_event() {
 461  
 462          // Trigger an event: external blog added.
 463          $eventparams = array(
 464              'context' => $context = \context_system::instance(),
 465              'objectid' => 1001,
 466              'other' => array('url' => 'http://moodle.org')
 467          );
 468  
 469          $event = \core\event\blog_external_added::create($eventparams);
 470          // Trigger and capture the event.
 471          $sink = $this->redirectEvents();
 472          $event->trigger();
 473          $events = $sink->get_events();
 474          $event = reset($events);
 475  
 476          // Check that the event data is valid.
 477          $this->assertInstanceOf('\core\event\blog_external_added', $event);
 478          $this->assertEquals(1001, $event->objectid);
 479          $this->assertEquals('http://moodle.org', $event->other['url']);
 480          $this->assertDebuggingNotCalled();
 481      }
 482  
 483      /**
 484       * Test external blog updated event.
 485       *
 486       * There is no external API for this, so the unit test will simply
 487       * create and trigger the event and ensure data is returned as expected.
 488       */
 489      public function test_external_blog_updated_event() {
 490  
 491          // Trigger an event: external blog updated.
 492          $eventparams = array(
 493              'context' => $context = \context_system::instance(),
 494              'objectid' => 1001,
 495              'other' => array('url' => 'http://moodle.org')
 496          );
 497  
 498          $event = \core\event\blog_external_updated::create($eventparams);
 499          // Trigger and capture the event.
 500          $sink = $this->redirectEvents();
 501          $event->trigger();
 502          $events = $sink->get_events();
 503          $event = reset($events);
 504  
 505          // Check that the event data is valid.
 506          $this->assertInstanceOf('\core\event\blog_external_updated', $event);
 507          $this->assertEquals(1001, $event->objectid);
 508          $this->assertEquals('http://moodle.org', $event->other['url']);
 509          $this->assertDebuggingNotCalled();
 510      }
 511  
 512      /**
 513       * Test external blog removed event.
 514       *
 515       * There is no external API for this, so the unit test will simply
 516       * create and trigger the event and ensure data is returned as expected.
 517       */
 518      public function test_external_blog_removed_event() {
 519  
 520          // Trigger an event: external blog removed.
 521          $eventparams = array(
 522              'context' => $context = \context_system::instance(),
 523              'objectid' => 1001,
 524          );
 525  
 526          $event = \core\event\blog_external_removed::create($eventparams);
 527          // Trigger and capture the event.
 528          $sink = $this->redirectEvents();
 529          $event->trigger();
 530          $events = $sink->get_events();
 531          $event = reset($events);
 532  
 533          // Check that the event data is valid.
 534          $this->assertInstanceOf('\core\event\blog_external_removed', $event);
 535          $this->assertEquals(1001, $event->objectid);
 536          $this->assertDebuggingNotCalled();
 537      }
 538  
 539      /**
 540       * Test external blogs viewed event.
 541       *
 542       * There is no external API for this, so the unit test will simply
 543       * create and trigger the event and ensure data is returned as expected.
 544       */
 545      public function test_external_blogs_viewed_event() {
 546  
 547          // Trigger an event: external blogs viewed.
 548          $eventparams = array(
 549              'context' => $context = \context_system::instance(),
 550          );
 551  
 552          $event = \core\event\blog_external_viewed::create($eventparams);
 553          // Trigger and capture the event.
 554          $sink = $this->redirectEvents();
 555          $event->trigger();
 556          $events = $sink->get_events();
 557          $event = reset($events);
 558  
 559          // Check that the event data is valid.
 560          $this->assertInstanceOf('\core\event\blog_external_viewed', $event);
 561          $this->assertDebuggingNotCalled();
 562      }
 563  }