Search moodle.org's
Developer Documentation

See Release Notes

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

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

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