Search moodle.org's
Developer Documentation

See Release Notes

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

Differences Between: [Versions 311 and 402] [Versions 400 and 402] [Versions 401 and 402]

   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_tag
  21   * @category test
  22   * @copyright 2014 Mark Nelson <markn@moodle.com>
  23   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace core_tag\event;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  global $CFG;
  31  
  32  // Used to create a wiki page to tag.
  33  require_once($CFG->dirroot . '/mod/wiki/locallib.php');
  34  
  35  class events_test extends \advanced_testcase {
  36  
  37      /**
  38       * Test set up.
  39       *
  40       * This is executed before running any test in this file.
  41       */
  42      public function setUp(): void {
  43          $this->resetAfterTest();
  44      }
  45  
  46      /**
  47       * Test the tag updated event.
  48       */
  49      public function test_tag_updated() {
  50          $this->setAdminUser();
  51  
  52          // Save the system context.
  53          $systemcontext = \context_system::instance();
  54  
  55          // Create a tag we are going to update.
  56          $tag = $this->getDataGenerator()->create_tag();
  57  
  58          // Store the name before we change it.
  59          $oldname = $tag->name;
  60  
  61          // Trigger and capture the event when renaming a tag.
  62          $sink = $this->redirectEvents();
  63          \core_tag_tag::get($tag->id, '*')->update(array('rawname' => 'newname'));
  64          // Update the tag's name since we have renamed it.
  65          $tag->name = 'newname';
  66          $events = $sink->get_events();
  67          $event = reset($events);
  68  
  69          // Check that the event data is valid.
  70          $this->assertInstanceOf('\core\event\tag_updated', $event);
  71          $this->assertEquals($systemcontext, $event->get_context());
  72  
  73          // Trigger and capture the event when setting the type of a tag.
  74          $sink = $this->redirectEvents();
  75          \core_tag_tag::get($tag->id, '*')->update(array('isstandard' => 1));
  76          $events = $sink->get_events();
  77          $event = reset($events);
  78  
  79          // Check that the event data is valid.
  80          $this->assertInstanceOf('\core\event\tag_updated', $event);
  81          $this->assertEquals($systemcontext, $event->get_context());
  82  
  83          // Trigger and capture the event for setting the description of a tag.
  84          $sink = $this->redirectEvents();
  85          \core_tag_tag::get($tag->id, '*')->update(
  86                  array('description' => 'description', 'descriptionformat' => FORMAT_MOODLE));
  87          $events = $sink->get_events();
  88          $event = reset($events);
  89  
  90          // Check that the event data is valid.
  91          $this->assertInstanceOf('\core\event\tag_updated', $event);
  92          $this->assertEquals($systemcontext, $event->get_context());
  93      }
  94  
  95      /**
  96       * Test the tag added event.
  97       */
  98      public function test_tag_added() {
  99          global $DB;
 100  
 101          // Create a course to tag.
 102          $course = $this->getDataGenerator()->create_course();
 103  
 104          // Trigger and capture the event for tagging a course.
 105          $sink = $this->redirectEvents();
 106          \core_tag_tag::set_item_tags('core', 'course', $course->id, \context_course::instance($course->id), array('A tag'));
 107          $events = $sink->get_events();
 108          $event = $events[1];
 109  
 110          // Check that the tag was added to the course and that the event data is valid.
 111          $this->assertEquals(1, $DB->count_records('tag_instance', array('component' => 'core')));
 112          $this->assertInstanceOf('\core\event\tag_added', $event);
 113          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
 114  
 115          // Create a question to tag.
 116          $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
 117          $cat = $questiongenerator->create_question_category();
 118          $question = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
 119  
 120          // Trigger and capture the event for tagging a question.
 121          $this->assertEquals(1, $DB->count_records('tag_instance'));
 122          $sink = $this->redirectEvents();
 123          \core_tag_tag::set_item_tags('core_question', 'question', $question->id,
 124              \context::instance_by_id($cat->contextid), array('A tag'));
 125          $events = $sink->get_events();
 126          $event = reset($events);
 127  
 128          // Check that the tag was added to the question and the event data is valid.
 129          $this->assertEquals(1, $DB->count_records('tag_instance', array('component' => 'core')));
 130          $this->assertInstanceOf('\core\event\tag_added', $event);
 131          $this->assertEquals(\context_system::instance(), $event->get_context());
 132      }
 133  
 134      /**
 135       * Test the tag removed event.
 136       */
 137      public function test_tag_removed() {
 138          global $DB;
 139  
 140          $this->setAdminUser();
 141  
 142          // Create a course to tag.
 143          $course = $this->getDataGenerator()->create_course();
 144  
 145          // Create a wiki page to tag.
 146          $wikigenerator = $this->getDataGenerator()->get_plugin_generator('mod_wiki');
 147          $wiki = $wikigenerator->create_instance(array('course' => $course->id));
 148          $subwikiid = wiki_add_subwiki($wiki->id, 0);
 149          $wikipageid = wiki_create_page($subwikiid, 'Title', FORMAT_HTML, '2');
 150  
 151          // Create the tag.
 152          $tag = $this->getDataGenerator()->create_tag();
 153  
 154          // Assign a tag to a course.
 155          \core_tag_tag::add_item_tag('core', 'course', $course->id, \context_course::instance($course->id), $tag->rawname);
 156  
 157          // Trigger and capture the event for untagging a course.
 158          $sink = $this->redirectEvents();
 159          \core_tag_tag::remove_item_tag('core', 'course', $course->id, $tag->rawname);
 160          $events = $sink->get_events();
 161          $event = reset($events);
 162  
 163          // Check that the tag was removed from the course and the event data is valid.
 164          $this->assertEquals(0, $DB->count_records('tag_instance'));
 165          $this->assertInstanceOf('\core\event\tag_removed', $event);
 166          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
 167  
 168          // Create the tag.
 169          $tag = $this->getDataGenerator()->create_tag();
 170  
 171          // Assign a tag to a wiki this time.
 172          \core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $wikipageid, \context_module::instance($wiki->cmid), $tag->rawname);
 173  
 174          // Trigger and capture the event for deleting this tag instance.
 175          $sink = $this->redirectEvents();
 176          \core_tag_tag::remove_item_tag('mod_wiki', 'wiki_pages', $wikipageid, $tag->rawname);
 177          $events = $sink->get_events();
 178          $event = reset($events);
 179  
 180          // Check that tag was removed from the wiki page and the event data is valid.
 181          $this->assertEquals(0, $DB->count_records('tag_instance'));
 182          $this->assertInstanceOf('\core\event\tag_removed', $event);
 183          $this->assertEquals(\context_module::instance($wiki->cmid), $event->get_context());
 184  
 185          // Create a tag again - the other would have been deleted since there were no more instances associated with it.
 186          $tag = $this->getDataGenerator()->create_tag();
 187  
 188          // Assign a tag to the wiki again.
 189          \core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $wikipageid, \context_module::instance($wiki->cmid), $tag->rawname);
 190  
 191          // Now we want to delete this tag, and because there is only one tag instance
 192          // associated with it, it should get deleted as well.
 193          $sink = $this->redirectEvents();
 194          \core_tag_tag::delete_tags($tag->id);
 195          $events = $sink->get_events();
 196          $event = reset($events);
 197  
 198          // Check that tag was removed from the wiki page and the event data is valid.
 199          $this->assertEquals(0, $DB->count_records('tag_instance'));
 200          $this->assertInstanceOf('\core\event\tag_removed', $event);
 201          $this->assertEquals(\context_module::instance($wiki->cmid), $event->get_context());
 202  
 203          // Create a tag again - the other would have been deleted since there were no more instances associated with it.
 204          $tag = $this->getDataGenerator()->create_tag();
 205  
 206          // Assign a tag to the wiki again.
 207          \core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $wikipageid, \context_module::instance($wiki->cmid), $tag->rawname);
 208  
 209          // Delete all tag instances for this wiki instance.
 210          $sink = $this->redirectEvents();
 211          \core_tag_tag::delete_instances('mod_wiki', 'wiki_pages', \context_module::instance($wiki->cmid)->id);
 212          $events = $sink->get_events();
 213          $event = reset($events);
 214  
 215          // Check that tag was removed from the wiki page and the event data is valid.
 216          $this->assertEquals(0, $DB->count_records('tag_instance'));
 217          $this->assertInstanceOf('\core\event\tag_removed', $event);
 218          $this->assertEquals(\context_module::instance($wiki->cmid), $event->get_context());
 219  
 220          // Create another wiki.
 221          $wiki2 = $wikigenerator->create_instance(array('course' => $course->id));
 222          $subwikiid2 = wiki_add_subwiki($wiki2->id, 0);
 223          $wikipageid2 = wiki_create_page($subwikiid2, 'Title', FORMAT_HTML, '2');
 224  
 225          // Assign a tag to both wiki pages.
 226          \core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $wikipageid, \context_module::instance($wiki->cmid), $tag->rawname);
 227          \core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $wikipageid2, \context_module::instance($wiki2->cmid), $tag->rawname);
 228  
 229          // Now remove all tag_instances associated with all wikis.
 230          $sink = $this->redirectEvents();
 231          \core_tag_tag::delete_instances('mod_wiki');
 232          $events = $sink->get_events();
 233  
 234          // There will be two events - one for each wiki instance removed.
 235          $this->assertCount(2, $events);
 236          $contexts = [\context_module::instance($wiki->cmid), \context_module::instance($wiki2->cmid)];
 237          $this->assertNotEquals($events[0]->contextid, $events[1]->contextid);
 238  
 239          // Check that the tags were removed from the wiki pages.
 240          $this->assertEquals(0, $DB->count_records('tag_instance'));
 241  
 242          // Check the first event data is valid.
 243          $this->assertInstanceOf('\core\event\tag_removed', $events[0]);
 244          $this->assertContains($events[0]->get_context(), $contexts);
 245  
 246          // Check that the second event data is valid.
 247          $this->assertInstanceOf('\core\event\tag_removed', $events[1]);
 248          $this->assertContains($events[1]->get_context(), $contexts);
 249      }
 250  
 251      /**
 252       * Test the tag flagged event.
 253       */
 254      public function test_tag_flagged() {
 255          global $DB;
 256  
 257          $this->setAdminUser();
 258  
 259          // Create tags we are going to flag.
 260          $tag = $this->getDataGenerator()->create_tag();
 261          $tag2 = $this->getDataGenerator()->create_tag();
 262          $tags = array($tag, $tag2);
 263  
 264          // Trigger and capture the event for setting the flag of a tag.
 265          $sink = $this->redirectEvents();
 266          \core_tag_tag::get($tag->id, '*')->flag();
 267          $events = $sink->get_events();
 268          $event = reset($events);
 269  
 270          // Check that the flag was updated.
 271          $tag = $DB->get_record('tag', array('id' => $tag->id));
 272          $this->assertEquals(1, $tag->flag);
 273  
 274          // Check that the event data is valid.
 275          $this->assertInstanceOf('\core\event\tag_flagged', $event);
 276          $this->assertEquals(\context_system::instance(), $event->get_context());
 277  
 278          // Unset the flag for both (though by default tag2 should have been created with 0 already).
 279          foreach ($tags as $t) {
 280              \core_tag_tag::get($t->id, '*')->reset_flag();
 281          }
 282  
 283          // Trigger and capture the event for setting the flag for multiple tags.
 284          $sink = $this->redirectEvents();
 285          foreach ($tags as $t) {
 286              \core_tag_tag::get($t->id, '*')->flag();
 287          }
 288          $events = $sink->get_events();
 289  
 290          // Check that the flags were updated.
 291          $tag = $DB->get_record('tag', array('id' => $tag->id));
 292          $this->assertEquals(1, $tag->flag);
 293          $tag2 = $DB->get_record('tag', array('id' => $tag2->id));
 294          $this->assertEquals(1, $tag2->flag);
 295  
 296          // Confirm the events.
 297          $event = $events[0];
 298          $this->assertInstanceOf('\core\event\tag_flagged', $event);
 299          $this->assertEquals(\context_system::instance(), $event->get_context());
 300  
 301          $event = $events[1];
 302          $this->assertInstanceOf('\core\event\tag_flagged', $event);
 303          $this->assertEquals(\context_system::instance(), $event->get_context());
 304      }
 305  
 306      /**
 307       * Test the tag unflagged event.
 308       */
 309      public function test_tag_unflagged() {
 310          global $DB;
 311  
 312          $this->setAdminUser();
 313  
 314          // Create tags we are going to unflag.
 315          $tag = $this->getDataGenerator()->create_tag();
 316          $tag2 = $this->getDataGenerator()->create_tag();
 317          $tags = array($tag, $tag2);
 318  
 319          // Flag it.
 320          \core_tag_tag::get($tag->id, '*')->flag();
 321  
 322          // Trigger and capture the event for unsetting the flag of a tag.
 323          $sink = $this->redirectEvents();
 324          \core_tag_tag::get($tag->id, '*')->reset_flag();
 325          $events = $sink->get_events();
 326          $event = reset($events);
 327  
 328          // Check that the flag was updated.
 329          $tag = $DB->get_record('tag', array('id' => $tag->id));
 330          $this->assertEquals(0, $tag->flag);
 331  
 332          // Check that the event data is valid.
 333          $this->assertInstanceOf('\core\event\tag_unflagged', $event);
 334          $this->assertEquals(\context_system::instance(), $event->get_context());
 335  
 336          // Set the flag back for both.
 337          foreach ($tags as $t) {
 338              \core_tag_tag::get($t->id, '*')->flag();
 339          }
 340  
 341          // Trigger and capture the event for unsetting the flag for multiple tags.
 342          $sink = $this->redirectEvents();
 343          foreach ($tags as $t) {
 344              \core_tag_tag::get($t->id, '*')->reset_flag();
 345          }
 346          $events = $sink->get_events();
 347  
 348          // Check that the flags were updated.
 349          $tag = $DB->get_record('tag', array('id' => $tag->id));
 350          $this->assertEquals(0, $tag->flag);
 351          $tag2 = $DB->get_record('tag', array('id' => $tag2->id));
 352          $this->assertEquals(0, $tag2->flag);
 353  
 354          // Confirm the events.
 355          $event = $events[0];
 356          $this->assertInstanceOf('\core\event\tag_unflagged', $event);
 357          $this->assertEquals(\context_system::instance(), $event->get_context());
 358  
 359          $event = $events[1];
 360          $this->assertInstanceOf('\core\event\tag_unflagged', $event);
 361          $this->assertEquals(\context_system::instance(), $event->get_context());
 362      }
 363  
 364      /**
 365       * Test the tag deleted event
 366       */
 367      public function test_tag_deleted() {
 368          global $DB;
 369  
 370          $this->setAdminUser();
 371  
 372          // Create a course and a user.
 373          $course = $this->getDataGenerator()->create_course();
 374          $user = $this->getDataGenerator()->create_user();
 375  
 376          // Create tag we are going to delete.
 377          $tag = $this->getDataGenerator()->create_tag();
 378  
 379          // Trigger and capture the event for deleting a tag.
 380          $sink = $this->redirectEvents();
 381          \core_tag_tag::delete_tags($tag->id);
 382          $events = $sink->get_events();
 383          $event = reset($events);
 384  
 385          // Check that the tag was deleted and the event data is valid.
 386          $this->assertEquals(0, $DB->count_records('tag'));
 387          $this->assertInstanceOf('\core\event\tag_deleted', $event);
 388          $this->assertEquals(\context_system::instance(), $event->get_context());
 389  
 390          // Create two tags we are going to delete to ensure passing multiple tags work.
 391          $tag = $this->getDataGenerator()->create_tag();
 392          $tag2 = $this->getDataGenerator()->create_tag();
 393  
 394          // Trigger and capture the events for deleting multiple tags.
 395          $sink = $this->redirectEvents();
 396          \core_tag_tag::delete_tags(array($tag->id, $tag2->id));
 397          $events = $sink->get_events();
 398  
 399          // Check that the tags were deleted and the events data is valid.
 400          $this->assertEquals(0, $DB->count_records('tag'));
 401          foreach ($events as $event) {
 402              $this->assertInstanceOf('\core\event\tag_deleted', $event);
 403              $this->assertEquals(\context_system::instance(), $event->get_context());
 404          }
 405  
 406          // Add a tag instance to a course.
 407          \core_tag_tag::add_item_tag('core', 'course', $course->id, \context_course::instance($course->id), 'cat', $user->id);
 408  
 409          // Trigger and capture the event for deleting a personal tag for a user for a course.
 410          $sink = $this->redirectEvents();
 411          \core_tag_tag::remove_item_tag('core', 'course', $course->id, 'cat', $user->id);
 412          $events = $sink->get_events();
 413          $event = $events[1];
 414  
 415          // Check that the tag was deleted and the event data is valid.
 416          $this->assertEquals(0, $DB->count_records('tag'));
 417          $this->assertInstanceOf('\core\event\tag_deleted', $event);
 418          $this->assertEquals(\context_system::instance(), $event->get_context());
 419  
 420          // Add the tag instance to the course again as it was deleted.
 421          \core_tag_tag::add_item_tag('core', 'course', $course->id, \context_course::instance($course->id), 'dog', $user->id);
 422  
 423          // Trigger and capture the event for deleting all tags in a course.
 424          $sink = $this->redirectEvents();
 425          \core_tag_tag::remove_all_item_tags('core', 'course', $course->id);
 426          $events = $sink->get_events();
 427          $event = $events[1];
 428  
 429          // Check that the tag was deleted and the event data is valid.
 430          $this->assertEquals(0, $DB->count_records('tag'));
 431          $this->assertInstanceOf('\core\event\tag_deleted', $event);
 432          $this->assertEquals(\context_system::instance(), $event->get_context());
 433  
 434          // Add multiple tag instances now and check that it still works.
 435          \core_tag_tag::set_item_tags('core', 'course', $course->id, \context_course::instance($course->id),
 436              array('fish', 'hamster'), $user->id);
 437  
 438          // Trigger and capture the event for deleting all tags in a course.
 439          $sink = $this->redirectEvents();
 440          \core_tag_tag::remove_all_item_tags('core', 'course', $course->id);
 441          $events = $sink->get_events();
 442          $events = array($events[1], $events[3]);
 443  
 444          // Check that the tags were deleted and the events data is valid.
 445          $this->assertEquals(0, $DB->count_records('tag'));
 446          foreach ($events as $event) {
 447              $this->assertInstanceOf('\core\event\tag_deleted', $event);
 448              $this->assertEquals(\context_system::instance(), $event->get_context());
 449          }
 450      }
 451  
 452      /**
 453       * Test the tag created event.
 454       */
 455      public function test_tag_created() {
 456          global $DB;
 457  
 458          // Trigger and capture the event for creating a tag.
 459          $sink = $this->redirectEvents();
 460          \core_tag_tag::create_if_missing(\core_tag_area::get_collection('core', 'course'),
 461                  array('A really awesome tag!'));
 462          $events = $sink->get_events();
 463          $event = reset($events);
 464  
 465          // Check that the tag was created and the event data is valid.
 466          $this->assertEquals(1, $DB->count_records('tag'));
 467          $this->assertInstanceOf('\core\event\tag_created', $event);
 468          $this->assertEquals(\context_system::instance(), $event->get_context());
 469      }
 470  }