Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310]

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