Search moodle.org's
Developer Documentation

See Release Notes

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

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

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Privacy provider tests.
  19   *
  20   * @package    core_message
  21   * @copyright  2018 Mark Nelson <markn@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace core_message\privacy;
  25  
  26  use core_privacy\local\metadata\collection;
  27  use core_message\privacy\provider;
  28  use core_privacy\local\request\contextlist;
  29  use core_privacy\local\request\writer;
  30  use core_privacy\local\request\transform;
  31  use core_message\tests\helper as testhelper;
  32  
  33  defined('MOODLE_INTERNAL') || die();
  34  
  35  /**
  36   * Privacy provider tests class.
  37   *
  38   * @package    core_message
  39   * @copyright  2018 Mark Nelson <markn@moodle.com>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class provider_test extends \core_privacy\tests\provider_testcase {
  43  
  44      /**
  45       * Test for provider::get_metadata().
  46       */
  47      public function test_get_metadata() {
  48          $collection = new collection('core_message');
  49          $newcollection = provider::get_metadata($collection);
  50          $itemcollection = $newcollection->get_collection();
  51          $this->assertCount(10, $itemcollection);
  52  
  53          $messagestable = array_shift($itemcollection);
  54          $this->assertEquals('messages', $messagestable->get_name());
  55  
  56          $messageuseractionstable = array_shift($itemcollection);
  57          $this->assertEquals('message_user_actions', $messageuseractionstable->get_name());
  58  
  59          $messageconversationmemberstable = array_shift($itemcollection);
  60          $this->assertEquals('message_conversation_members', $messageconversationmemberstable->get_name());
  61  
  62          $messageconversationactions = array_shift($itemcollection);
  63          $this->assertEquals('message_conversation_actions', $messageconversationactions->get_name());
  64  
  65          $messagecontacts = array_shift($itemcollection);
  66          $this->assertEquals('message_contacts', $messagecontacts->get_name());
  67  
  68          $messagecontactrequests = array_shift($itemcollection);
  69          $this->assertEquals('message_contact_requests', $messagecontactrequests->get_name());
  70  
  71          $messageusersblocked = array_shift($itemcollection);
  72          $this->assertEquals('message_users_blocked', $messageusersblocked->get_name());
  73  
  74          $notificationstable = array_shift($itemcollection);
  75          $this->assertEquals('notifications', $notificationstable->get_name());
  76  
  77          $usersettings = array_shift($itemcollection);
  78          $this->assertEquals('core_message_messageprovider_settings', $usersettings->get_name());
  79  
  80          $favouriteconversations = array_shift($itemcollection);
  81          $this->assertEquals('core_favourites', $favouriteconversations->get_name());
  82          $this->assertEquals('privacy:metadata:core_favourites', $favouriteconversations->get_summary());
  83  
  84          $privacyfields = $messagestable->get_privacy_fields();
  85          $this->assertArrayHasKey('useridfrom', $privacyfields);
  86          $this->assertArrayHasKey('conversationid', $privacyfields);
  87          $this->assertArrayHasKey('subject', $privacyfields);
  88          $this->assertArrayHasKey('fullmessage', $privacyfields);
  89          $this->assertArrayHasKey('fullmessageformat', $privacyfields);
  90          $this->assertArrayHasKey('fullmessagehtml', $privacyfields);
  91          $this->assertArrayHasKey('smallmessage', $privacyfields);
  92          $this->assertArrayHasKey('timecreated', $privacyfields);
  93          $this->assertArrayHasKey('customdata', $privacyfields);
  94          $this->assertEquals('privacy:metadata:messages', $messagestable->get_summary());
  95  
  96          $privacyfields = $messageuseractionstable->get_privacy_fields();
  97          $this->assertArrayHasKey('userid', $privacyfields);
  98          $this->assertArrayHasKey('messageid', $privacyfields);
  99          $this->assertArrayHasKey('action', $privacyfields);
 100          $this->assertArrayHasKey('timecreated', $privacyfields);
 101          $this->assertEquals('privacy:metadata:message_user_actions', $messageuseractionstable->get_summary());
 102  
 103          $privacyfields = $messageconversationmemberstable->get_privacy_fields();
 104          $this->assertArrayHasKey('conversationid', $privacyfields);
 105          $this->assertArrayHasKey('userid', $privacyfields);
 106          $this->assertArrayHasKey('timecreated', $privacyfields);
 107          $this->assertEquals('privacy:metadata:message_conversation_members', $messageconversationmemberstable->get_summary());
 108  
 109          $privacyfields = $messagecontacts->get_privacy_fields();
 110          $this->assertArrayHasKey('userid', $privacyfields);
 111          $this->assertArrayHasKey('contactid', $privacyfields);
 112          $this->assertArrayHasKey('timecreated', $privacyfields);
 113          $this->assertEquals('privacy:metadata:message_contacts', $messagecontacts->get_summary());
 114  
 115          $privacyfields = $messagecontactrequests->get_privacy_fields();
 116          $this->assertArrayHasKey('userid', $privacyfields);
 117          $this->assertArrayHasKey('requesteduserid', $privacyfields);
 118          $this->assertArrayHasKey('timecreated', $privacyfields);
 119          $this->assertEquals('privacy:metadata:message_contact_requests', $messagecontactrequests->get_summary());
 120  
 121          $privacyfields = $messageusersblocked->get_privacy_fields();
 122          $this->assertArrayHasKey('userid', $privacyfields);
 123          $this->assertArrayHasKey('blockeduserid', $privacyfields);
 124          $this->assertArrayHasKey('timecreated', $privacyfields);
 125          $this->assertEquals('privacy:metadata:message_users_blocked', $messageusersblocked->get_summary());
 126  
 127          $privacyfields = $notificationstable->get_privacy_fields();
 128          $this->assertArrayHasKey('useridfrom', $privacyfields);
 129          $this->assertArrayHasKey('useridto', $privacyfields);
 130          $this->assertArrayHasKey('subject', $privacyfields);
 131          $this->assertArrayHasKey('fullmessage', $privacyfields);
 132          $this->assertArrayHasKey('fullmessageformat', $privacyfields);
 133          $this->assertArrayHasKey('fullmessagehtml', $privacyfields);
 134          $this->assertArrayHasKey('smallmessage', $privacyfields);
 135          $this->assertArrayHasKey('component', $privacyfields);
 136          $this->assertArrayHasKey('eventtype', $privacyfields);
 137          $this->assertArrayHasKey('contexturl', $privacyfields);
 138          $this->assertArrayHasKey('contexturlname', $privacyfields);
 139          $this->assertArrayHasKey('timeread', $privacyfields);
 140          $this->assertArrayHasKey('timecreated', $privacyfields);
 141          $this->assertArrayHasKey('customdata', $privacyfields);
 142          $this->assertEquals('privacy:metadata:notifications', $notificationstable->get_summary());
 143      }
 144  
 145      /**
 146       * Test for provider::export_user_preferences().
 147       */
 148      public function test_export_user_preferences_no_pref() {
 149          $this->resetAfterTest();
 150  
 151          $user = $this->getDataGenerator()->create_user();
 152          provider::export_user_preferences($user->id);
 153  
 154          $writer = writer::with_context(\context_system::instance());
 155  
 156          $this->assertFalse($writer->has_any_data());
 157      }
 158  
 159      /**
 160       * Test for provider::export_user_preferences().
 161       */
 162      public function test_export_user_preferences() {
 163          global $USER;
 164  
 165          $this->resetAfterTest();
 166  
 167          $this->setAdminUser();
 168  
 169          // Create another user to set a preference for who we won't be exporting.
 170          $user = $this->getDataGenerator()->create_user();
 171  
 172          // Set some message user preferences.
 173          set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $USER->id);
 174          set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'popup', $USER->id);
 175          set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $USER->id);
 176          set_user_preference('message_entertosend', true, $USER->id);
 177          set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'inbound', $user->id);
 178  
 179          // Set an unrelated preference.
 180          set_user_preference('some_unrelated_preference', 'courses', $USER->id);
 181  
 182          provider::export_user_preferences($USER->id);
 183  
 184          $writer = writer::with_context(\context_system::instance());
 185  
 186          $this->assertTrue($writer->has_any_data());
 187  
 188          $prefs = (array) $writer->get_user_preferences('core_message');
 189  
 190          // Check only 3 preferences exist.
 191          $this->assertCount(4, $prefs);
 192          $this->assertArrayHasKey('message_provider_moodle_instantmessage_loggedin', $prefs);
 193          $this->assertArrayHasKey('message_provider_moodle_instantmessage_loggedoff', $prefs);
 194          $this->assertArrayHasKey('message_blocknoncontacts', $prefs);
 195          $this->assertArrayHasKey('message_entertosend', $prefs);
 196  
 197          foreach ($prefs as $key => $pref) {
 198              if ($key == 'message_provider_moodle_instantmessage_loggedin') {
 199                  $this->assertEquals('airnotifier', $pref->value);
 200              } else if ($key == 'message_provider_moodle_instantmessage_loggedoff') {
 201                  $this->assertEquals('popup', $pref->value);
 202              } else {
 203                  $this->assertEquals(1, $pref->value);
 204              }
 205          }
 206      }
 207  
 208      /**
 209       * Test for provider::get_contexts_for_userid() when there is no message or notification.
 210       */
 211      public function test_get_contexts_for_userid_no_data() {
 212          $this->resetAfterTest();
 213  
 214          $user = $this->getDataGenerator()->create_user();
 215  
 216          $contextlist = provider::get_contexts_for_userid($user->id);
 217          $this->assertCount(1, $contextlist);
 218  
 219          $this->remove_user_self_conversation($user->id);
 220  
 221          $contextlist = provider::get_contexts_for_userid($user->id);
 222          $this->assertEmpty($contextlist);
 223      }
 224  
 225      /**
 226       * Test for provider::get_contexts_for_userid() when there is a private message between users.
 227       */
 228      public function test_get_contexts_for_userid_with_private_messages() {
 229          $this->resetAfterTest();
 230  
 231          $user1 = $this->getDataGenerator()->create_user();
 232          $user2 = $this->getDataGenerator()->create_user();
 233          $user3 = $this->getDataGenerator()->create_user();
 234  
 235          // Remove user self-conversations.
 236          $this->remove_user_self_conversation($user1->id);
 237          $this->remove_user_self_conversation($user2->id);
 238          $this->remove_user_self_conversation($user3->id);
 239  
 240          // Test nothing is found before group conversations is created or message is sent.
 241          $contextlist = provider::get_contexts_for_userid($user1->id);
 242          $this->assertCount(0, $contextlist);
 243          $contextlist = provider::get_contexts_for_userid($user2->id);
 244          $this->assertCount(0, $contextlist);
 245  
 246          // Send some private messages.
 247          $pm1id = $this->create_message($user1->id, $user2->id, time() - (9 * DAYSECS));
 248  
 249          // Test for the sender (user1).
 250          $contextlist = provider::get_contexts_for_userid($user1->id);
 251          $this->assertCount(1, $contextlist);
 252          $contextforuser = $contextlist->current();
 253          $this->assertEquals(
 254                  \context_user::instance($user1->id)->id,
 255                  $contextforuser->id);
 256  
 257          // Test for the receiver (user2).
 258          $contextlist = provider::get_contexts_for_userid($user2->id);
 259          $this->assertCount(1, $contextlist);
 260          $contextforuser = $contextlist->current();
 261          $this->assertEquals(
 262                  \context_user::instance($user2->id)->id,
 263                  $contextforuser->id);
 264  
 265          // Test for user3 (no private messages).
 266          $contextlist = provider::get_contexts_for_userid($user3->id);
 267          $this->assertCount(0, $contextlist);
 268      }
 269  
 270      /**
 271       * Test for provider::get_contexts_for_userid() when there is several messages (private and group).
 272       */
 273      public function test_get_contexts_for_userid_with_messages() {
 274          $this->resetAfterTest();
 275          $this->setAdminUser();
 276  
 277          $user1 = $this->getDataGenerator()->create_user();
 278          $user2 = $this->getDataGenerator()->create_user();
 279          $user3 = $this->getDataGenerator()->create_user();
 280          $user4 = $this->getDataGenerator()->create_user();
 281  
 282          // Remove user self-conversations.
 283          $this->remove_user_self_conversation($user1->id);
 284          $this->remove_user_self_conversation($user2->id);
 285          $this->remove_user_self_conversation($user3->id);
 286          $this->remove_user_self_conversation($user4->id);
 287  
 288          // Test nothing is found before group conversations is created or message is sent.
 289          $contextlist = provider::get_contexts_for_userid($user1->id);
 290          $this->assertCount(0, $contextlist);
 291          $contextlist = provider::get_contexts_for_userid($user2->id);
 292          $this->assertCount(0, $contextlist);
 293  
 294          // Create course.
 295          $course1 = $this->getDataGenerator()->create_course();
 296          $coursecontext1 = \context_course::instance($course1->id);
 297  
 298          // Enrol users to courses.
 299          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
 300          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
 301          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
 302  
 303          // Create groups (only one with enablemessaging = 1).
 304          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
 305  
 306          // Add users to groups.
 307          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
 308          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
 309          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
 310  
 311          // Get conversation.
 312          $component = 'core_group';
 313          $itemtype = 'groups';
 314          $conversation1 = \core_message\api::get_conversation_by_area(
 315              $component,
 316              $itemtype,
 317              $group1a->id,
 318              $coursecontext1->id
 319          );
 320  
 321          // Send some messages to the group conversation.
 322          $now = time();
 323          $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
 324          $m2id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
 325          $m3id = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 3', $now + 3);
 326  
 327          // Test for user1 (although is member of the conversation, hasn't any private message).
 328          $contextlist = provider::get_contexts_for_userid($user1->id);
 329          $this->assertCount(0, $contextlist);
 330  
 331          // Test for user2 (although is member of the conversation, hasn't any private message).
 332          $contextlist = provider::get_contexts_for_userid($user2->id);
 333          $this->assertCount(0, $contextlist);
 334  
 335          // Test for user3 (although is member of the conversation, hasn't any private message).
 336          $contextlist = provider::get_contexts_for_userid($user3->id);
 337          $this->assertCount(0, $contextlist);
 338  
 339          // Test for user4 (doesn't belong to the conversation).
 340          $contextlist = provider::get_contexts_for_userid($user4->id);
 341          $this->assertCount(0, $contextlist);
 342  
 343          // Send some private messages.
 344          $pm1id = $this->create_message($user1->id, $user2->id, time() - (9 * DAYSECS));
 345  
 346          // Test user1 now has the user context because of the private message.
 347          $contextlist = provider::get_contexts_for_userid($user1->id);
 348          $this->assertCount(1, $contextlist);
 349          $contextforuser = $contextlist->current();
 350          $this->assertEquals(
 351                  \context_user::instance($user1->id)->id,
 352                  $contextforuser->id);
 353  
 354          // Test user2 now has the user context because of the private message.
 355          $contextlist = provider::get_contexts_for_userid($user2->id);
 356          $this->assertCount(1, $contextlist);
 357          $contextforuser = $contextlist->current();
 358          $this->assertEquals(
 359                  \context_user::instance($user2->id)->id,
 360                  $contextforuser->id);
 361  
 362          // Test for user3 (although is member of the conversation, hasn't still any private message).
 363          $contextlist = provider::get_contexts_for_userid($user3->id);
 364          $this->assertCount(0, $contextlist);
 365  
 366          // Test for user4 (doesn't belong to the conversation and hasn't any private message).
 367          $contextlist = provider::get_contexts_for_userid($user4->id);
 368          $this->assertCount(0, $contextlist);
 369      }
 370  
 371      /**
 372       * Test for provider::get_contexts_for_userid() when there is a notification between users.
 373       */
 374      public function test_get_contexts_for_userid_with_notification() {
 375          $this->resetAfterTest();
 376  
 377          $user1 = $this->getDataGenerator()->create_user();
 378          $user2 = $this->getDataGenerator()->create_user();
 379  
 380          // Remove user self-conversations.
 381          $this->remove_user_self_conversation($user1->id);
 382          $this->remove_user_self_conversation($user2->id);
 383  
 384          // Test nothing is found before notification is created.
 385          $contextlist = provider::get_contexts_for_userid($user1->id);
 386          $this->assertCount(0, $contextlist);
 387          $contextlist = provider::get_contexts_for_userid($user2->id);
 388          $this->assertCount(0, $contextlist);
 389  
 390          $this->create_notification($user1->id, $user2->id, time() - (9 * DAYSECS));
 391  
 392          // Test for the sender.
 393          $contextlist = provider::get_contexts_for_userid($user1->id);
 394          $this->assertCount(1, $contextlist);
 395          $contextforuser = $contextlist->current();
 396          $this->assertEquals(
 397                  \context_user::instance($user1->id)->id,
 398                  $contextforuser->id);
 399  
 400          // Test for the receiver.
 401          $contextlist = provider::get_contexts_for_userid($user2->id);
 402          $this->assertCount(1, $contextlist);
 403          $contextforuser = $contextlist->current();
 404          $this->assertEquals(
 405                  \context_user::instance($user2->id)->id,
 406                  $contextforuser->id);
 407      }
 408  
 409      /**
 410       * Test for provider::get_contexts_for_userid() when a users has a contact.
 411       */
 412      public function test_get_contexts_for_userid_with_contact() {
 413          $this->resetAfterTest();
 414  
 415          $user1 = $this->getDataGenerator()->create_user();
 416          $user2 = $this->getDataGenerator()->create_user();
 417  
 418          // Remove user self-conversations.
 419          $this->remove_user_self_conversation($user1->id);
 420          $this->remove_user_self_conversation($user2->id);
 421  
 422          // Test nothing is found before contact is created.
 423          $contextlist = provider::get_contexts_for_userid($user1->id);
 424          $this->assertCount(0, $contextlist);
 425          $contextlist = provider::get_contexts_for_userid($user2->id);
 426          $this->assertCount(0, $contextlist);
 427  
 428          \core_message\api::add_contact($user1->id, $user2->id);
 429  
 430          // Test for the user adding the contact.
 431          $contextlist = provider::get_contexts_for_userid($user1->id);
 432          $this->assertCount(1, $contextlist);
 433          $contextforuser = $contextlist->current();
 434          $this->assertEquals(
 435                  \context_user::instance($user1->id)->id,
 436                  $contextforuser->id);
 437  
 438          // Test for the user who is the contact.
 439          $contextlist = provider::get_contexts_for_userid($user2->id);
 440          $this->assertCount(1, $contextlist);
 441          $contextforuser = $contextlist->current();
 442          $this->assertEquals(
 443                  \context_user::instance($user2->id)->id,
 444                  $contextforuser->id);
 445      }
 446  
 447      /**
 448       * Test for provider::get_contexts_for_userid() when a user makes a contact request.
 449       */
 450      public function test_get_contexts_for_userid_with_contact_request() {
 451          $this->resetAfterTest();
 452  
 453          $user1 = $this->getDataGenerator()->create_user();
 454          $user2 = $this->getDataGenerator()->create_user();
 455  
 456          // Remove user self-conversations.
 457          $this->remove_user_self_conversation($user1->id);
 458          $this->remove_user_self_conversation($user2->id);
 459  
 460          // Test nothing is found before request is created.
 461          $contextlist = provider::get_contexts_for_userid($user1->id);
 462          $this->assertCount(0, $contextlist);
 463          $contextlist = provider::get_contexts_for_userid($user2->id);
 464          $this->assertCount(0, $contextlist);
 465  
 466          \core_message\api::create_contact_request($user1->id, $user2->id);
 467  
 468          // Test for the user requesting the contact.
 469          $contextlist = provider::get_contexts_for_userid($user1->id);
 470          $this->assertCount(1, $contextlist);
 471          $contextforuser = $contextlist->current();
 472          $this->assertEquals(
 473                  \context_user::instance($user1->id)->id,
 474                  $contextforuser->id);
 475  
 476          // Test for the user receiving the contact request.
 477          $contextlist = provider::get_contexts_for_userid($user2->id);
 478          $this->assertCount(1, $contextlist);
 479          $contextforuser = $contextlist->current();
 480          $this->assertEquals(
 481                  \context_user::instance($user2->id)->id,
 482                  $contextforuser->id);
 483      }
 484  
 485      /**
 486       * Test for provider::get_contexts_for_userid() when a user is blocked.
 487       */
 488      public function test_get_contexts_for_userid_with_blocked_contact() {
 489          $this->resetAfterTest();
 490  
 491          $user1 = $this->getDataGenerator()->create_user();
 492          $user2 = $this->getDataGenerator()->create_user();
 493  
 494          // Remove user self-conversations.
 495          $this->remove_user_self_conversation($user1->id);
 496          $this->remove_user_self_conversation($user2->id);
 497  
 498          // Test nothing is found before user is blocked.
 499          $contextlist = provider::get_contexts_for_userid($user1->id);
 500          $this->assertCount(0, $contextlist);
 501          $contextlist = provider::get_contexts_for_userid($user2->id);
 502          $this->assertCount(0, $contextlist);
 503  
 504          \core_message\api::block_user($user1->id, $user2->id);
 505  
 506          // Test for the blocking user.
 507          $contextlist = provider::get_contexts_for_userid($user1->id);
 508          $this->assertCount(1, $contextlist);
 509          $contextforuser = $contextlist->current();
 510          $this->assertEquals(
 511                  \context_user::instance($user1->id)->id,
 512                  $contextforuser->id);
 513  
 514          // Test for the user who is blocked.
 515          $contextlist = provider::get_contexts_for_userid($user2->id);
 516          $this->assertCount(1, $contextlist);
 517          $contextforuser = $contextlist->current();
 518          $this->assertEquals(
 519                  \context_user::instance($user2->id)->id,
 520                  $contextforuser->id);
 521      }
 522  
 523      /**
 524       * Test for provider::export_user_data().
 525       */
 526      public function test_export_for_context_with_contacts() {
 527          $this->resetAfterTest();
 528  
 529          // Create users to test with.
 530          $user1 = $this->getDataGenerator()->create_user();
 531          $user2 = $this->getDataGenerator()->create_user();
 532          $user3 = $this->getDataGenerator()->create_user();
 533          $user4 = $this->getDataGenerator()->create_user();
 534  
 535          // Remove user self-conversations.
 536          $this->remove_user_self_conversation($user1->id);
 537          $this->remove_user_self_conversation($user2->id);
 538          $this->remove_user_self_conversation($user3->id);
 539          $this->remove_user_self_conversation($user4->id);
 540  
 541          \core_message\api::add_contact($user1->id, $user2->id);
 542          \core_message\api::add_contact($user1->id, $user3->id);
 543          \core_message\api::add_contact($user1->id, $user4->id);
 544  
 545          $user1context = \context_user::instance($user1->id);
 546  
 547          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 548  
 549          $writer = writer::with_context($user1context);
 550  
 551          $contacts = (array) $writer->get_data([get_string('contacts', 'core_message')]);
 552          usort($contacts, ['static', 'sort_contacts']);
 553  
 554          $this->assertCount(3, $contacts);
 555  
 556          $contact1 = array_shift($contacts);
 557          $this->assertEquals($user2->id, $contact1->contact);
 558  
 559          $contact2 = array_shift($contacts);
 560          $this->assertEquals($user3->id, $contact2->contact);
 561  
 562          $contact3 = array_shift($contacts);
 563          $this->assertEquals($user4->id, $contact3->contact);
 564      }
 565  
 566      /**
 567       * Test for provider::export_user_data().
 568       */
 569      public function test_export_for_context_with_contact_requests() {
 570          $this->resetAfterTest();
 571  
 572          // Create users to test with.
 573          $user1 = $this->getDataGenerator()->create_user();
 574          $user2 = $this->getDataGenerator()->create_user();
 575          $user3 = $this->getDataGenerator()->create_user();
 576          $user4 = $this->getDataGenerator()->create_user();
 577  
 578          // Remove user self-conversations.
 579          $this->remove_user_self_conversation($user1->id);
 580          $this->remove_user_self_conversation($user2->id);
 581          $this->remove_user_self_conversation($user3->id);
 582          $this->remove_user_self_conversation($user4->id);
 583  
 584          \core_message\api::create_contact_request($user1->id, $user2->id);
 585          \core_message\api::create_contact_request($user3->id, $user1->id);
 586          \core_message\api::create_contact_request($user1->id, $user4->id);
 587  
 588          $user1context = \context_user::instance($user1->id);
 589  
 590          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 591  
 592          $writer = writer::with_context($user1context);
 593  
 594          $contactrequests = (array) $writer->get_data([get_string('contactrequests', 'core_message')]);
 595  
 596          $this->assertCount(3, $contactrequests);
 597  
 598          $contactrequest1 = array_shift($contactrequests);
 599          $this->assertEquals($user2->id, $contactrequest1->contactrequest);
 600          $this->assertEquals(get_string('yes'), $contactrequest1->maderequest);
 601  
 602          $contactrequest2 = array_shift($contactrequests);
 603          $this->assertEquals($user3->id, $contactrequest2->contactrequest);
 604          $this->assertEquals(get_string('no'), $contactrequest2->maderequest);
 605  
 606          $contactrequest3 = array_shift($contactrequests);
 607          $this->assertEquals($user4->id, $contactrequest3->contactrequest);
 608          $this->assertEquals(get_string('yes'), $contactrequest3->maderequest);
 609      }
 610  
 611      /**
 612       * Test for provider::export_user_data().
 613       */
 614      public function test_export_for_context_with_blocked_users() {
 615          $this->resetAfterTest();
 616  
 617          // Create users to test with.
 618          $user1 = $this->getDataGenerator()->create_user();
 619          $user2 = $this->getDataGenerator()->create_user();
 620          $user3 = $this->getDataGenerator()->create_user();
 621          $user4 = $this->getDataGenerator()->create_user();
 622  
 623          // Remove user self-conversations.
 624          $this->remove_user_self_conversation($user1->id);
 625          $this->remove_user_self_conversation($user2->id);
 626          $this->remove_user_self_conversation($user3->id);
 627          $this->remove_user_self_conversation($user4->id);
 628  
 629          \core_message\api::block_user($user1->id, $user2->id);
 630          \core_message\api::block_user($user1->id, $user3->id);
 631          \core_message\api::block_user($user1->id, $user4->id);
 632  
 633          $user1context = \context_user::instance($user1->id);
 634  
 635          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 636  
 637          $writer = writer::with_context($user1context);
 638  
 639          $blockedusers = (array) $writer->get_data([get_string('blockedusers', 'core_message')]);
 640  
 641          $this->assertCount(3, $blockedusers);
 642  
 643          $blockeduser1 = array_shift($blockedusers);
 644          $this->assertEquals($user2->id, $blockeduser1->blockeduser);
 645  
 646          $blockeduser2 = array_shift($blockedusers);
 647          $this->assertEquals($user3->id, $blockeduser2->blockeduser);
 648  
 649          $blockeduser3 = array_shift($blockedusers);
 650          $this->assertEquals($user4->id, $blockeduser3->blockeduser);
 651      }
 652  
 653      /**
 654       * Test for provider::export_user_data().
 655       */
 656      public function test_export_for_context_with_private_messages() {
 657          global $DB;
 658  
 659          $this->resetAfterTest();
 660  
 661          // Create users to test with.
 662          $user1 = $this->getDataGenerator()->create_user();
 663          $user2 = $this->getDataGenerator()->create_user();
 664          $user3 = $this->getDataGenerator()->create_user();
 665  
 666          // Remove user self-conversations.
 667          $this->remove_user_self_conversation($user1->id);
 668          $this->remove_user_self_conversation($user2->id);
 669          $this->remove_user_self_conversation($user3->id);
 670  
 671          $now = time();
 672  
 673          // Send messages from user 1 to user 2.
 674          $m1 = $this->create_message($user1->id, $user2->id, $now - (9 * DAYSECS), true);
 675          $m2 = $this->create_message($user2->id, $user1->id, $now - (8 * DAYSECS));
 676          $m3 = $this->create_message($user1->id, $user2->id, $now - (7 * DAYSECS));
 677  
 678          // Send messages from user 3 to user 1.
 679          $m4 = $this->create_message($user3->id, $user1->id, $now - (6 * DAYSECS), true);
 680          $m5 = $this->create_message($user1->id, $user3->id, $now - (5 * DAYSECS));
 681          $m6 = $this->create_message($user3->id, $user1->id, $now - (4 * DAYSECS));
 682  
 683          // Send messages from user 3 to user 2 - these should not be included in the export.
 684          $m7 = $this->create_message($user3->id, $user2->id, $now - (3 * DAYSECS), true);
 685          $m8 = $this->create_message($user2->id, $user3->id, $now - (2 * DAYSECS));
 686          $m9 = $this->create_message($user3->id, $user2->id, $now - (1 * DAYSECS));
 687  
 688          // Mark message 2 and 5 as deleted.
 689          \core_message\api::delete_message($user1->id, $m2);
 690          \core_message\api::delete_message($user1->id, $m5);
 691  
 692          $user1context = \context_user::instance($user1->id);
 693  
 694          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 695  
 696          $writer = writer::with_context($user1context);
 697  
 698          $this->assertTrue($writer->has_any_data());
 699  
 700          // Confirm the messages with user 2 are correct.
 701          $messages = (array) $writer->get_data([get_string('messages', 'core_message'), $user2->id]);
 702          $this->assertCount(3, $messages);
 703  
 704          $dbm1 = $DB->get_record('messages', ['id' => $m1]);
 705          $dbm2 = $DB->get_record('messages', ['id' => $m2]);
 706          $dbm3 = $DB->get_record('messages', ['id' => $m3]);
 707  
 708          usort($messages, ['static', 'sort_messages']);
 709          $m1 = array_shift($messages);
 710          $m2 = array_shift($messages);
 711          $m3 = array_shift($messages);
 712  
 713          $this->assertEquals(get_string('yes'), $m1->issender);
 714          $this->assertEquals(message_format_message_text($dbm1), $m1->message);
 715          $this->assertEquals(transform::datetime($now - (9 * DAYSECS)), $m1->timecreated);
 716          $this->assertEquals('-', $m1->timeread);
 717          $this->assertArrayNotHasKey('timedeleted', (array) $m1);
 718  
 719          $this->assertEquals(get_string('no'), $m2->issender);
 720          $this->assertEquals(message_format_message_text($dbm2), $m2->message);
 721          $this->assertEquals(transform::datetime($now - (8 * DAYSECS)), $m2->timecreated);
 722          $this->assertEquals('-', $m2->timeread);
 723          $this->assertArrayHasKey('timedeleted', (array) $m2);
 724  
 725          $this->assertEquals(get_string('yes'), $m3->issender);
 726          $this->assertEquals(message_format_message_text($dbm3), $m3->message);
 727          $this->assertEquals(transform::datetime($now - (7 * DAYSECS)), $m3->timecreated);
 728          $this->assertEquals('-', $m3->timeread);
 729  
 730          // Confirm the messages with user 3 are correct.
 731          $messages = (array) $writer->get_data([get_string('messages', 'core_message'), $user3->id]);
 732          $this->assertCount(3, $messages);
 733  
 734          $dbm4 = $DB->get_record('messages', ['id' => $m4]);
 735          $dbm5 = $DB->get_record('messages', ['id' => $m5]);
 736          $dbm6 = $DB->get_record('messages', ['id' => $m6]);
 737  
 738          usort($messages, ['static', 'sort_messages']);
 739          $m4 = array_shift($messages);
 740          $m5 = array_shift($messages);
 741          $m6 = array_shift($messages);
 742  
 743          $this->assertEquals(get_string('no'), $m4->issender);
 744          $this->assertEquals(message_format_message_text($dbm4), $m4->message);
 745          $this->assertEquals(transform::datetime($now - (6 * DAYSECS)), $m4->timecreated);
 746          $this->assertNotEquals('-', $m4->timeread);
 747          $this->assertArrayNotHasKey('timedeleted', (array) $m4);
 748  
 749          $this->assertEquals(get_string('yes'), $m5->issender);
 750          $this->assertEquals(message_format_message_text($dbm5), $m5->message);
 751          $this->assertEquals(transform::datetime($now - (5 * DAYSECS)), $m5->timecreated);
 752          $this->assertEquals('-', $m5->timeread);
 753          $this->assertArrayHasKey('timedeleted', (array) $m5);
 754  
 755          $this->assertEquals(get_string('no'), $m6->issender);
 756          $this->assertEquals(message_format_message_text($dbm6), $m6->message);
 757          $this->assertEquals(transform::datetime($now - (4 * DAYSECS)), $m6->timecreated);
 758          $this->assertEquals('-', $m6->timeread);
 759      }
 760  
 761      /**
 762       * Test for provider::export_user_data().
 763       */
 764      public function test_export_for_context_with_messages() {
 765          global $DB;
 766  
 767          $this->resetAfterTest();
 768          $this->setAdminUser();
 769          $now = time();
 770          $systemcontext = \context_system::instance();
 771  
 772          // Create users to test with.
 773          $user1 = $this->getDataGenerator()->create_user();
 774          $user2 = $this->getDataGenerator()->create_user();
 775          $user3 = $this->getDataGenerator()->create_user();
 776          $user1context = \context_user::instance($user1->id);
 777  
 778          // Remove user self-conversations.
 779          $this->remove_user_self_conversation($user1->id);
 780          $this->remove_user_self_conversation($user2->id);
 781          $this->remove_user_self_conversation($user3->id);
 782  
 783          $course1 = $this->getDataGenerator()->create_course();
 784          $course2 = $this->getDataGenerator()->create_course();
 785          $coursecontext1 = \context_course::instance($course1->id);
 786          $coursecontext2 = \context_course::instance($course2->id);
 787  
 788          // Enrol users to courses.
 789          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
 790          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
 791          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
 792          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
 793  
 794          // Create course groups with group messaging enabled.
 795          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
 796          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
 797  
 798          // Add users to groups.
 799          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
 800          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
 801          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
 802          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
 803  
 804          // Get conversation.
 805          $component = 'core_group';
 806          $itemtype = 'groups';
 807          $conversation = \core_message\api::get_conversation_by_area(
 808              $component,
 809              $itemtype,
 810              $group1a->id,
 811              $coursecontext1->id
 812          );
 813  
 814          // Send some private messages between user 1 and user 2.
 815          $pm1id = $this->create_message($user1->id, $user2->id, $now);
 816  
 817          $dbpm1 = $DB->get_record('messages', ['id' => $pm1id]);
 818  
 819          // Send some messages to the conversation.
 820          $m1 = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $now + 1);
 821          $m2 = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 2', $now + 2);
 822          $m3 = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 3', $now + 3);
 823  
 824          $dbm1 = $DB->get_record('messages', ['id' => $m1]);
 825          $dbm2 = $DB->get_record('messages', ['id' => $m2]);
 826          $dbm3 = $DB->get_record('messages', ['id' => $m3]);
 827  
 828          // Mark as read and delete some messages.
 829          \core_message\api::mark_message_as_read($user2->id, $dbm1);
 830          \core_message\api::delete_message($user1->id, $m2);
 831  
 832          // Confirm the user1 has no data in any course context because private messages are related to user context.
 833          $this->export_context_data_for_user($user1->id, $coursecontext2, 'core_message');
 834  
 835          // Check that system context hasn't been exported.
 836          $writer = writer::with_context($systemcontext);
 837          $this->assertFalse($writer->has_any_data());
 838  
 839          // Check that course1 context hasn't been exported.
 840          $writer = writer::with_context($coursecontext1);
 841          $this->assertFalse($writer->has_any_data());
 842  
 843          // Check that course2 context has been exported and contains data.
 844          $writer = writer::with_context($coursecontext2);
 845          $this->assertFalse($writer->has_any_data());
 846  
 847          // Confirm the user1 has only private messages in the user context.
 848          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 849          $writer = writer::with_context($user1context);
 850          $this->assertTrue($writer->has_any_data());
 851  
 852          // Confirm the messages with user 2 are correct.
 853          $messages = (array) $writer->get_data([get_string('messages', 'core_message'), $user2->id]);
 854          $this->assertCount(1, $messages);
 855          $m1 = reset($messages);
 856  
 857          $this->assertEquals(get_string('yes'), $m1->issender);
 858          $this->assertEquals(message_format_message_text($dbpm1), $m1->message);
 859          $this->assertEquals(transform::datetime($now), $m1->timecreated);
 860          $this->assertEquals('-', $m1->timeread);
 861          $this->assertArrayNotHasKey('timedeleted', (array) $m1);
 862  
 863          // Confirm the messages with user 3 are correct.
 864          $messages = (array) $writer->get_data([get_string('messages', 'core_message'), fullname($user3)]);
 865          $this->assertCount(0, $messages);
 866      }
 867  
 868      /**
 869       * Test for provider::export_user_data().
 870       */
 871      public function test_export_for_context_with_notifications() {
 872          $this->resetAfterTest();
 873  
 874          // Create users to test with.
 875          $user1 = $this->getDataGenerator()->create_user();
 876          $user2 = $this->getDataGenerator()->create_user();
 877          $user3 = $this->getDataGenerator()->create_user();
 878  
 879          // Remove user self-conversations.
 880          $this->remove_user_self_conversation($user1->id);
 881          $this->remove_user_self_conversation($user2->id);
 882          $this->remove_user_self_conversation($user3->id);
 883  
 884          $now = time();
 885          $timeread = $now - DAYSECS;
 886  
 887          // Send notifications from user 1 to user 2.
 888          $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
 889          $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
 890          $this->create_notification($user1->id, $user2->id, $now + (7 * DAYSECS));
 891  
 892          // Send notifications from user 3 to user 1.
 893          $this->create_notification($user3->id, $user1->id, $now + (6 * DAYSECS), $timeread);
 894          $this->create_notification($user1->id, $user3->id, $now + (5 * DAYSECS));
 895          $this->create_notification($user3->id, $user1->id, $now + (4 * DAYSECS));
 896  
 897          // Send notifications from user 3 to user 2 - should not be part of the export.
 898          $this->create_notification($user3->id, $user2->id, $now + (3 * DAYSECS), $timeread);
 899          $this->create_notification($user2->id, $user3->id, $now + (2 * DAYSECS));
 900          $this->create_notification($user3->id, $user2->id, $now + (1 * DAYSECS));
 901  
 902          $user1context = \context_user::instance($user1->id);
 903  
 904          $this->export_context_data_for_user($user1->id, $user1context, 'core_message');
 905  
 906          $writer = writer::with_context($user1context);
 907  
 908          $this->assertTrue($writer->has_any_data());
 909  
 910          // Confirm the notifications.
 911          $notifications = (array) $writer->get_data([get_string('notifications', 'core_message')]);
 912  
 913          $this->assertCount(6, $notifications);
 914      }
 915  
 916      /**
 917       * Test for provider::delete_data_for_all_users_in_context().
 918       */
 919      public function test_delete_data_for_all_users_in_context() {
 920          global $DB;
 921  
 922          $this->resetAfterTest();
 923  
 924          // Create users to test with.
 925          $user1 = $this->getDataGenerator()->create_user();
 926          $user2 = $this->getDataGenerator()->create_user();
 927          $user3 = $this->getDataGenerator()->create_user();
 928          $user4 = $this->getDataGenerator()->create_user();
 929          $user5 = $this->getDataGenerator()->create_user();
 930  
 931          $now = time();
 932          $timeread = $now - DAYSECS;
 933  
 934          $user1context = \context_user::instance($user1->id);
 935  
 936          // Create contacts.
 937          \core_message\api::add_contact($user1->id, $user2->id);
 938          \core_message\api::add_contact($user2->id, $user3->id);
 939  
 940          // Create contact requests.
 941          \core_message\api::create_contact_request($user1->id, $user3->id);
 942          \core_message\api::create_contact_request($user2->id, $user4->id);
 943  
 944          // Block a user.
 945          \core_message\api::block_user($user1->id, $user3->id);
 946          \core_message\api::block_user($user3->id, $user4->id);
 947  
 948          // Create messages.
 949          $m1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
 950          $m2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS));
 951          $m3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
 952  
 953          // Create notifications.
 954          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
 955          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
 956          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
 957  
 958          // Delete one of the messages.
 959          \core_message\api::delete_message($user1->id, $m2);
 960  
 961          // There should be 2 contacts.
 962          $this->assertEquals(2, $DB->count_records('message_contacts'));
 963  
 964          // There should be 2 contact requests.
 965          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
 966  
 967          // There should be 2 blocked users.
 968          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
 969  
 970          // There should be 3 messages.
 971          $this->assertEquals(3, $DB->count_records('messages'));
 972  
 973          // There should be 2 user actions - one for reading the message, one for deleting.
 974          $this->assertEquals(2, $DB->count_records('message_user_actions'));
 975  
 976          // There should be 4 conversation members + 5 self-conversations.
 977          $this->assertEquals(9, $DB->count_records('message_conversation_members'));
 978  
 979          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
 980          $this->assertEquals(5, $DB->count_records('notifications'));
 981  
 982          provider::delete_data_for_all_users_in_context($user1context);
 983  
 984          // Confirm there is only 1 contact left.
 985          $this->assertEquals(1, $DB->count_records('message_contacts'));
 986          // And it is not related to user1.
 987          $this->assertEquals(0,
 988                  $DB->count_records_select('message_contacts', 'userid = ? OR contactid = ?', [$user1->id, $user1->id]));
 989  
 990          // Confirm there is only 1 contact request left.
 991          $this->assertEquals(1, $DB->count_records('message_contact_requests'));
 992          // And it is not related to user1.
 993          $this->assertEquals(0,
 994                  $DB->count_records_select('message_contact_requests', 'userid = ? OR requesteduserid = ?',
 995                          [$user1->id, $user1->id]));
 996  
 997          // Confirm there is only 1 blocked user left.
 998          $this->assertEquals(1, $DB->count_records('message_users_blocked'));
 999          // And it is not related to user1.
