Search moodle.org's
Developer Documentation

See Release Notes

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

Differences Between: [Versions 39 and 310]

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