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_message
  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  require_once($CFG->dirroot . '/message/tests/messagelib_test.php');
  31  
  32  /**
  33   * Class containing the tests for message related events.
  34   *
  35   * @package core_message
  36   * @category test
  37   * @copyright 2014 Mark Nelson <markn@moodle.com>
  38   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  class core_message_events_testcase extends core_message_messagelib_testcase {
  41  
  42      /**
  43       * Test set up.
  44       *
  45       * This is executed before running any test in this file.
  46       */
  47      public function setUp(): void {
  48          $this->resetAfterTest();
  49      }
  50  
  51      /**
  52       * Test the message contact added event.
  53       */
  54      public function test_message_contact_added() {
  55          global $USER;
  56  
  57          // Set this user as the admin.
  58          $this->setAdminUser();
  59  
  60          // Create a user to add to the admin's contact list.
  61          $user = $this->getDataGenerator()->create_user();
  62  
  63          // Trigger and capture the event when adding a contact.
  64          $sink = $this->redirectEvents();
  65          \core_message\api::add_contact($USER->id, $user->id);
  66          $events = $sink->get_events();
  67          $event = reset($events);
  68  
  69          // Check that the event data is valid.
  70          $this->assertInstanceOf('\core\event\message_contact_added', $event);
  71          $this->assertEquals(context_user::instance(2), $event->get_context());
  72          $expected = array(SITEID, 'message', 'add contact', 'index.php?user1=' . $user->id .
  73              '&amp;user2=2', $user->id);
  74          $this->assertEventLegacyLogData($expected, $event);
  75          $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
  76          $this->assertEquals($url, $event->get_url());
  77      }
  78  
  79      /**
  80       * Test the message contact removed event.
  81       */
  82      public function test_message_contact_removed() {
  83          global $USER;
  84  
  85          // Set this user as the admin.
  86          $this->setAdminUser();
  87  
  88          // Create a user to add to the admin's contact list.
  89          $user = $this->getDataGenerator()->create_user();
  90  
  91          // Add the user to the admin's contact list.
  92          \core_message\api::add_contact($USER->id, $user->id);
  93  
  94          // Trigger and capture the event when adding a contact.
  95          $sink = $this->redirectEvents();
  96          \core_message\api::remove_contact($USER->id, $user->id);
  97          $events = $sink->get_events();
  98          $event = reset($events);
  99  
 100          // Check that the event data is valid.
 101          $this->assertInstanceOf('\core\event\message_contact_removed', $event);
 102          $this->assertEquals(context_user::instance(2), $event->get_context());
 103          $expected = array(SITEID, 'message', 'remove contact', 'index.php?user1=' . $user->id .
 104              '&amp;user2=2', $user->id);
 105          $this->assertEventLegacyLogData($expected, $event);
 106          $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
 107          $this->assertEquals($url, $event->get_url());
 108      }
 109  
 110      /**
 111       * Test the message user blocked event.
 112       */
 113      public function test_message_user_blocked() {
 114          global $USER;
 115  
 116          // Set this user as the admin.
 117          $this->setAdminUser();
 118  
 119          // Create a user to add to the admin's contact list.
 120          $user = $this->getDataGenerator()->create_user();
 121  
 122          // Add the user to the admin's contact list.
 123          \core_message\api::add_contact($USER->id, $user->id);
 124  
 125          // Trigger and capture the event when blocking a contact.
 126          $sink = $this->redirectEvents();
 127          \core_message\api::block_user($USER->id, $user->id);
 128          $events = $sink->get_events();
 129          $event = reset($events);
 130  
 131          // Check that the event data is valid.
 132          $this->assertInstanceOf('\core\event\message_user_blocked', $event);
 133          $this->assertEquals(context_user::instance(2), $event->get_context());
 134      }
 135  
 136      /**
 137       * Test the message user unblocked event.
 138       */
 139      public function test_message_user_unblocked() {
 140          global $USER;
 141  
 142          // Set this user as the admin.
 143          $this->setAdminUser();
 144  
 145          // Create a user to add to the admin's contact list.
 146          $user = $this->getDataGenerator()->create_user();
 147  
 148          // Add the user to the admin's contact list.
 149          \core_message\api::add_contact($USER->id, $user->id);
 150  
 151          // Block the user.
 152          \core_message\api::block_user($USER->id, $user->id);
 153          // Make sure that we have 1 blocked user.
 154          $this->assertEquals(1, \core_message\api::count_blocked_users());
 155  
 156          // Trigger and capture the event when unblocking a contact.
 157          $sink = $this->redirectEvents();
 158          \core_message\api::unblock_user($USER->id, $user->id);
 159          $events = $sink->get_events();
 160          $event = reset($events);
 161  
 162          // Check that the event data is valid.
 163          $this->assertInstanceOf('\core\event\message_user_unblocked', $event);
 164          $this->assertEquals(context_user::instance(2), $event->get_context());
 165  
 166          // Make sure that we have no blocked users.
 167          $this->assertEmpty(\core_message\api::count_blocked_users());
 168      }
 169  
 170      /**
 171       * Test the message sent event.
 172       *
 173       * We can not use the message_send() function in the unit test to check that the event was fired as there is a
 174       * conditional check to ensure a fake message is sent during unit tests when calling that particular function.
 175       */
 176      public function test_message_sent() {
 177          $event = \core\event\message_sent::create(array(
 178              'objectid' => 3,
 179              'userid' => 1,
 180              'context'  => context_system::instance(),
 181              'relateduserid' => 2,
 182              'other' => array(
 183                  'courseid' => 4
 184              )
 185          ));
 186  
 187          // Trigger and capturing the event.
 188          $sink = $this->redirectEvents();
 189          $event->trigger();
 190          $events = $sink->get_events();
 191          $event = reset($events);
 192  
 193          // Check that the event data is valid.
 194          $this->assertInstanceOf('\core\event\message_sent', $event);
 195          $this->assertEquals(context_system::instance(), $event->get_context());
 196          $expected = array(SITEID, 'message', 'write', 'index.php?user=1&id=2&history=1#m3', 1);
 197          $this->assertEventLegacyLogData($expected, $event);
 198          $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
 199          $this->assertEquals($url, $event->get_url());
 200          $this->assertEquals(3, $event->objectid);
 201          $this->assertEquals(4, $event->other['courseid']);
 202      }
 203  
 204      public function test_mesage_sent_without_other_courseid() {
 205  
 206          // Creating a message_sent event without other[courseid] leads to exception.
 207          $this->expectException('coding_exception');
 208          $this->expectExceptionMessage('The \'courseid\' value must be set in other');
 209  
 210          $event = \core\event\message_sent::create(array(
 211              'userid' => 1,
 212              'context'  => context_system::instance(),
 213              'relateduserid' => 2,
 214              'other' => array(
 215                  'messageid' => 3,
 216              )
 217          ));
 218      }
 219  
 220      public function test_mesage_sent_via_create_from_ids() {
 221          // Containing courseid.
 222          $event = \core\event\message_sent::create_from_ids(1, 2, 3, 4);
 223  
 224          // Trigger and capturing the event.
 225          $sink = $this->redirectEvents();
 226          $event->trigger();
 227          $events = $sink->get_events();
 228          $event = reset($events);
 229  
 230          // Check that the event data is valid.
 231          $this->assertInstanceOf('\core\event\message_sent', $event);
 232          $this->assertEquals(context_system::instance(), $event->get_context());
 233          $expected = array(SITEID, 'message', 'write', 'index.php?user=1&id=2&history=1#m3', 1);
 234          $this->assertEventLegacyLogData($expected, $event);
 235          $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
 236          $this->assertEquals($url, $event->get_url());
 237          $this->assertEquals(3, $event->objectid);
 238          $this->assertEquals(4, $event->other['courseid']);
 239      }
 240  
 241      /**
 242       * Test the group message sent event.
 243       *
 244       * We can't test events in any testing of the message_send() function as there is a conditional PHPUNIT check in message_send,
 245       * resulting in fake messages being generated and captured under test. As a result, none of the events code, nor message
 246       * processor code is called during testing.
 247       */
 248      public function test_group_message_sent() {
 249          $event = \core\event\group_message_sent::create([
 250              'objectid' => 3,
 251              'userid' => 1,
 252              'context'  => context_system::instance(),
 253              'other' => [
 254                  'courseid' => 4,
 255                  'conversationid' => 54
 256              ]
 257          ]);
 258  
 259          // Trigger and capture the event.
 260          $sink = $this->redirectEvents();
 261          $event->trigger();
 262          $events = $sink->get_events();
 263          $event = reset($events);
 264  
 265          // Check that the event data is valid.
 266          $this->assertInstanceOf('\core\event\group_message_sent', $event);
 267          $this->assertEquals(context_system::instance(), $event->get_context());
 268          $url = new moodle_url('/message/index.php');
 269          $this->assertEquals($url, $event->get_url());
 270          $this->assertEquals(3, $event->objectid);
 271          $this->assertEquals(4, $event->other['courseid']);
 272          $this->assertEquals(54, $event->other['conversationid']);
 273      }
 274  
 275      /**
 276       * Test the group message sent event when created without a courseid.
 277       */
 278      public function test_group_message_sent_without_other_courseid() {
 279          // Creating a message_sent event without other[courseid] leads to exception.
 280          $this->expectException('coding_exception');
 281          $this->expectExceptionMessage('The \'courseid\' value must be set in other');
 282  
 283          $event = \core\event\group_message_sent::create([
 284              'userid' => 1,
 285              'objectid' => 3,
 286              'context'  => context_system::instance(),
 287              'relateduserid' => 2,
 288              'other' => [
 289                  'conversationid' => 34
 290              ]
 291          ]);
 292      }
 293  
 294      /**
 295       * Test the group message sent event when created without a conversationid.
 296       */
 297      public function test_group_message_sent_without_other_conversationid() {
 298          // Creating a message_sent event without other[courseid] leads to exception.
 299          $this->expectException('coding_exception');
 300          $this->expectExceptionMessage('The \'conversationid\' value must be set in other');
 301  
 302          $event = \core\event\group_message_sent::create([
 303              'userid' => 1,
 304              'objectid' => 3,
 305              'context'  => context_system::instance(),
 306              'relateduserid' => 2,
 307              'other' => [
 308                  'courseid' => 44,
 309              ]
 310          ]);
 311      }
 312  
 313      /**
 314       * Test the group message sent event using the create_from_ids() method.
 315       */
 316      public function test_group_message_sent_via_create_from_ids() {
 317          // Fields are: userfromid, conversationid, messageid, courseid.
 318          $event = \core\event\group_message_sent::create_from_ids(1, 2, 3, 4);
 319  
 320          // Trigger and capture the event.
 321          $sink = $this->redirectEvents();
 322          $event->trigger();
 323          $events = $sink->get_events();
 324          $event = reset($events);
 325  
 326          // Check that the event data is valid.
 327          $this->assertInstanceOf('\core\event\group_message_sent', $event);
 328          $this->assertEquals(context_system::instance(), $event->get_context());
 329          $this->assertEquals(new moodle_url('/message/index.php'), $event->get_url());
 330          $this->assertEquals(1, $event->userid);
 331          $this->assertEquals(2, $event->other['conversationid']);
 332          $this->assertEquals(3, $event->objectid);
 333          $this->assertEquals(4, $event->other['courseid']);
 334      }
 335  
 336      /**
 337       * Test the message viewed event.
 338       */
 339      public function test_message_viewed() {
 340          global $DB;
 341  
 342          // Create users to send messages between.
 343          $user1 = $this->getDataGenerator()->create_user();
 344          $user2 = $this->getDataGenerator()->create_user();
 345  
 346          $messageid = $this->send_fake_message($user1, $user2);
 347  
 348          // Trigger and capture the event.
 349          $sink = $this->redirectEvents();
 350          $message = $DB->get_record('messages', ['id' => $messageid]);
 351          \core_message\api::mark_message_as_read($user1->id, $message);
 352          $events = $sink->get_events();
 353          $event = reset($events);
 354  
 355          // Get the usage action.
 356          $mua = $DB->get_record('message_user_actions', ['userid' => $user1->id, 'messageid' => $messageid,
 357              'action' => \core_message\api::MESSAGE_ACTION_READ]);
 358  
 359          // Check that the event data is valid.
 360          $this->assertInstanceOf('\core\event\message_viewed', $event);
 361          $this->assertEquals(context_user::instance($user1->id), $event->get_context());
 362          $this->assertEquals($mua->id, $event->objectid);
 363          $this->assertEquals($messageid, $event->other['messageid']);
 364          $url = new moodle_url('/message/index.php', array('user1' => $event->userid, 'user2' => $event->relateduserid));
 365          $this->assertEquals($url, $event->get_url());
 366      }
 367  
 368      /**
 369       * Test the message deleted event.
 370       */
 371      public function test_message_deleted() {
 372          global $DB, $USER;
 373  
 374          $this->setAdminUser();
 375  
 376          // Create users to send messages between.
 377          $user1 = $this->getDataGenerator()->create_user();
 378          $user2 = $this->getDataGenerator()->create_user();
 379  
 380          $messageid = $this->send_fake_message($user1, $user2);
 381  
 382          // Trigger and capture the event.
 383          $sink = $this->redirectEvents();
 384          \core_message\api::delete_message($user1->id, $messageid);
 385          $events = $sink->get_events();
 386          $event = reset($events);
 387  
 388          // Get the usage action.
 389          $mua = $DB->get_record('message_user_actions', ['userid' => $user1->id, 'messageid' => $messageid,
 390              'action' => \core_message\api::MESSAGE_ACTION_DELETED]);
 391  
 392          // Check that the event data is valid.
 393          $this->assertInstanceOf('\core\event\message_deleted', $event);
 394          $this->assertEquals($USER->id, $event->userid); // The user who deleted it.
 395          $this->assertEquals($user1->id, $event->relateduserid);
 396          $this->assertEquals($mua->id, $event->objectid);
 397          $this->assertEquals($messageid, $event->other['messageid']);
 398  
 399          $this->setUser($user1);
 400  
 401          // Create a read message.
 402          $messageid = $this->send_fake_message($user1, $user2);
 403          $m = $DB->get_record('messages', ['id' => $messageid]);
 404          \core_message\api::mark_message_as_read($user2->id, $m);
 405  
 406          // Trigger and capture the event.
 407          $sink = $this->redirectEvents();
 408          \core_message\api::delete_message($user2->id, $messageid);
 409          $events = $sink->get_events();
 410          $event = reset($events);
 411  
 412          // Get the usage action.
 413          $mua = $DB->get_record('message_user_actions', ['userid' => $user2->id, 'messageid' => $messageid,
 414              'action' => \core_message\api::MESSAGE_ACTION_DELETED]);
 415  
 416          // Check that the event data is valid.
 417          $this->assertInstanceOf('\core\event\message_deleted', $event);
 418          $this->assertEquals($user1->id, $event->userid);
 419          $this->assertEquals($user2->id, $event->relateduserid);
 420          $this->assertEquals($mua->id, $event->objectid);
 421          $this->assertEquals($messageid, $event->other['messageid']);
 422      }
 423  
 424      /**
 425       * Test the message deleted event is fired when deleting a conversation.
 426       */
 427      public function test_message_deleted_whole_conversation() {
 428          global $DB;
 429  
 430          // Create some users.
 431          $user1 = self::getDataGenerator()->create_user();
 432          $user2 = self::getDataGenerator()->create_user();
 433  
 434          // The person doing the deletion.
 435          $this->setUser($user1);
 436  
 437          // Send some messages back and forth.
 438          $time = 1;
 439          $messages = [];
 440          $messages[] = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
 441          $messages[] = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
 442          $messages[] = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
 443          $messages[] = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
 444          $messages[] = $this->send_fake_message($user1, $user2, 'You doing much?', 0, $time + 5);
 445          $messages[] = $this->send_fake_message($user2, $user1, 'Nah', 0, $time + 6);
 446          $messages[] = $this->send_fake_message($user1, $user2, 'You nubz0r!', 0, $time + 7);
 447          $messages[] = $this->send_fake_message($user2, $user1, 'Ouch.', 0, $time + 8);
 448  
 449          // Mark the last 4 messages as read.
 450          $m5 = $DB->get_record('messages', ['id' => $messages[4]]);
 451          $m6 = $DB->get_record('messages', ['id' => $messages[5]]);
 452          $m7 = $DB->get_record('messages', ['id' => $messages[6]]);
 453          $m8 = $DB->get_record('messages', ['id' => $messages[7]]);
 454          \core_message\api::mark_message_as_read($user2->id, $m5);
 455          \core_message\api::mark_message_as_read($user1->id, $m6);
 456          \core_message\api::mark_message_as_read($user2->id, $m7);
 457          \core_message\api::mark_message_as_read($user1->id, $m8);
 458  
 459          // Trigger and capture the event.
 460          $sink = $this->redirectEvents();
 461          $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
 462          \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
 463          $events = $sink->get_events();
 464  
 465          // Get the user actions for the messages deleted by that user.
 466          $muas = $DB->get_records('message_user_actions', ['userid' => $user1->id,
 467              'action' => \core_message\api::MESSAGE_ACTION_DELETED], 'timecreated ASC');
 468          $this->assertCount(8, $muas);
 469  
 470          // Create a list we can use for testing.
 471          $muatest = [];
 472          foreach ($muas as $mua) {
 473              $muatest[$mua->messageid] = $mua;
 474          }
 475  
 476          // Check that there were the correct number of events triggered.
 477          $this->assertEquals(8, count($events));
 478  
 479          // Check that the event data is valid.
 480          $i = 1;
 481          foreach ($events as $event) {
 482              $messageid = $messages[$i - 1];
 483  
 484              $this->assertInstanceOf('\core\event\message_deleted', $event);
 485  
 486              $this->assertEquals($muatest[$messageid]->id, $event->objectid);
 487              $this->assertEquals($user1->id, $event->userid);
 488              $this->assertEquals($user1->id, $event->relateduserid);
 489              $this->assertEquals($messageid, $event->other['messageid']);
 490  
 491              $i++;
 492          }
 493      }
 494  
 495      /**
 496       * Test the notification sent event.
 497       */
 498      public function test_notification_sent() {
 499          // Create a course.
 500          $course = $this->getDataGenerator()->create_course();
 501  
 502          // Create users to send notification between.
 503          $user1 = $this->getDataGenerator()->create_user();
 504          $user2 = $this->getDataGenerator()->create_user();
 505  
 506          // Send a notification.
 507          $notificationid = $this->send_fake_message($user1, $user2, 'Hello world!', 1);
 508  
 509          // Containing courseid.
 510          $event = \core\event\notification_sent::create_from_ids($user1->id, $user2->id, $notificationid, $course->id);
 511  
 512          // Trigger and capturing the event.
 513          $sink = $this->redirectEvents();
 514          $event->trigger();
 515          $events = $sink->get_events();
 516          $event = reset($events);
 517  
 518          // Check that the event data is valid.
 519          $this->assertInstanceOf('\core\event\notification_sent', $event);
 520          $this->assertEquals($notificationid, $event->objectid);
 521          $this->assertEquals($user1->id, $event->userid);
 522          $this->assertEquals($user2->id, $event->relateduserid);
 523          $this->assertEquals(context_system::instance(), $event->get_context());
 524          $this->assertEquals($course->id, $event->other['courseid']);
 525          $url = new moodle_url('/message/output/popup/notifications.php', array('notificationid' => $event->objectid));
 526          $this->assertEquals($url, $event->get_url());
 527      }
 528  
 529      /**
 530       * Test the notification sent event when null passed as course.
 531       */
 532      public function test_notification_sent_with_null_course() {
 533          $event = \core\event\notification_sent::create_from_ids(1, 1, 1, null);
 534  
 535          // Trigger and capture the event.
 536          $sink = $this->redirectEvents();
 537          $event->trigger();
 538          $events = $sink->get_events();
 539          $event = reset($events);
 540  
 541          // Check that the event data is valid.
 542          $this->assertInstanceOf('\core\event\notification_sent', $event);
 543          $this->assertEquals(SITEID, $event->other['courseid']);
 544      }
 545  
 546      /**
 547       * Test the notification viewed event.
 548       */
 549      public function test_notification_viewed() {
 550          global $DB;
 551  
 552          // Create users to send notifications between.
 553          $user1 = $this->getDataGenerator()->create_user();
 554          $user2 = $this->getDataGenerator()->create_user();
 555  
 556          // Send a notification.
 557          $notificationid = $this->send_fake_message($user1, $user2, 'Hello world!', 1);
 558  
 559          // Trigger and capture the event.
 560          $sink = $this->redirectEvents();
 561          $notification = $DB->get_record('notifications', ['id' => $notificationid]);
 562          \core_message\api::mark_notification_as_read($notification);
 563          $events = $sink->get_events();
 564          $event = reset($events);
 565  
 566          // Check that the event data is valid.
 567          $this->assertInstanceOf('\core\event\notification_viewed', $event);
 568          $this->assertEquals($notificationid, $event->objectid);
 569          $this->assertEquals($user2->id, $event->userid);
 570          $this->assertEquals($user1->id, $event->relateduserid);
 571          $this->assertEquals(context_user::instance($user2->id), $event->get_context());
 572          $url = new moodle_url('/message/output/popup/notifications.php', array('notificationid' => $event->objectid));
 573          $this->assertEquals($url, $event->get_url());
 574      }
 575  }