1000          $this->assertEquals(0,
1001                  $DB->count_records_select('message_users_blocked', 'userid = ? OR blockeduserid = ?', [$user1->id, $user1->id]));
1002  
1003          // Confirm there are only 2 messages left.
1004          $this->assertEquals(2, $DB->count_records('messages'));
1005          // And none of them are from user1.
1006          $this->assertEquals(0, $DB->count_records('messages', ['useridfrom' => $user1->id]));
1007  
1008          // Confirm there is 0 user action left.
1009          $this->assertEquals(0, $DB->count_records('message_user_actions'));
1010          // And it is not for user1.
1011          $this->assertEquals(0, $DB->count_records('message_user_actions', ['userid' => $user1->id]));
1012  
1013          // Confirm there are only 3 conversation members left + 4 self-conversations.
1014          $this->assertEquals(7, $DB->count_records('message_conversation_members'));
1015          // And user1 is not in any conversation.
1016          $this->assertEquals(0, $DB->count_records('message_conversation_members', ['userid' => $user1->id]));
1017  
1018          // Confirm there are only 2 notifications.
1019          $this->assertEquals(2, $DB->count_records('notifications'));
1020          // And it is not related to user1.
1021          $this->assertEquals(0,
1022                  $DB->count_records_select('notifications', 'useridfrom = ? OR useridto = ? ', [$user1->id, $user1->id]));
1023  
1024          // Delete user self-conversations.
1025          $this->remove_user_self_conversation($user2->id);
1026          $this->remove_user_self_conversation($user3->id);
1027          $this->remove_user_self_conversation($user4->id);
1028          $this->remove_user_self_conversation($user5->id);
1029  
1030          // Confirm there are only 3 conversation members left.
1031          $this->assertEquals(3, $DB->count_records('message_conversation_members'));
1032          // And user1 is not in any conversation.
1033          $this->assertEquals(0, $DB->count_records('message_conversation_members', ['userid' => $user1->id]));
1034  
1035      }
1036  
1037      /**
1038       * Test for provider::delete_data_for_user().
1039       */
1040      public function test_delete_data_for_user() {
1041          global $DB;
1042  
1043          $this->resetAfterTest();
1044  
1045          // Create users to test with.
1046          $user1 = $this->getDataGenerator()->create_user();
1047          $user2 = $this->getDataGenerator()->create_user();
1048          $user3 = $this->getDataGenerator()->create_user();
1049          $user4 = $this->getDataGenerator()->create_user();
1050          $user5 = $this->getDataGenerator()->create_user();
1051          $user6 = $this->getDataGenerator()->create_user();
1052  
1053          $now = time();
1054          $timeread = $now - DAYSECS;
1055  
1056          // Create contacts.
1057          \core_message\api::add_contact($user1->id, $user2->id);
1058          \core_message\api::add_contact($user2->id, $user3->id);
1059  
1060          // Create contact requests.
1061          \core_message\api::create_contact_request($user1->id, $user3->id);
1062          \core_message\api::create_contact_request($user2->id, $user4->id);
1063  
1064          // Block users.
1065          \core_message\api::block_user($user1->id, $user5->id);
1066          \core_message\api::block_user($user2->id, $user6->id);
1067  
1068          // Create messages.
1069          $m1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
1070          $m2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS));
1071  
1072          // Create notifications.
1073          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
1074          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
1075          $n2 = $this->create_notification($user2->id, $user3->id, $now + (8 * DAYSECS));
1076  
1077          // Delete one of the messages.
1078          \core_message\api::delete_message($user1->id, $m2);
1079  
1080          // There should be 2 contacts.
1081          $this->assertEquals(2, $DB->count_records('message_contacts'));
1082  
1083          // There should be 1 contact request.
1084          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
1085  
1086          // There should be 1 blocked user.
1087          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
1088  
1089          // There should be two messages.
1090          $this->assertEquals(2, $DB->count_records('messages'));
1091  
1092          // There should be two user actions - one for reading the message, one for deleting.
1093          $this->assertEquals(2, $DB->count_records('message_user_actions'));
1094  
1095          // There should be two conversation members + 6 self-conversations.
1096          $this->assertEquals(8, $DB->count_records('message_conversation_members'));
1097  
1098          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
1099          $this->assertEquals(5, $DB->count_records('notifications'));
1100  
1101          $user1context = \context_user::instance($user1->id);
1102          $contextlist = new \core_privacy\local\request\approved_contextlist($user1, 'core_message',
1103              [$user1context->id]);
1104          provider::delete_data_for_user($contextlist);
1105  
1106          // Confirm the user 2 data still exists.
1107          $contacts = $DB->get_records('message_contacts');
1108          $contactrequests = $DB->get_records('message_contact_requests');
1109          $blockedusers = $DB->get_records('message_users_blocked');
1110          $messages = $DB->get_records('messages');
1111          $muas = $DB->get_records('message_user_actions');
1112          $mcms = $DB->get_records('message_conversation_members');
1113          $notifications = $DB->get_records('notifications');
1114  
1115          $this->assertCount(1, $contacts);
1116          $contact = reset($contacts);
1117          $this->assertEquals($user2->id, $contact->userid);
1118          $this->assertEquals($user3->id, $contact->contactid);
1119  
1120          $this->assertCount(1, $contactrequests);
1121          $contactrequest = reset($contactrequests);
1122          $this->assertEquals($user2->id, $contactrequest->userid);
1123          $this->assertEquals($user4->id, $contactrequest->requesteduserid);
1124  
1125          $this->assertCount(1, $blockedusers);
1126          $blockeduser = reset($blockedusers);
1127          $this->assertEquals($user2->id, $blockeduser->userid);
1128          $this->assertEquals($user6->id, $blockeduser->blockeduserid);
1129  
1130          $this->assertCount(1, $messages);
1131          $message = reset($messages);
1132          $this->assertEquals($m2, $message->id);
1133  
1134          $this->assertCount(0, $muas);
1135  
1136          $this->assertCount(6, $mcms);
1137          $members = array_map(function($member) {
1138              return $member->userid;
1139          }, $mcms);
1140          $this->assertContains($user2->id, $members);
1141  
1142          $this->assertCount(2, $notifications);
1143          ksort($notifications);
1144  
1145          $notification = array_pop($notifications);
1146          $this->assertEquals($user2->id, $notification->useridfrom);
1147          $this->assertEquals($user3->id, $notification->useridto);
1148      }
1149  
1150      /**
1151       * Test for provider::get_users_in_context() when there is no message or notification.
1152       */
1153      public function test_get_users_in_context_no_data() {
1154          $this->resetAfterTest();
1155  
1156          $user = $this->getDataGenerator()->create_user();
1157          $usercontext = \context_user::instance($user->id);
1158          $this->remove_user_self_conversation($user->id);
1159  
1160          $userlist = new \core_privacy\local\request\userlist($usercontext, 'core_message');
1161          \core_message\privacy\provider::get_users_in_context($userlist);
1162  
1163          $this->assertEmpty($userlist->get_userids());
1164      }
1165  
1166      /**
1167       * Test for provider::get_users_in_context() when there is a message between users.
1168       */
1169      public function test_get_users_in_context_with_message() {
1170          $this->resetAfterTest();
1171  
1172          $user1 = $this->getDataGenerator()->create_user();
1173          $user2 = $this->getDataGenerator()->create_user();
1174  
1175          $user1context = \context_user::instance($user1->id);
1176          $user2context = \context_user::instance($user2->id);
1177  
1178          // Delete user self-conversations.
1179          $this->remove_user_self_conversation($user1->id);
1180          $this->remove_user_self_conversation($user2->id);
1181  
1182          // Test nothing is found before message is sent.
1183          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1184          \core_message\privacy\provider::get_users_in_context($userlist);
1185          $this->assertCount(0, $userlist);
1186          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1187          \core_message\privacy\provider::get_users_in_context($userlist);
1188          $this->assertCount(0, $userlist);
1189  
1190          $this->create_message($user1->id, $user2->id, time() - (9 * DAYSECS));
1191  
1192          // Test for the sender.
1193          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1194          \core_message\privacy\provider::get_users_in_context($userlist);
1195          $this->assertCount(1, $userlist);
1196          $userincontext = $userlist->current();
1197          $this->assertEquals($user1->id, $userincontext->id);
1198  
1199          // Test for the receiver.
1200          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1201          \core_message\privacy\provider::get_users_in_context($userlist);
1202          $this->assertCount(1, $userlist);
1203          $userincontext = $userlist->current();
1204          $this->assertEquals($user2->id, $userincontext->id);
1205      }
1206  
1207      /**
1208       * Test for provider::get_users_in_context() when there is a notification between users.
1209       */
1210      public function test_get_users_in_context_with_notification() {
1211          $this->resetAfterTest();
1212  
1213          $user1 = $this->getDataGenerator()->create_user();
1214          $user2 = $this->getDataGenerator()->create_user();
1215  
1216          $user1context = \context_user::instance($user1->id);
1217          $user2context = \context_user::instance($user2->id);
1218  
1219          // Delete user self-conversations.
1220          $this->remove_user_self_conversation($user1->id);
1221          $this->remove_user_self_conversation($user2->id);
1222  
1223          // Test nothing is found before notification is created.
1224          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1225          \core_message\privacy\provider::get_users_in_context($userlist);
1226          $this->assertCount(0, $userlist);
1227          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1228          \core_message\privacy\provider::get_users_in_context($userlist);
1229          $this->assertCount(0, $userlist);
1230  
1231          $this->create_notification($user1->id, $user2->id, time() - (9 * DAYSECS));
1232  
1233          // Test for the sender.
1234          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1235          \core_message\privacy\provider::get_users_in_context($userlist);
1236          $this->assertCount(1, $userlist);
1237          $userincontext = $userlist->current();
1238          $this->assertEquals($user1->id, $userincontext->id);
1239  
1240          // Test for the receiver.
1241          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1242          \core_message\privacy\provider::get_users_in_context($userlist);
1243          $this->assertCount(1, $userlist);
1244          $userincontext = $userlist->current();
1245          $this->assertEquals($user2->id, $userincontext->id);
1246      }
1247  
1248      /**
1249       * Test for provider::get_users_in_context() when a users has a contact.
1250       */
1251      public function test_get_users_in_context_with_contact() {
1252          $this->resetAfterTest();
1253  
1254          $user1 = $this->getDataGenerator()->create_user();
1255          $user2 = $this->getDataGenerator()->create_user();
1256  
1257          $user1context = \context_user::instance($user1->id);
1258          $user2context = \context_user::instance($user2->id);
1259  
1260          // Delete user self-conversations.
1261          $this->remove_user_self_conversation($user1->id);
1262          $this->remove_user_self_conversation($user2->id);
1263  
1264          // Test nothing is found before contact is created.
1265          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1266          \core_message\privacy\provider::get_users_in_context($userlist);
1267          $this->assertCount(0, $userlist);
1268          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1269          \core_message\privacy\provider::get_users_in_context($userlist);
1270          $this->assertCount(0, $userlist);
1271  
1272          \core_message\api::add_contact($user1->id, $user2->id);
1273  
1274          // Test for the user adding the contact.
1275          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1276          \core_message\privacy\provider::get_users_in_context($userlist);
1277          $this->assertCount(1, $userlist);
1278          $userincontext = $userlist->current();
1279          $this->assertEquals($user1->id, $userincontext->id);
1280  
1281          // Test for the user who is the contact.
1282          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1283          \core_message\privacy\provider::get_users_in_context($userlist);
1284          $this->assertCount(1, $userlist);
1285          $userincontext = $userlist->current();
1286          $this->assertEquals($user2->id, $userincontext->id);
1287      }
1288  
1289      /**
1290       * Test for provider::get_users_in_context() when a user makes a contact request.
1291       */
1292      public function test_get_users_in_context_with_contact_request() {
1293          $this->resetAfterTest();
1294  
1295          $user1 = $this->getDataGenerator()->create_user();
1296          $user2 = $this->getDataGenerator()->create_user();
1297  
1298          $user1context = \context_user::instance($user1->id);
1299          $user2context = \context_user::instance($user2->id);
1300  
1301          // Delete user self-conversations.
1302          $this->remove_user_self_conversation($user1->id);
1303          $this->remove_user_self_conversation($user2->id);
1304  
1305          // Test nothing is found before request is created.
1306          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1307          \core_message\privacy\provider::get_users_in_context($userlist);
1308          $this->assertCount(0, $userlist);
1309          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1310          \core_message\privacy\provider::get_users_in_context($userlist);
1311          $this->assertCount(0, $userlist);
1312  
1313          \core_message\api::create_contact_request($user1->id, $user2->id);
1314  
1315          // Test for the user requesting the contact.
1316          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1317          \core_message\privacy\provider::get_users_in_context($userlist);
1318          $this->assertCount(1, $userlist);
1319          $userincontext = $userlist->current();
1320          $this->assertEquals($user1->id, $userincontext->id);
1321  
1322          // Test for the user receiving the contact request.
1323          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1324          \core_message\privacy\provider::get_users_in_context($userlist);
1325          $this->assertCount(1, $userlist);
1326          $userincontext = $userlist->current();
1327          $this->assertEquals($user2->id, $userincontext->id);
1328      }
1329  
1330      /**
1331       * Test for provider::get_users_in_context() when a user is blocked.
1332       */
1333      public function test_get_users_in_context_with_blocked_contact() {
1334          $this->resetAfterTest();
1335  
1336          $user1 = $this->getDataGenerator()->create_user();
1337          $user2 = $this->getDataGenerator()->create_user();
1338  
1339          $user1context = \context_user::instance($user1->id);
1340          $user2context = \context_user::instance($user2->id);
1341  
1342          // Delete user self-conversations.
1343          $this->remove_user_self_conversation($user1->id);
1344          $this->remove_user_self_conversation($user2->id);
1345  
1346          // Test nothing is found before user is blocked.
1347          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1348          \core_message\privacy\provider::get_users_in_context($userlist);
1349          $this->assertCount(0, $userlist);
1350          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1351          \core_message\privacy\provider::get_users_in_context($userlist);
1352          $this->assertCount(0, $userlist);
1353  
1354          \core_message\api::block_user($user1->id, $user2->id);
1355  
1356          // Test for the blocking user.
1357          $userlist = new \core_privacy\local\request\userlist($user1context, 'core_message');
1358          \core_message\privacy\provider::get_users_in_context($userlist);
1359          $this->assertCount(1, $userlist);
1360          $userincontext = $userlist->current();
1361          $this->assertEquals($user1->id, $userincontext->id);
1362  
1363          // Test for the user who is blocked.
1364          $userlist = new \core_privacy\local\request\userlist($user2context, 'core_message');
1365          \core_message\privacy\provider::get_users_in_context($userlist);
1366          $this->assertCount(1, $userlist);
1367          $userincontext = $userlist->current();
1368          $this->assertEquals($user2->id, $userincontext->id);
1369      }
1370  
1371      /**
1372       * Test for provider::delete_data_for_users().
1373       */
1374      public function test_delete_data_for_users() {
1375          global $DB;
1376  
1377          $this->resetAfterTest();
1378  
1379          // Create users to test with.
1380          $user1 = $this->getDataGenerator()->create_user();
1381          $user2 = $this->getDataGenerator()->create_user();
1382          $user3 = $this->getDataGenerator()->create_user();
1383          $user4 = $this->getDataGenerator()->create_user();
1384          $user5 = $this->getDataGenerator()->create_user();
1385          $user6 = $this->getDataGenerator()->create_user();
1386  
1387          $now = time();
1388          $timeread = $now - DAYSECS;
1389  
1390          // Create contacts.
1391          \core_message\api::add_contact($user1->id, $user2->id);
1392          \core_message\api::add_contact($user2->id, $user3->id);
1393  
1394          // Create contact requests.
1395          \core_message\api::create_contact_request($user1->id, $user3->id);
1396          \core_message\api::create_contact_request($user2->id, $user4->id);
1397  
1398          // Block users.
1399          \core_message\api::block_user($user1->id, $user5->id);
1400          \core_message\api::block_user($user2->id, $user6->id);
1401  
1402          // Create messages.
1403          $m1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
1404          $m2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS));
1405  
1406          // Create notifications.
1407          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
1408          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
1409          $n2 = $this->create_notification($user2->id, $user3->id, $now + (8 * DAYSECS));
1410  
1411          // Delete one of the messages.
1412          \core_message\api::delete_message($user1->id, $m2);
1413  
1414          // There should be 2 contacts.
1415          $this->assertEquals(2, $DB->count_records('message_contacts'));
1416  
1417          // There should be 1 contact request.
1418          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
1419  
1420          // There should be 1 blocked user.
1421          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
1422  
1423          // There should be two messages.
1424          $this->assertEquals(2, $DB->count_records('messages'));
1425  
1426          // There should be two user actions - one for reading the message, one for deleting.
1427          $this->assertEquals(2, $DB->count_records('message_user_actions'));
1428  
1429          // There should be two conversation members + 6 self-conversations.
1430          $this->assertEquals(8, $DB->count_records('message_conversation_members'));
1431  
1432          // There should be three notifications + two for the contact requests.
1433          $this->assertEquals(5, $DB->count_records('notifications'));
1434  
1435          $user1context = \context_user::instance($user1->id);
1436          $approveduserlist = new \core_privacy\local\request\approved_userlist($user1context, 'core_message',
1437                  [$user1->id, $user2->id]);
1438          provider::delete_data_for_users($approveduserlist);
1439  
1440          // Only user1's data should be deleted. User2 should be skipped as user2 is an invalid user for user1context.
1441  
1442          // Confirm the user 2 data still exists.
1443          $contacts = $DB->get_records('message_contacts');
1444          $contactrequests = $DB->get_records('message_contact_requests');
1445          $blockedusers = $DB->get_records('message_users_blocked');
1446          $messages = $DB->get_records('messages');
1447          $muas = $DB->get_records('message_user_actions');
1448          $mcms = $DB->get_records('message_conversation_members');
1449          $notifications = $DB->get_records('notifications');
1450  
1451          $this->assertCount(1, $contacts);
1452          $contact = reset($contacts);
1453          $this->assertEquals($user2->id, $contact->userid);
1454          $this->assertEquals($user3->id, $contact->contactid);
1455  
1456          $this->assertCount(1, $contactrequests);
1457          $contactrequest = reset($contactrequests);
1458          $this->assertEquals($user2->id, $contactrequest->userid);
1459          $this->assertEquals($user4->id, $contactrequest->requesteduserid);
1460  
1461          $this->assertCount(1, $blockedusers);
1462          $blockeduser = reset($blockedusers);
1463          $this->assertEquals($user2->id, $blockeduser->userid);
1464          $this->assertEquals($user6->id, $blockeduser->blockeduserid);
1465  
1466          $this->assertCount(1, $messages);
1467          $message = reset($messages);
1468          $this->assertEquals($m2, $message->id);
1469  
1470          $this->assertCount(0, $muas);
1471  
1472          $this->assertCount(6, $mcms);
1473          $memberids = array_map(function($convmember) {
1474                  return $convmember->userid;
1475          }, $mcms);
1476          $this->assertContains($user2->id, $memberids);
1477  
1478          $this->assertCount(2, $notifications);
1479          ksort($notifications);
1480  
1481          $notification = array_pop($notifications);
1482          $this->assertEquals($user2->id, $notification->useridfrom);
1483          $this->assertEquals($user3->id, $notification->useridto);
1484      }
1485  
1486      /**
1487       * Test for provider::add_contexts_for_conversations().
1488       */
1489      public function test_add_contexts_for_conversations() {
1490          $this->resetAfterTest();
1491          $this->setAdminUser();
1492          $component = 'core_group';
1493          $itemtype = 'groups';
1494  
1495          $user1 = $this->getDataGenerator()->create_user();
1496          $user2 = $this->getDataGenerator()->create_user();
1497          $user3 = $this->getDataGenerator()->create_user();
1498          $user4 = $this->getDataGenerator()->create_user();
1499  
1500          // Delete user self-conversations.
1501          $this->remove_user_self_conversation($user1->id);
1502          $this->remove_user_self_conversation($user2->id);
1503          $this->remove_user_self_conversation($user3->id);
1504          $this->remove_user_self_conversation($user4->id);
1505  
1506          // Test nothing is found before group conversations is created or message is sent.
1507          $contextlist = new contextlist();
1508          provider::add_contexts_for_conversations($contextlist, $user1->id, $component, $itemtype);
1509          $this->assertCount(0, $contextlist);
1510          provider::add_contexts_for_conversations($contextlist, $user2->id, $component, $itemtype);
1511          $this->assertCount(0, $contextlist);
1512  
1513          // Create courses.
1514          $course1 = $this->getDataGenerator()->create_course();
1515          $course2 = $this->getDataGenerator()->create_course();
1516          $coursecontext1 = \context_course::instance($course1->id);
1517          $coursecontext2 = \context_course::instance($course2->id);
1518  
1519          // Enrol users to courses.
1520          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1521          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1522          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1523          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1524          $this->getDataGenerator()->enrol_user($user2->id, $course2->id);
1525  
1526          // Create course groups with messaging enabled.
1527          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
1528          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
1529  
1530          // Add users to groups.
1531          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
1532          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
1533          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
1534          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
1535  
1536          // Get conversation.
1537          $conversation1 = \core_message\api::get_conversation_by_area(
1538              $component,
1539              $itemtype,
1540              $group1a->id,
1541              $coursecontext1->id
1542          );
1543  
1544          // Send some messages to the group conversation.
1545          $now = time();
1546          $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
1547          $m2id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
1548          $m3id = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 3', $now + 3);
1549  
1550          // Test for user1 (is member of the conversation and has sent a message).
1551          $contextlist = new contextlist();
1552          provider::add_contexts_for_conversations($contextlist, $user1->id, $component, $itemtype);
1553          $this->assertCount(2, $contextlist);
1554          $this->assertContainsEquals($coursecontext1->id, $contextlist->get_contextids());
1555          $this->assertContainsEquals($coursecontext2->id, $contextlist->get_contextids());
1556  
1557          // Test for user2 (is member of the conversation and has sent a message).
1558          $contextlist = new contextlist();
1559          provider::add_contexts_for_conversations($contextlist, $user2->id, $component, $itemtype);
1560          $this->assertCount(1, $contextlist);
1561          $this->assertEquals($coursecontext1, $contextlist->current());
1562  
1563          // Test for user3 (is member of the conversation).
1564          $contextlist = new contextlist();
1565          provider::add_contexts_for_conversations($contextlist, $user3->id, $component, $itemtype);
1566          $this->assertCount(1, $contextlist);
1567          $this->assertEquals($coursecontext1, $contextlist->current());
1568  
1569          // Test for user4 (doesn't belong to the conversation).
1570          $contextlist = new contextlist();
1571          provider::add_contexts_for_conversations($contextlist, $user4->id, $component, $itemtype);
1572          $this->assertCount(0, $contextlist);
1573      }
1574  
1575      /**
1576       * Test for provider::add_conversations_in_context().
1577       */
1578      public function test_add_conversations_in_context() {
1579          $this->resetAfterTest();
1580          $this->setAdminUser();
1581          $component = 'core_group';
1582          $itemtype = 'groups';
1583  
1584          $user1 = $this->getDataGenerator()->create_user();
1585          $user2 = $this->getDataGenerator()->create_user();
1586          $user3 = $this->getDataGenerator()->create_user();
1587          $user4 = $this->getDataGenerator()->create_user();
1588  
1589          // Create courses.
1590          $course1 = $this->getDataGenerator()->create_course();
1591          $course2 = $this->getDataGenerator()->create_course();
1592          $coursecontext1 = \context_course::instance($course1->id);
1593          $coursecontext2 = \context_course::instance($course2->id);
1594  
1595          // Test nothing is found before group conversations is created or message is sent.
1596          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, 'core_message');
1597          provider::add_conversations_in_context($userlist1, $component, $itemtype);
1598          $this->assertCount(0, $userlist1);
1599  
1600          // Enrol users to courses.
1601          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1602          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1603          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1604          $this->getDataGenerator()->enrol_user($user4->id, $course1->id);
1605          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1606          $this->getDataGenerator()->enrol_user($user2->id, $course2->id);
1607  
1608          // Create course groups with messaging enabled.
1609          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
1610          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
1611  
1612          // Add users to groups.
1613          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
1614          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
1615          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
1616          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
1617  
1618          // Get conversation.
1619          $conversation1 = \core_message\api::get_conversation_by_area(
1620              $component,
1621              $itemtype,
1622              $group1a->id,
1623              $coursecontext1->id
1624          );
1625  
1626          // Send some messages to the group conversation.
1627          $now = time();
1628          $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
1629          $m2id = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
1630          $m3id = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 3', $now + 3);
1631  
1632          // Test for users with any group conversation in course1.
1633          provider::add_conversations_in_context($userlist1, $component, $itemtype);
1634          $this->assertCount(3, $userlist1);
1635          $this->assertEqualsCanonicalizing([$user1->id, $user2->id, $user3->id], $userlist1->get_userids());
1636  
1637          // Test for users with any group conversation in course2.
1638          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, 'core_message');
1639          provider::add_conversations_in_context($userlist2, $component, $itemtype);
1640          $this->assertCount(1, $userlist2);
1641          $this->assertEquals(
1642                  [$user1->id],
1643                  $userlist2->get_userids());
1644      }
1645  
1646      /**
1647       * Test for provider::export_conversations().
1648       */
1649      public function test_export_conversations() {
1650          global $DB;
1651  
1652          $this->resetAfterTest();
1653          $this->setAdminUser();
1654          $now = time();
1655          $systemcontext = \context_system::instance();
1656  
1657          // Create users to test with.
1658          $user1 = $this->getDataGenerator()->create_user();
1659          $user2 = $this->getDataGenerator()->create_user();
1660          $user3 = $this->getDataGenerator()->create_user();
1661          $user1context = \context_user::instance($user1->id);
1662  
1663          $course1 = $this->getDataGenerator()->create_course();
1664          $course2 = $this->getDataGenerator()->create_course();
1665          $coursecontext1 = \context_course::instance($course1->id);
1666          $coursecontext2 = \context_course::instance($course2->id);
1667  
1668          // Enrol users to courses.
1669          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1670          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1671          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1672          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1673  
1674          // Create course groups with group messaging enabled.
1675          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
1676          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
1677  
1678          // Add users to groups.
1679          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
1680          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
1681          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
1682          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
1683  
1684          // Send some private messages between user 1 and user 2.
1685          $pm1id = $this->create_message($user1->id, $user2->id, $now);
1686  
1687          // Get conversation.
1688          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1689          $component = 'core_group';
1690          $itemtype = 'groups';
1691          $conversation1 = \core_message\api::get_conversation_by_area(
1692              $component,
1693              $itemtype,
1694              $group1a->id,
1695              $coursecontext1->id
1696          );
1697  
1698          // Make favourite some conversations.
1699          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
1700          \core_message\api::set_favourite_conversation($iconversation1id, $user2->id);
1701  
1702          // Mute some conversations.
1703          \core_message\api::mute_conversation($user1->id, $conversation1->id);
1704          \core_message\api::mute_conversation($user2->id, $iconversation1id);
1705  
1706          // Send some messages to the conversation.
1707          $m1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
1708          $m2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
1709          $m3 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 3', $now + 3);
1710  
1711          $dbm1 = $DB->get_record('messages', ['id' => $m1]);
1712          $dbm2 = $DB->get_record('messages', ['id' => $m2]);
1713          $dbm3 = $DB->get_record('messages', ['id' => $m3]);
1714  
1715          // Mark as read and delete some messages.
1716          \core_message\api::mark_message_as_read($user1->id, $dbm3, $now + 5);
1717          \core_message\api::delete_message($user1->id, $m2);
1718  
1719          // Export all the conversations related to the groups in course1 for user1.
1720          provider::export_conversations($user1->id, 'core_group', 'groups', $coursecontext1);
1721  
1722          // Check that system context hasn't been exported.
1723          $writer = writer::with_context($systemcontext);
1724          $this->assertFalse($writer->has_any_data());
1725  
1726          // Check that course2 context hasn't been exported.
1727          $writer = writer::with_context($coursecontext2);
1728          $this->assertFalse($writer->has_any_data());
1729  
1730          // Check that course1 context has been exported for user1 and contains data.
1731          $writer = writer::with_context($coursecontext1);
1732          $this->assertTrue($writer->has_any_data());
1733  
1734          // Confirm the messages for conversation1 are correct.
1735          $messages = (array) $writer->get_data([
1736              get_string('messages', 'core_message'),
1737              get_string($conversation1->itemtype, $conversation1->component),
1738              get_string('privacy:export:conversationprefix', 'core_message') . $conversation1->name
1739          ]);
1740          $this->assertCount(3, $messages);
1741  
1742          usort($messages, ['static', 'sort_messages']);
1743          $m1 = array_shift($messages);
1744          $m2 = array_shift($messages);
1745          $m3 = array_shift($messages);
1746  
1747          // Check message 1 is correct.
1748          $this->assertEquals(get_string('yes'), $m1->issender);
1749          $this->assertEquals(message_format_message_text($dbm1), $m1->message);
1750          $this->assertEquals(transform::datetime($now + 1), $m1->timecreated);
1751          $this->assertEquals('-', $m1->timeread);
1752          $this->assertArrayNotHasKey('timedeleted', (array) $m1);
1753  
1754          // Check message 2 is correct.
1755          $this->assertEquals(get_string('yes'), $m2->issender);
1756          $this->assertEquals(message_format_message_text($dbm2), $m2->message);
1757          $this->assertEquals(transform::datetime($now + 2), $m2->timecreated);
1758          $this->assertEquals('-', $m2->timeread);
1759          $this->assertArrayHasKey('timedeleted', (array) $m2);
1760  
1761          // Check message 3 is correct.
1762          $this->assertEquals(get_string('no'), $m3->issender);
1763          $this->assertEquals(message_format_message_text($dbm3), $m3->message);
1764          $this->assertEquals(transform::datetime($now + 3), $m3->timecreated);
1765          $this->assertEquals(transform::datetime($now + 5), $m3->timeread);
1766          $this->assertArrayNotHasKey('timedeleted', (array) $m3);
1767  
1768          // Confirm the muted group conversation is correct.
1769          $mutedconversations = (array) $writer->get_related_data([
1770              get_string('messages', 'core_message'),
1771              get_string($conversation1->itemtype, $conversation1->component),
1772              get_string('privacy:export:conversationprefix', 'core_message') . $conversation1->name
1773          ], 'muted');
1774          $this->assertCount(2, $mutedconversations);
1775          $this->assertEquals(get_string('yes'), $mutedconversations['muted']);
1776  
1777          // Confirm the favourite group conversation is correct.
1778          $favourite = (array) $writer->get_related_data([
1779              get_string('messages', 'core_message'),
1780              get_string($conversation1->itemtype, $conversation1->component),
1781              get_string('privacy:export:conversationprefix', 'core_message') . $conversation1->name
1782          ], 'starred');
1783          $this->assertCount(4, $favourite);
1784          $this->assertEquals(get_string('yes'), $favourite['starred']);
1785  
1786          // Reset writer before exporting conversations for user2.
1787          writer::reset();
1788  
1789          // Export all the conversations related to the groups in course1 for user2.
1790          provider::export_conversations($user2->id, 'core_group', 'groups', $coursecontext1);
1791  
1792          // Check that system context hasn't been exported.
1793          $writer = writer::with_context($systemcontext);
1794          $this->assertFalse($writer->has_any_data());
1795  
1796          // Check that course2 context hasn't been exported.
1797          $writer = writer::with_context($coursecontext2);
1798          $this->assertFalse($writer->has_any_data());
1799  
1800          // Check that course1 context has been exported for user2 and contains data.
1801          $writer = writer::with_context($coursecontext1);
1802          $this->assertTrue($writer->has_any_data());
1803  
1804          // Confirm the messages for conversation1 are correct.
1805          $messages = (array) $writer->get_data([
1806              get_string('messages', 'core_message'),
1807              get_string($conversation1->itemtype, $conversation1->component),
1808              get_string('privacy:export:conversationprefix', 'core_message') . $conversation1->name
1809          ]);
1810          $this->assertCount(3, $messages);
1811  
1812          usort($messages, ['static', 'sort_messages']);
1813          $m1 = array_shift($messages);
1814          $m2 = array_shift($messages);
1815          $m3 = array_shift($messages);
1816  
1817          // Check message 1 is correct.
1818          $this->assertEquals(get_string('no'), $m1->issender);
1819          $this->assertEquals(message_format_message_text($dbm1), $m1->message);
1820          $this->assertEquals(transform::datetime($now + 1), $m1->timecreated);
1821          $this->assertEquals('-', $m1->timeread);
1822          $this->assertArrayNotHasKey('timedeleted', (array) $m1);
1823  
1824          // Check message 2 is correct.
1825          $this->assertEquals(get_string('no'), $m2->issender);
1826          $this->assertEquals(message_format_message_text($dbm2), $m2->message);
1827          $this->assertEquals(transform::datetime($now + 2), $m2->timecreated);
1828          $this->assertEquals('-', $m2->timeread);
1829          $this->assertArrayNotHasKey('timedeleted', (array) $m2);
1830  
1831          // Check message 3 is correct.
1832          $this->assertEquals(get_string('yes'), $m3->issender);
1833          $this->assertEquals(message_format_message_text($dbm3), $m3->message);
1834          $this->assertEquals(transform::datetime($now + 3), $m3->timecreated);
1835          $this->assertEquals('-', $m3->timeread);
1836          $this->assertArrayNotHasKey('timedeleted', (array) $m3);
1837  
1838          // Confirm the muted group conversation is correct.
1839          $mutedconversations = (array) $writer->get_related_data([
1840              get_string('messages', 'core_message'),
1841              get_string($conversation1->itemtype, $conversation1->component),
1842              $conversation1->name
1843          ], 'muted');
1844          $this->assertCount(0, $mutedconversations);
1845  
1846          // Confirm there are no favourite group conversation for user2.
1847          $favourite = (array) $writer->get_related_data([
1848              get_string('messages', 'core_message'),
1849              get_string($conversation1->itemtype, $conversation1->component),
1850              $conversation1->name
1851          ], 'starred');
1852          $this->assertCount(0, $favourite);
1853      }
1854  
1855      /**
1856       * Test for provider::delete_conversations_for_all_users().
1857       */
1858      public function test_delete_conversations_for_all_users() {
1859          global $DB;
1860  
1861          $this->resetAfterTest();
1862          $this->setAdminUser();
1863          $now = time();
1864          $timeread = $now - DAYSECS;
1865          $component = 'core_group';
1866          $itemtype = 'groups';
1867  
1868          // Create users to test with.
1869          $user1 = $this->getDataGenerator()->create_user();
1870          $user2 = $this->getDataGenerator()->create_user();
1871          $user3 = $this->getDataGenerator()->create_user();
1872          $user4 = $this->getDataGenerator()->create_user();
1873          $user5 = $this->getDataGenerator()->create_user();
1874          $user1context = \context_user::instance($user1->id);
1875  
1876          // Create contacts.
1877          \core_message\api::add_contact($user1->id, $user2->id);
1878          \core_message\api::add_contact($user2->id, $user3->id);
1879  
1880          // Create contact requests.
1881          \core_message\api::create_contact_request($user1->id, $user3->id);
1882          \core_message\api::create_contact_request($user2->id, $user4->id);
1883  
1884          // Block a user.
1885          \core_message\api::block_user($user1->id, $user3->id);
1886          \core_message\api::block_user($user3->id, $user4->id);
1887  
1888          // Create individual messages.
1889          $im1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
1890          $im2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS), true);
1891          $im3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
1892  
1893          // Create notifications.
1894          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
1895          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
1896          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
1897  
1898          // Delete one of the messages.
1899          \core_message\api::delete_message($user1->id, $im2);
1900  
1901          // Create course2.
1902          $course1 = $this->getDataGenerator()->create_course();
1903          $course2 = $this->getDataGenerator()->create_course();
1904          $coursecontext1 = \context_course::instance($course1->id);
1905          $coursecontext2 = \context_course::instance($course2->id);
1906  
1907          // Enrol users to courses.
1908          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1909          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1910          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1911          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1912          $this->getDataGenerator()->enrol_user($user2->id, $course2->id);
1913  
1914          // Create course groups with group messaging enabled.
1915          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
1916          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
1917  
1918          // Add users to groups.
1919          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
1920          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
1921          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
1922          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
1923          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user2->id));
1924  
1925          // Get conversations.
1926          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1927          $conversation1 = \core_message\api::get_conversation_by_area(
1928              $component,
1929              $itemtype,
1930              $group1a->id,
1931              $coursecontext1->id
1932          );
1933          $conversation2 = \core_message\api::get_conversation_by_area(
1934              $component,
1935              $itemtype,
1936              $group2a->id,
1937              $coursecontext2->id
1938          );
1939  
1940          // Make favourite some conversations.
1941          \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
1942          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
1943          \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
1944  
1945          // Send some messages to the conversation.
1946          $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
1947          $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
1948          $gm3 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 1.3', $now + 3);
1949          $gm4 = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 2.1', $now + 4);
1950          $gm5 = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2.2', $now + 5);
1951  
1952          $dbgm1 = $DB->get_record('messages', ['id' => $gm1]);
1953          $dbgm2 = $DB->get_record('messages', ['id' => $gm2]);
1954          $dbgm3 = $DB->get_record('messages', ['id' => $gm3]);
1955          $dbgm4 = $DB->get_record('messages', ['id' => $gm4]);
1956          $dbgm5 = $DB->get_record('messages', ['id' => $gm5]);
1957  
1958          // Mark as read one of the conversation messages.
1959          \core_message\api::mark_message_as_read($user1->id, $dbgm3, $now + 5);
1960  
1961          // Mark some conversations as muted by two users.
1962          \core_message\api::mute_conversation($user1->id, $iconversation1id);
1963          \core_message\api::mute_conversation($user1->id, $conversation1->id);
1964          \core_message\api::mute_conversation($user2->id, $conversation1->id);
1965  
1966          // There should be 2 contacts.
1967          $this->assertEquals(2, $DB->count_records('message_contacts'));
1968  
1969          // There should be 2 contact requests.
1970          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
1971  
1972          // There should be 2 blocked users.
1973          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
1974  
1975          // There should be 8 messages.
1976          $this->assertEquals(8, $DB->count_records('messages'));
1977  
1978          // There should be 4 user actions - 3 for reading the message, 1 for deleting.
1979          $this->assertEquals(4, $DB->count_records('message_user_actions'));
1980  
1981          // There should be 3 muted conversations.
1982          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
1983  
1984          // There should be 4 conversations - 2 individual + 2 group + 5 self-conversations.
1985          $this->assertEquals(9, $DB->count_records('message_conversations'));
1986  
1987          // There should be 9 conversation members - (2 + 2) individual + (3 + 2) group + 5 self-conversations.
1988          $this->assertEquals(14 , $DB->count_records('message_conversation_members'));
1989  
1990          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
1991          $this->assertEquals(5, $DB->count_records('notifications'));
1992  
1993          // There should be 3 favourite conversations + 5 self-conversations.
1994          $this->assertEquals(8, $DB->count_records('favourite'));
1995  
1996          // Delete conversations for all users in course1.
1997          provider::delete_conversations_for_all_users($coursecontext1, $component, $itemtype);
1998  
1999          // There should be still 2 contacts.
2000          $this->assertEquals(2, $DB->count_records('message_contacts'));
2001  
2002          // There should be still 2 contact requests.
2003          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2004  
2005          // There should be still 2 blocked users.
2006          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2007  
2008          // There should be 1 muted conversation.
2009          $this->assertEquals(1, $DB->count_records('message_conversation_actions'));
2010  
2011          // There should be 3 notifications.
2012          $this->assertEquals(5, $DB->count_records('notifications'));
2013  
2014          // There should be 5 messages - 3 individual - 2 group (course2).
2015          $this->assertEquals(5, $DB->count_records('messages'));
2016          $messages = $DB->get_records('messages');
2017          $this->assertArrayHasKey($im1, $messages);
2018          $this->assertArrayHasKey($im2, $messages);
2019          $this->assertArrayHasKey($im3, $messages);
2020          $this->assertArrayHasKey($gm4, $messages);
2021          $this->assertArrayHasKey($gm5, $messages);
2022  
2023          // There should be 3 user actions - 2 for reading the message, 1 for deleting.
2024          $this->assertEquals(3, $DB->count_records('message_user_actions'));
2025          $useractions = $DB->get_records('message_user_actions');
2026          $useractions = array_map(function($action) {
2027                  return $action->messageid;
2028          }, $useractions);
2029          $this->assertNotContains($gm3, $useractions);
2030  
2031          // There should be 3 conversations - 2 individual + 1 group (course2) + 5 self-conversations.
2032          $this->assertEquals(8, $DB->count_records('message_conversations'));
2033          $conversations = $DB->get_records('message_conversations');
2034          $this->assertArrayNotHasKey($conversation1->id, $conversations);
2035  
2036          // There should be 6 conversation members - (2 + 2) individual + 2 group + 5 self-conversations.
2037          $this->assertEquals(11, $DB->count_records('message_conversation_members'));
2038  
2039          // There should be 1 favourite conversation - the individual one + 5 self-conversations.
2040          $this->assertEquals(6, $DB->count_records('favourite'));
2041      }
2042  
2043      /**
2044       * Test for provider::delete_conversations_for_all_users() in the system context.
2045       */
2046      public function test_delete_conversations_for_all_users_systemcontext() {
2047          global $DB;
2048  
2049          $this->resetAfterTest();
2050          $this->setAdminUser();
2051          $now = time();
2052          $timeread = $now - DAYSECS;
2053          $systemcontext = \context_system::instance();
2054          $component = 'core_group';
2055          $itemtype = 'groups';
2056  
2057          // Create users to test with.
2058          $user1 = $this->getDataGenerator()->create_user();
2059          $user2 = $this->getDataGenerator()->create_user();
2060          $user3 = $this->getDataGenerator()->create_user();
2061          $user4 = $this->getDataGenerator()->create_user();
2062          $user5 = $this->getDataGenerator()->create_user();
2063  
2064          // Create contacts.
2065          \core_message\api::add_contact($user1->id, $user2->id);
2066          \core_message\api::add_contact($user2->id, $user3->id);
2067  
2068          // Create contact requests.
2069          \core_message\api::create_contact_request($user1->id, $user3->id);
2070          \core_message\api::create_contact_request($user2->id, $user4->id);
2071  
2072          // Block a user.
2073          \core_message\api::block_user($user1->id, $user3->id);
2074          \core_message\api::block_user($user3->id, $user4->id);
2075  
2076          // Create individual messages.
2077          $im1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
2078          $im2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS), true);
2079          $im3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
2080  
2081          // Create notifications.
2082          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
2083          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
2084          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
2085  
2086          // Delete one of the messages.
2087          \core_message\api::delete_message($user1->id, $im2);
2088  
2089          // Create course2.
2090          $course1 = $this->getDataGenerator()->create_course();
2091          $course2 = $this->getDataGenerator()->create_course();
2092          $coursecontext1 = \context_course::instance($course1->id);
2093          $coursecontext2 = \context_course::instance($course2->id);
2094  
2095          // Enrol users to courses.
2096          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2097          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2098          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
2099          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
2100          $this->getDataGenerator()->enrol_user($user2->id, $course2->id);
2101  
2102          // Create course groups with group messaging enabled.
2103          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
2104          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
2105  
2106          // Add users to groups.
2107          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
2108          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
2109          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
2110          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
2111          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user2->id));
2112  
2113          // Get conversations.
2114          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2115          $conversation1 = \core_message\api::get_conversation_by_area(
2116              $component,
2117              $itemtype,
2118              $group1a->id,
2119              $coursecontext1->id
2120          );
2121          $conversation2 = \core_message\api::get_conversation_by_area(
2122              $component,
2123              $itemtype,
2124              $group2a->id,
2125              $coursecontext2->id
2126          );
2127  
2128          // Make favourite some conversations.
2129          \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
2130          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
2131          \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
2132  
2133          // Send some messages to the conversation.
2134          $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
2135          $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
2136          $gm3 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 1.3', $now + 3);
2137          $gm4 = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 2.1', $now + 4);
2138          $gm5 = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2.2', $now + 5);
2139  
2140          $dbgm3 = $DB->get_record('messages', ['id' => $gm3]);
2141  
2142          // Mark some conversations as muted by two users.
2143          \core_message\api::mute_conversation($user1->id, $iconversation1id);
2144          \core_message\api::mute_conversation($user1->id, $conversation1->id);
2145          \core_message\api::mute_conversation($user2->id, $conversation1->id);
2146  
2147          // Mark as read one of the conversation messages.
2148          \core_message\api::mark_message_as_read($user1->id, $dbgm3, $now + 5);
2149  
2150          // There should be 2 contacts.
2151          $this->assertEquals(2, $DB->count_records('message_contacts'));
2152  
2153          // There should be 2 contact requests.
2154          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2155  
2156          // There should be 2 blocked users.
2157          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2158  
2159          // There should be 8 messages.
2160          $this->assertEquals(8, $DB->count_records('messages'));
2161  
2162          // There should be 4 user actions - 3 for reading the message, 1 for deleting.
2163          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2164  
2165          // There should be 3 muted conversations.
2166          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2167  
2168          // There should be 4 conversations - 2 individual + 2 group + 5 self-conversations.
2169          $this->assertEquals(9, $DB->count_records('message_conversations'));
2170  
2171          // There should be 9 conversation members - (2 + 2) individual + (3 + 2) group + 5 self-conversations.
2172          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2173  
2174          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
2175          $this->assertEquals(5, $DB->count_records('notifications'));
2176  
2177          // There should be 3 favourite conversations + 5 self-conversations.
2178          $this->assertEquals(8, $DB->count_records('favourite'));
2179  
2180          // Delete group conversations for all users in system context.
2181          provider::delete_conversations_for_all_users($systemcontext, $component, $itemtype);
2182  
2183          // No conversations should be removed, because they are in the course context.
2184          $this->assertEquals(2, $DB->count_records('message_contacts'));
2185          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2186          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2187          $this->assertEquals(8, $DB->count_records('messages'));
2188          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2189          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2190          $this->assertEquals(9, $DB->count_records('message_conversations'));
2191          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2192          $this->assertEquals(5, $DB->count_records('notifications'));
2193          $this->assertEquals(8, $DB->count_records('favourite'));
2194  
2195          // Delete individual conversations for all users in system context.
2196          provider::delete_conversations_for_all_users($systemcontext, '', '');
2197  
2198          // No conversations should be removed, because they've been moved to user context.
2199          $this->assertEquals(2, $DB->count_records('message_contacts'));
2200          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2201          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2202          $this->assertEquals(8, $DB->count_records('messages'));
2203          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2204          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2205          $this->assertEquals(9, $DB->count_records('message_conversations'));
2206          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2207          $this->assertEquals(5, $DB->count_records('notifications'));
2208          $this->assertEquals(8, $DB->count_records('favourite'));
2209      }
2210  
2211      /**
2212       * Test for provider::delete_conversations_for_all_users() in the user context.
2213       */
2214      public function test_delete_conversations_for_all_users_usercontext() {
2215          global $DB;
2216  
2217          $this->resetAfterTest();
2218          $this->setAdminUser();
2219          $now = time();
2220          $timeread = $now - DAYSECS;
2221          $component = 'core_group';
2222          $itemtype = 'groups';
2223  
2224          // Create users to test with.
2225          $user1 = $this->getDataGenerator()->create_user();
2226          $user2 = $this->getDataGenerator()->create_user();
2227          $user3 = $this->getDataGenerator()->create_user();
2228          $user4 = $this->getDataGenerator()->create_user();
2229          $user5 = $this->getDataGenerator()->create_user();
2230          $user1context = \context_user::instance($user1->id);
2231  
2232          // Create contacts.
2233          \core_message\api::add_contact($user1->id, $user2->id);
2234          \core_message\api::add_contact($user2->id, $user3->id);
2235  
2236          // Create contact requests.
2237          \core_message\api::create_contact_request($user1->id, $user3->id);
2238          \core_message\api::create_contact_request($user2->id, $user4->id);
2239  
2240          // Block a user.
2241          \core_message\api::block_user($user1->id, $user3->id);
2242          \core_message\api::block_user($user3->id, $user4->id);
2243  
2244          // Create individual messages.
2245          $im1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
2246          $im2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS), true);
2247          $im3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
2248  
2249          // Create notifications.
2250          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
2251          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
2252          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
2253  
2254          // Delete one of the messages.
2255          \core_message\api::delete_message($user1->id, $im2);
2256  
2257          // Create course2.
2258          $course1 = $this->getDataGenerator()->create_course();
2259          $course2 = $this->getDataGenerator()->create_course();
2260          $coursecontext1 = \context_course::instance($course1->id);
2261          $coursecontext2 = \context_course::instance($course2->id);
2262  
2263          // Enrol users to courses.
2264          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2265          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2266          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
2267          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
2268          $this->getDataGenerator()->enrol_user($user2->id, $course2->id);
2269  
2270          // Create course groups with group messaging enabled.
2271          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
2272          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
2273  
2274          // Add users to groups.
2275          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
2276          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
2277          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
2278          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user1->id));
2279          $this->getDataGenerator()->create_group_member(array('groupid' => $group2a->id, 'userid' => $user2->id));
2280  
2281          // Get conversation.
2282          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2283          $iconversation2id = \core_message\api::get_conversation_between_users([$user2->id, $user3->id]);
2284          $conversation1 = \core_message\api::get_conversation_by_area(
2285              $component,
2286              $itemtype,
2287              $group1a->id,
2288              $coursecontext1->id
2289          );
2290          $conversation2 = \core_message\api::get_conversation_by_area(
2291              $component,
2292              $itemtype,
2293              $group2a->id,
2294              $coursecontext2->id
2295          );
2296  
2297          // Make favourite some conversations.
2298          \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
2299          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
2300          \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
2301  
2302          // Send some messages to the conversation.
2303          $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.1', $now + 1);
2304          $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1.2', $now + 2);
2305          $gm3 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 1.3', $now + 3);
2306          $gm4 = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 2.1', $now + 4);
2307          $gm5 = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2.2', $now + 5);
2308  
2309          $dbgm3 = $DB->get_record('messages', ['id' => $gm3]);
2310  
2311          // Mark as read one of the conversation messages.
2312          \core_message\api::mark_message_as_read($user1->id, $dbgm3, $now + 5);
2313  
2314          // Mark some of the conversations as muted by two users.
2315          \core_message\api::mute_conversation($user1->id, $iconversation1id);
2316          \core_message\api::mute_conversation($user1->id, $conversation1->id);
2317          \core_message\api::mute_conversation($user2->id, $conversation1->id);
2318  
2319          // There should be 2 contacts.
2320          $this->assertEquals(2, $DB->count_records('message_contacts'));
2321  
2322          // There should be 2 contact requests.
2323          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2324  
2325          // There should be 2 blocked users.
2326          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2327  
2328          // There should be 8 messages - 3 individual + 5 group.
2329          $this->assertEquals(8, $DB->count_records('messages'));
2330  
2331          // There should be 4 user actions - 3 for reading the message, 1 for deleting.
2332          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2333  
2334          // There should be 3 muted conversations.
2335          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2336  
2337          // There should be 4 conversations - 2 individual + 2 group + 5 self-conversations.
2338          $this->assertEquals(9, $DB->count_records('message_conversations'));
2339  
2340          // There should be 9 conversation members - (2 + 2) individual + (3 + 2) group + 5 self-conversations.
2341          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2342  
2343          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
2344          $this->assertEquals(5, $DB->count_records('notifications'));
2345  
2346          // There should be 3 favourite conversations + 5 self-conversations.
2347          $this->assertEquals(8, $DB->count_records('favourite'));
2348  
2349          // Delete group conversations for all users in user context.
2350          provider::delete_conversations_for_all_users($user1context, $component, $itemtype);
2351  
2352          // No conversations should be removed, because they are in the course context.
2353          $this->assertEquals(2, $DB->count_records('message_contacts'));
2354          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2355          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2356          $this->assertEquals(8, $DB->count_records('messages'));
2357          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2358          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2359          $this->assertEquals(9, $DB->count_records('message_conversations'));
2360          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2361          $this->assertEquals(5, $DB->count_records('notifications'));
2362          $this->assertEquals(8, $DB->count_records('favourite'));
2363  
2364          // Delete individual conversations for all users in user context.
2365          provider::delete_conversations_for_all_users($user1context, '', '');
2366  
2367          // No conversations should be removed, because they are in the course context.
2368          $this->assertEquals(2, $DB->count_records('message_contacts'));
2369          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2370          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2371          $this->assertEquals(8, $DB->count_records('messages'));
2372          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2373          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2374          $this->assertEquals(9, $DB->count_records('message_conversations'));
2375          $this->assertEquals(14, $DB->count_records('message_conversation_members'));
2376          $this->assertEquals(5, $DB->count_records('notifications'));
2377          $this->assertEquals(8, $DB->count_records('favourite'));
2378      }
2379  
2380      /**
2381       * Test for provider::delete_conversations_for_user().
2382       */
2383      public function test_delete_conversations_for_user() {
2384          global $DB;
2385  
2386          $this->resetAfterTest();
2387          $this->setAdminUser();
2388          $now = time();
2389          $timeread = $now - DAYSECS;
2390          $systemcontext = \context_system::instance();
2391          $component = 'core_group';
2392          $itemtype = 'groups';
2393  
2394          // Create users to test with.
2395          $user1 = $this->getDataGenerator()->create_user();
2396          $user2 = $this->getDataGenerator()->create_user();
2397          $user3 = $this->getDataGenerator()->create_user();
2398          $user4 = $this->getDataGenerator()->create_user();
2399          $user5 = $this->getDataGenerator()->create_user();
2400          $user1context = \context_user::instance($user1->id);
2401  
2402          // Create contacts.
2403          \core_message\api::add_contact($user1->id, $user2->id);
2404          \core_message\api::add_contact($user2->id, $user3->id);
2405  
2406          // Create contact requests.
2407          \core_message\api::create_contact_request($user1->id, $user3->id);
2408          \core_message\api::create_contact_request($user2->id, $user4->id);
2409  
2410          // Block a user.
2411          \core_message\api::block_user($user1->id, $user3->id);
2412          \core_message\api::block_user($user3->id, $user4->id);
2413  
2414          // Create private messages.
2415          $pm1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
2416          $pm2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS), true);
2417          $pm3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
2418  
2419          // Create notifications.
2420          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
2421          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
2422          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
2423  
2424          // Delete one of the messages.
2425          \core_message\api::delete_message($user1->id, $pm2);
2426  
2427          // Create course.
2428          $course1 = $this->getDataGenerator()->create_course();
2429          $course2 = $this->getDataGenerator()->create_course();
2430          $coursecontext1 = \context_course::instance($course1->id);
2431          $coursecontext2 = \context_course::instance($course2->id);
2432  
2433          // Enrol users to courses.
2434          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2435          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2436          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
2437          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
2438  
2439          // Create course groups with group messaging enabled.
2440          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
2441  
2442          // Add users to groups.
2443          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
2444          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
2445          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
2446  
2447          // Get conversation.
2448          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2449          $conversation1 = \core_message\api::get_conversation_by_area(
2450              $component,
2451              $itemtype,
2452              $group1a->id,
2453              $coursecontext1->id
2454          );
2455  
2456          // Make favourite some conversations.
2457          \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
2458          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
2459          \core_message\api::set_favourite_conversation($conversation1->id, $user2->id);
2460  
2461          // Send some messages to the conversation.
2462          $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
2463          $gm2 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 2', $now + 2);
2464          $gm3 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 3', $now + 3);
2465  
2466          $dbm3 = $DB->get_record('messages', ['id' => $gm3]);
2467  
2468          // Mark as read one of the conversation messages.
2469          \core_message\api::mark_message_as_read($user1->id, $dbm3, $now + 5);
2470  
2471          // Mark some of the conversations as muted by two users.
2472          \core_message\api::mute_conversation($user1->id, $iconversation1id);
2473          \core_message\api::mute_conversation($user1->id, $conversation1->id);
2474          \core_message\api::mute_conversation($user2->id, $conversation1->id);
2475  
2476          // There should be 2 contacts.
2477          $this->assertEquals(2, $DB->count_records('message_contacts'));
2478  
2479          // There should be 2 contact requests.
2480          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2481  
2482          // There should be 2 blocked users.
2483          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2484  
2485          // There should be 5 notifications.
2486          $this->assertEquals(5, $DB->count_records('notifications'));
2487  
2488          // There should be 6 messages.
2489          $this->assertEquals(6, $DB->count_records('messages'));
2490  
2491          // There should be 4 user actions - 3 for reading the message, one for deleting.
2492          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2493  
2494          // There should be 3 users muting a conversation.
2495          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2496  
2497          // There should be 3 conversations - 2 private + 1 group + 5 self-conversations.
2498          $this->assertEquals(8, $DB->count_records('message_conversations'));
2499  
2500          // There should be 7 conversation members - 2 + 2 private conversations + 3 group conversation + 5 self-conversations.
2501          $this->assertEquals(12, $DB->count_records('message_conversation_members'));
2502          $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation1->id]);
2503          $members = array_map(function($member) {
2504                  return $member->userid;
2505          }, $members);
2506          $this->assertContains($user1->id, $members);
2507  
2508          // There should be three favourite conversations + 5 self-conversations.
2509          $this->assertEquals(8, $DB->count_records('favourite'));
2510  
2511          // Delete group conversations for user1 in course1 and course2.
2512          $approvedcontextlist = new \core_privacy\tests\request\approved_contextlist($user1, 'core_message',
2513                  [$coursecontext1->id, $coursecontext2->id]);
2514          provider::delete_conversations_for_user($approvedcontextlist, $component, $itemtype);
2515  
2516          // There should be still 2 contacts.
2517          $this->assertEquals(2, $DB->count_records('message_contacts'));
2518  
2519          // There should be still 2 contact requests.
2520          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2521  
2522          // There should be still 2 blocked users.
2523          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2524  
2525          // There should be 2 muted conversation.
2526          $this->assertEquals(2, $DB->count_records('message_conversation_actions'));
2527  
2528          // There should be 3 notifications.
2529          $this->assertEquals(5, $DB->count_records('notifications'));
2530  
2531          // There should be 4 messages - 3 private + 1 group sent by user2.
2532          $this->assertEquals(4, $DB->count_records('messages'));
2533          $messages = $DB->get_records('messages');
2534          $this->assertArrayHasKey($pm1, $messages);
2535          $this->assertArrayHasKey($pm2, $messages);
2536          $this->assertArrayHasKey($pm3, $messages);
2537          $this->assertArrayHasKey($gm3, $messages);
2538  
2539          // There should be 3 user actions - 2 for reading the message, one for deleting.
2540          $this->assertEquals(3, $DB->count_records('message_user_actions'));
2541          $useractions = $DB->get_records('message_user_actions');
2542          $useractions = array_map(function($action) {
2543                  return $action->messageid;
2544          }, $useractions);
2545          $this->assertNotContains($gm3, $useractions);
2546  
2547          // There should be still 3 conversations - 2 private + 1 group + 5 self-conversations.
2548          $this->assertEquals(8, $DB->count_records('message_conversations'));
2549  
2550          // There should be 6 conversation members - 2 + 2 private conversations + 2 group conversation + 5 self-conversations.
2551          $this->assertEquals(11, $DB->count_records('message_conversation_members'));
2552          $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation1->id]);
2553          $members = array_map(function($member) {
2554                  return $member->userid;
2555          }, $members);
2556          $this->assertNotContains($user1->id, $members);
2557  
2558          // Unset favourite self-conversations.
2559          $this->remove_user_self_conversation($user1->id);
2560          $this->remove_user_self_conversation($user2->id);
2561          $this->remove_user_self_conversation($user3->id);
2562          $this->remove_user_self_conversation($user4->id);
2563          $this->remove_user_self_conversation($user5->id);
2564  
2565          // There should be 2 favourite conversations - 2 group.
2566          $this->assertEquals(2, $DB->count_records('favourite'));
2567          $favourites = $DB->get_records('favourite');
2568          foreach ($favourites as $favourite) {
2569              if ($favourite->userid == $user1->id) {
2570                  $this->assertEquals($iconversation1id, $favourite->itemid);
2571              } else if ($favourite->userid == $user2->id) {
2572                  $this->assertEquals($conversation1->id, $favourite->itemid);
2573              }
2574          }
2575      }
2576  
2577  
2578      /**
2579       * Test for provider::delete_conversations_for_users().
2580       */
2581      public function test_delete_conversations_for_users() {
2582          global $DB;
2583  
2584          $this->resetAfterTest();
2585          $this->setAdminUser();
2586          $now = time();
2587          $timeread = $now - DAYSECS;
2588          $systemcontext = \context_system::instance();
2589          $component = 'core_group';
2590          $itemtype = 'groups';
2591  
2592          // Create users to test with.
2593          $user1 = $this->getDataGenerator()->create_user();
2594          $user2 = $this->getDataGenerator()->create_user();
2595          $user3 = $this->getDataGenerator()->create_user();
2596          $user4 = $this->getDataGenerator()->create_user();
2597          $user5 = $this->getDataGenerator()->create_user();
2598          $user1context = \context_user::instance($user1->id);
2599  
2600          // Create contacts.
2601          \core_message\api::add_contact($user1->id, $user2->id);
2602          \core_message\api::add_contact($user2->id, $user3->id);
2603  
2604          // Create contact requests.
2605          \core_message\api::create_contact_request($user1->id, $user3->id);
2606          \core_message\api::create_contact_request($user2->id, $user4->id);
2607  
2608          // Block a user.
2609          \core_message\api::block_user($user1->id, $user3->id);
2610          \core_message\api::block_user($user3->id, $user4->id);
2611  
2612          // Create private messages.
2613          $pm1 = $this->create_message($user1->id, $user2->id, $now + (9 * DAYSECS), true);
2614          $pm2 = $this->create_message($user2->id, $user1->id, $now + (8 * DAYSECS), true);
2615          $pm3 = $this->create_message($user2->id, $user3->id, $now + (7 * DAYSECS));
2616  
2617          // Create notifications.
2618          $n1 = $this->create_notification($user1->id, $user2->id, $now + (9 * DAYSECS), $timeread);
2619          $n2 = $this->create_notification($user2->id, $user1->id, $now + (8 * DAYSECS));
2620          $n3 = $this->create_notification($user2->id, $user3->id, $now + (7 * DAYSECS));
2621  
2622          // Delete one of the messages.
2623          \core_message\api::delete_message($user1->id, $pm2);
2624  
2625          // Create course.
2626          $course1 = $this->getDataGenerator()->create_course();
2627          $course2 = $this->getDataGenerator()->create_course();
2628          $coursecontext1 = \context_course::instance($course1->id);
2629          $coursecontext2 = \context_course::instance($course2->id);
2630  
2631          // Enrol users to courses.
2632          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2633          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2634          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
2635          $this->getDataGenerator()->enrol_user($user4->id, $course1->id);
2636          $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
2637  
2638          // Create course groups with group messaging enabled.
2639          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
2640          $group2a = $this->getDataGenerator()->create_group(array('courseid' => $course2->id, 'enablemessaging' => 1));
2641  
2642          // Add users to groups.
2643          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user1->id));
2644          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user2->id));
2645          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user3->id));
2646          $this->getDataGenerator()->create_group_member(array('groupid' => $group1a->id, 'userid' => $user4->id));
2647  
2648          // Get conversation.
2649          $iconversation1id = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2650          $conversation1 = \core_message\api::get_conversation_by_area(
2651              $component,
2652              $itemtype,
2653              $group1a->id,
2654              $coursecontext1->id
2655          );
2656  
2657          // Make favourite some conversations.
2658          \core_message\api::set_favourite_conversation($iconversation1id, $user1->id);
2659          \core_message\api::set_favourite_conversation($conversation1->id, $user1->id);
2660          \core_message\api::set_favourite_conversation($conversation1->id, $user3->id);
2661  
2662          // Send some messages to the conversation.
2663          $gm1 = testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1', $now + 1);
2664          $gm2 = testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2', $now + 2);
2665          $gm3 = testhelper::send_fake_message_to_conversation($user3, $conversation1->id, 'Message 3', $now + 3);
2666  
2667          $dbm3 = $DB->get_record('messages', ['id' => $gm3]);
2668  
2669          // Mark as read one of the conversation messages.
2670          \core_message\api::mark_message_as_read($user1->id, $dbm3, $now + 5);
2671  
2672          // Mark some of the conversations as muted by two users.
2673          \core_message\api::mute_conversation($user1->id, $iconversation1id);
2674          \core_message\api::mute_conversation($user1->id, $conversation1->id);
2675          \core_message\api::mute_conversation($user2->id, $conversation1->id);
2676  
2677          // There should be 2 contacts.
2678          $this->assertEquals(2, $DB->count_records('message_contacts'));
2679  
2680          // There should be 2 contact requests.
2681          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2682  
2683          // There should be 2 blocked users.
2684          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2685  
2686          // There should be 5 notifications (3 from create_notification and 2 from create_contact_request).
2687          $this->assertEquals(5, $DB->count_records('notifications'));
2688  
2689          // There should be 6 messages.
2690          $this->assertEquals(6, $DB->count_records('messages'));
2691  
2692          // There should be 4 user actions - 3 for reading the message, one for deleting.
2693          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2694  
2695          // There should be 3 muted conversation.
2696          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2697  
2698          // There should be 3 conversations - 2 private + 2 group + 5 self-conversations.
2699          $this->assertEquals(9, $DB->count_records('message_conversations'));
2700  
2701          // There should be 8 conversation members - (2 + 2) private + 4 group + 5 self-conversations.
2702          $this->assertEquals(13, $DB->count_records('message_conversation_members'));
2703          $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation1->id]);
2704          $members = array_map(function($member) {
2705                  return $member->userid;
2706          }, $members);
2707          $this->assertContains($user1->id, $members);
2708          $this->assertContains($user4->id, $members);
2709  
2710          // There should be 3 favourite conversations + 5 self-conversations.
2711          $this->assertEquals(8, $DB->count_records('favourite'));
2712  
2713          // Delete group conversations for user1 and user2 in course2 context.
2714          $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext2, 'core_message',
2715                  [$user1->id, $user2->id]);
2716          provider::delete_conversations_for_users($approveduserlist, $component, $itemtype);
2717  
2718          // There should be exactly the same content, because $user1 and $user2 don't belong to any group in course2).
2719          $this->assertEquals(2, $DB->count_records('message_contacts'));
2720          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2721          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2722          $this->assertEquals(5, $DB->count_records('notifications'));
2723          $this->assertEquals(6, $DB->count_records('messages'));
2724          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2725          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2726          $this->assertEquals(9, $DB->count_records('message_conversations'));
2727          $this->assertEquals(13, $DB->count_records('message_conversation_members'));
2728          $this->assertEquals(8, $DB->count_records('favourite'));
2729  
2730          // Delete group conversations for user4 in course1 context.
2731          $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext1, 'core_message',
2732                  [$user4->id]);
2733          provider::delete_conversations_for_users($approveduserlist, $component, $itemtype);
2734  
2735          // There should be the same content except for the members (to remove user4 from the group1 in course1).
2736          $this->assertEquals(2, $DB->count_records('message_contacts'));
2737          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2738          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2739          $this->assertEquals(5, $DB->count_records('notifications'));
2740          $this->assertEquals(6, $DB->count_records('messages'));
2741          $this->assertEquals(4, $DB->count_records('message_user_actions'));
2742          $this->assertEquals(3, $DB->count_records('message_conversation_actions'));
2743          $this->assertEquals(9, $DB->count_records('message_conversations'));
2744          $this->assertEquals(8, $DB->count_records('favourite'));
2745          // There should be 7 conversation members - (2 + 2) private + 3 group + 5 self-conversations.
2746          $this->assertEquals(12, $DB->count_records('message_conversation_members'));
2747  
2748          // Delete group conversations for user1 and user2 in course1 context.
2749          $approveduserlist = new \core_privacy\local\request\approved_userlist($coursecontext1, 'core_message',
2750                  [$user1->id, $user2->id]);
2751          provider::delete_conversations_for_users($approveduserlist, $component, $itemtype);
2752  
2753          // There should be still 2 contacts.
2754          $this->assertEquals(2, $DB->count_records('message_contacts'));
2755  
2756          // There should be still 2 contact requests.
2757          $this->assertEquals(2, $DB->count_records('message_contact_requests'));
2758  
2759          // There should be still 2 blocked users.
2760          $this->assertEquals(2, $DB->count_records('message_users_blocked'));
2761  
2762          // There should be 5 notifications.
2763          $this->assertEquals(5, $DB->count_records('notifications'));
2764  
2765          // There should be 4 messages - 3 private + 1 group sent by user3.
2766          $this->assertEquals(4, $DB->count_records('messages'));
2767          $messages = $DB->get_records('messages');
2768          $this->assertArrayHasKey($pm1, $messages);
2769          $this->assertArrayHasKey($pm2, $messages);
2770          $this->assertArrayHasKey($pm3, $messages);
2771          $this->assertArrayHasKey($gm3, $messages);
2772  
2773          // There should be 3 user actions - 2 for reading the message, one for deleting.
2774          $this->assertEquals(3, $DB->count_records('message_user_actions'));
2775          $useractions = $DB->get_records('message_user_actions');
2776          $useractions = array_map(function($action) {
2777                  return $action->messageid;
2778          }, $useractions);
2779          $this->assertNotContains($gm3, $useractions);
2780  
2781          // There should be 1 muted conversation.
2782          $this->assertEquals(1, $DB->count_records('message_conversation_actions'));
2783  
2784          // There should be still 4 conversations - 2 private + 2 group + 5 self-conversations.
2785          $this->assertEquals(9, $DB->count_records('message_conversations'));
2786  
2787          // There should be 5 conversation members - (2 + 2) private + 1 group + 5 self-conversations.
2788          $this->assertEquals(10, $DB->count_records('message_conversation_members'));
2789          $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation1->id]);
2790          $members = array_map(function($member) {
2791                  return $member->userid;
2792          }, $members);
2793          $this->assertNotContains($user1->id, $members);
2794          $this->assertNotContains($user2->id, $members);
2795  
2796          // Unset favourite self-conversations.
2797          $this->remove_user_self_conversation($user1->id);
2798          $this->remove_user_self_conversation($user2->id);
2799          $this->remove_user_self_conversation($user3->id);
2800          $this->remove_user_self_conversation($user4->id);
2801          $this->remove_user_self_conversation($user5->id);
2802  
2803          // There should be 2 favourite conversations - user1 individual + user3 group.
2804          $this->assertEquals(2, $DB->count_records('favourite'));
2805          $favourites = $DB->get_records('favourite');
2806          foreach ($favourites as $favourite) {
2807              if ($favourite->userid == $user1->id) {
2808                  $this->assertEquals($iconversation1id, $favourite->itemid);
2809              } else if ($favourite->userid == $user3->id) {
2810                  $this->assertEquals($conversation1->id, $favourite->itemid);
2811              }
2812          }
2813      }
2814  
2815      /**
2816       * Creates a message to be used for testing.
2817       *
2818       * @param int $useridfrom The user id from
2819       * @param int $useridto The user id to
2820       * @param int $timecreated
2821       * @param bool $read Do we want to mark the message as read?
2822       * @return int The id of the message
2823       * @throws dml_exception
2824       */
2825      private function create_message(int $useridfrom, int $useridto, int $timecreated = null, bool $read = false) {
2826          global $DB;
2827  
2828          static $i = 1;
2829  
2830          if (is_null($timecreated)) {
2831              $timecreated = time();
2832          }
2833  
2834          if (!$conversationid = \core_message\api::get_conversation_between_users([$useridfrom, $useridto])) {
2835              $conversation = \core_message\api::create_conversation(
2836                  \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2837                  [
2838                      $useridfrom,
2839                      $useridto
2840                  ]
2841              );
2842              $conversationid = $conversation->id;
2843          }
2844  
2845          // Ok, send the message.
2846          $record = new \stdClass();
2847          $record->useridfrom = $useridfrom;
2848          $record->conversationid = $conversationid;
2849          $record->subject = 'No subject';
2850          $record->fullmessage = 'A rad message ' . $i;
2851          $record->smallmessage = 'A rad message ' . $i;
2852          $record->timecreated = $timecreated;
2853          $record->customdata = json_encode(['akey' => 'avalue']);
2854  
2855          $i++;
2856  
2857          $record->id = $DB->insert_record('messages', $record);
2858  
2859          if ($read) {
2860              \core_message\api::mark_message_as_read($useridto, $record);
2861          }
2862  
2863          return $record->id;
2864      }
2865  
2866      /**
2867       * Creates a notification to be used for testing.
2868       *
2869       * @param int $useridfrom The user id from
2870       * @param int $useridto The user id to
2871       * @param int|null $timecreated The time the notification was created
2872       * @param int|null $timeread The time the notification was read, null if it hasn't been.
2873       * @return int The id of the notification
2874       * @throws dml_exception
2875       */
2876      private function create_notification(int $useridfrom, int $useridto, int $timecreated = null, int $timeread = null) {
2877          global $DB;
2878  
2879          static $i = 1;
2880  
2881          if (is_null($timecreated)) {
2882              $timecreated = time();
2883          }
2884  
2885          $record = new \stdClass();
2886          $record->useridfrom = $useridfrom;
2887          $record->useridto = $useridto;
2888          $record->subject = 'No subject';
2889          $record->fullmessage = 'Some rad notification ' . $i;
2890          $record->smallmessage = 'Yo homie, you got some stuff to do, yolo. ' . $i;
2891          $record->timeread = $timeread;
2892          $record->timecreated = $timecreated;
2893          $record->customdata = json_encode(['akey' => 'avalue']);
2894  
2895          $i++;
2896  
2897          return $DB->insert_record('notifications', $record);
2898      }
2899  
2900      /**
2901       * Comparison function for sorting messages.
2902       *
2903       * @param   \stdClass $a
2904       * @param   \stdClass $b
2905       * @return  bool
2906       */
2907      protected static function sort_messages($a, $b) {
2908          return strcmp($a->message, $b->message);
2909      }
2910  
2911      /**
2912       * Comparison function for sorting contacts.
2913       *
2914       * @param   \stdClass $a
2915       * @param   \stdClass $b
2916       * @return  bool
2917       */
2918      protected static function sort_contacts($a, $b) {
2919          // Contact attribute contains user id.
2920          return $a->contact <=> $b->contact;
2921      }
2922  
2923      /**
2924       * Function to unset favourite and delete all conversation data for a user's self-conversation.
2925       *
2926       * @param int $userid The user id
2927       * @return  void
2928       * @throws moodle_exception
2929       */
2930      protected static function remove_user_self_conversation(int $userid) {
2931          $selfconversation = \core_message\api::get_self_conversation($userid);
2932          \core_message\api::unset_favourite_conversation($selfconversation->id, $userid);
2933          \core_message\api::delete_all_conversation_data($selfconversation->id);
2934      }
2935  }