See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [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 namespace core_message; 18 19 use core_message\tests\helper as testhelper; 20 21 defined('MOODLE_INTERNAL') || die(); 22 23 global $CFG; 24 25 require_once($CFG->dirroot . '/message/tests/messagelib_test.php'); 26 27 /** 28 * Test message API. 29 * 30 * @package core_message 31 * @category test 32 * @copyright 2016 Mark Nelson <markn@moodle.com> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class api_test extends messagelib_test { 36 37 public function test_mark_all_read_for_user_touser() { 38 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1')); 39 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2')); 40 41 $this->send_fake_message($sender, $recipient, 'Notification', 1); 42 $this->send_fake_message($sender, $recipient, 'Notification', 1); 43 $this->send_fake_message($sender, $recipient, 'Notification', 1); 44 $this->send_fake_message($sender, $recipient); 45 $this->send_fake_message($sender, $recipient); 46 $this->send_fake_message($sender, $recipient); 47 48 api::mark_all_notifications_as_read($recipient->id); 49 api::mark_all_messages_as_read($recipient->id); 50 51 $this->assertEquals(message_count_unread_messages($recipient), 0); 52 $this->assertDebuggingCalled(); 53 } 54 55 public function test_mark_all_read_for_user_touser_with_fromuser() { 56 $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1')); 57 $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3')); 58 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2')); 59 60 $this->send_fake_message($sender1, $recipient, 'Notification', 1); 61 $this->send_fake_message($sender1, $recipient, 'Notification', 1); 62 $this->send_fake_message($sender1, $recipient, 'Notification', 1); 63 $this->send_fake_message($sender1, $recipient); 64 $this->send_fake_message($sender1, $recipient); 65 $this->send_fake_message($sender1, $recipient); 66 $this->send_fake_message($sender2, $recipient, 'Notification', 1); 67 $this->send_fake_message($sender2, $recipient, 'Notification', 1); 68 $this->send_fake_message($sender2, $recipient, 'Notification', 1); 69 $this->send_fake_message($sender2, $recipient); 70 $this->send_fake_message($sender2, $recipient); 71 $this->send_fake_message($sender2, $recipient); 72 73 api::mark_all_notifications_as_read($recipient->id, $sender1->id); 74 $conversationid = api::get_conversation_between_users([$recipient->id, $sender1->id]); 75 api::mark_all_messages_as_read($recipient->id, $conversationid); 76 77 $this->assertEquals(message_count_unread_messages($recipient), 3); 78 $this->assertDebuggingCalled(); 79 } 80 81 public function test_mark_all_read_for_user_touser_with_type() { 82 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1')); 83 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2')); 84 85 $this->send_fake_message($sender, $recipient, 'Notification', 1); 86 $this->send_fake_message($sender, $recipient, 'Notification', 1); 87 $this->send_fake_message($sender, $recipient, 'Notification', 1); 88 $this->send_fake_message($sender, $recipient); 89 $this->send_fake_message($sender, $recipient); 90 $this->send_fake_message($sender, $recipient); 91 92 api::mark_all_notifications_as_read($recipient->id); 93 $this->assertEquals(message_count_unread_messages($recipient), 3); 94 $this->assertDebuggingCalled(); 95 96 api::mark_all_messages_as_read($recipient->id); 97 $this->assertEquals(message_count_unread_messages($recipient), 0); 98 $this->assertDebuggingCalled(); 99 } 100 101 /** 102 * Test count_blocked_users. 103 */ 104 public function test_count_blocked_users() { 105 global $USER; 106 107 // Set this user as the admin. 108 $this->setAdminUser(); 109 110 // Create user to add to the admin's block list. 111 $user1 = $this->getDataGenerator()->create_user(); 112 $user2 = $this->getDataGenerator()->create_user(); 113 114 $this->assertEquals(0, api::count_blocked_users()); 115 116 // Add 1 blocked user to admin's blocked user list. 117 api::block_user($USER->id, $user1->id); 118 119 $this->assertEquals(0, api::count_blocked_users($user1)); 120 $this->assertEquals(1, api::count_blocked_users()); 121 } 122 123 /** 124 * Tests searching for users when site-wide messaging is disabled. 125 * 126 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view. 127 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's 128 * profile. 129 */ 130 public function test_message_search_users_messagingallusers_disabled() { 131 global $DB; 132 $this->resetAfterTest(); 133 134 // Create some users. 135 $users = []; 136 foreach (range(1, 8) as $i) { 137 $user = new \stdClass(); 138 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 139 $user->lastname = $i; 140 $user = $this->getDataGenerator()->create_user($user); 141 $users[$i] = $user; 142 } 143 144 // Enrol a few users in the same course, but leave them as non-contacts. 145 $course1 = $this->getDataGenerator()->create_course(); 146 $course2 = $this->getDataGenerator()->create_course(); 147 148 $this->setAdminUser(); 149 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id); 150 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id); 151 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id); 152 153 // Add some other users as contacts. 154 api::add_contact($users[1]->id, $users[2]->id); 155 api::add_contact($users[3]->id, $users[1]->id); 156 api::add_contact($users[1]->id, $users[4]->id); 157 158 // Enrol a user as a teacher in the course, and make the teacher role a course contact role. 159 $this->getDataGenerator()->enrol_user($users[8]->id, $course2->id, 'editingteacher'); 160 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 161 set_config('coursecontact', $teacherrole->id); 162 163 // Create individual conversations between some users, one contact and one non-contact. 164 $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 165 [$users[1]->id, $users[2]->id]); 166 $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 167 [$users[6]->id, $users[1]->id]); 168 169 // Create a group conversation between 4 users, including a contact and a non-contact. 170 $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 171 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat'); 172 173 // Set as the user performing the search. 174 $this->setUser($users[1]); 175 176 // Perform a search with $CFG->messagingallusers disabled. 177 set_config('messagingallusers', 0); 178 $result = api::message_search_users($users[1]->id, 'search'); 179 180 // Confirm that we returns contacts and non-contacts. 181 $this->assertArrayHasKey(0, $result); 182 $this->assertArrayHasKey(1, $result); 183 $contacts = $result[0]; 184 $noncontacts = $result[1]; 185 186 // Check that we retrieved the correct contacts. 187 $this->assertCount(2, $contacts); 188 $this->assertEquals($users[2]->id, $contacts[0]->id); 189 $this->assertEquals($users[3]->id, $contacts[1]->id); 190 191 // Verify the correct conversations were returned for the contacts. 192 $this->assertCount(2, $contacts[0]->conversations); 193 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type); 194 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type); 195 196 $this->assertCount(0, $contacts[1]->conversations); 197 198 // Check that we retrieved the correct non-contacts. 199 // When site wide messaging is disabled, we expect to see only those users who we share a course with and whose profiles 200 // are visible in that course. This excludes users like course contacts. 201 $this->assertCount(3, $noncontacts); 202 // Self-conversation first. 203 $this->assertEquals($users[1]->id, $noncontacts[0]->id); 204 $this->assertEquals($users[6]->id, $noncontacts[1]->id); 205 $this->assertEquals($users[7]->id, $noncontacts[2]->id); 206 207 // Verify the correct conversations were returned for the non-contacts. 208 $this->assertCount(1, $noncontacts[1]->conversations); 209 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 210 $noncontacts[1]->conversations[$ic2->id]->type); 211 212 $this->assertCount(1, $noncontacts[2]->conversations); 213 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type); 214 } 215 216 /** 217 * Tests searching for users when site-wide messaging is enabled. 218 * 219 * This test verifies that any contacts are returned, as well as any non-contacts, 220 * provided the searching user can view their profile. 221 */ 222 public function test_message_search_users_messagingallusers_enabled() { 223 global $DB; 224 $this->resetAfterTest(); 225 226 // Create some users. 227 $users = []; 228 foreach (range(1, 9) as $i) { 229 $user = new \stdClass(); 230 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 231 $user->lastname = $i; 232 $user = $this->getDataGenerator()->create_user($user); 233 $users[$i] = $user; 234 } 235 236 $course1 = $this->getDataGenerator()->create_course(); 237 $coursecontext = \context_course::instance($course1->id); 238 239 // Enrol a few users in the same course, but leave them as non-contacts. 240 $this->setAdminUser(); 241 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id, 'student'); 242 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id, 'student'); 243 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id, 'student'); 244 245 // Add some other users as contacts. 246 api::add_contact($users[1]->id, $users[2]->id); 247 api::add_contact($users[3]->id, $users[1]->id); 248 api::add_contact($users[1]->id, $users[4]->id); 249 250 // Enrol a user as a teacher in the course, and make the teacher role a course contact role. 251 $this->getDataGenerator()->enrol_user($users[9]->id, $course1->id, 'editingteacher'); 252 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 253 set_config('coursecontact', $teacherrole->id); 254 255 // Get self-conversation. 256 $selfconversation = api::get_self_conversation($users[1]->id); 257 258 // Create individual conversations between some users, one contact and one non-contact. 259 $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 260 [$users[1]->id, $users[2]->id]); 261 $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 262 [$users[6]->id, $users[1]->id]); 263 264 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course. 265 $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 266 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat'); 267 268 // Set as the user performing the search. 269 $this->setUser($users[1]); 270 271 // Perform a search with $CFG->messagingallusers enabled. 272 set_config('messagingallusers', 1); 273 $result = api::message_search_users($users[1]->id, 'search'); 274 275 // Confirm that we returns contacts and non-contacts. 276 $this->assertArrayHasKey(0, $result); 277 $this->assertArrayHasKey(1, $result); 278 $contacts = $result[0]; 279 $noncontacts = $result[1]; 280 281 // Check that we retrieved the correct contacts. 282 $this->assertCount(2, $contacts); 283 $this->assertEquals($users[2]->id, $contacts[0]->id); 284 $this->assertEquals($users[3]->id, $contacts[1]->id); 285 286 // Verify the correct conversations were returned for the contacts. 287 $this->assertCount(2, $contacts[0]->conversations); 288 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type); 289 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type); 290 291 $this->assertCount(0, $contacts[1]->conversations); 292 293 // Check that we retrieved the correct non-contacts. 294 // If site wide messaging is enabled, we expect to only be able to search for users whose profiles we can view. 295 // In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1. 296 // Consider first conversations is self-conversation. 297 $this->assertCount(4, $noncontacts); 298 $this->assertEquals($users[1]->id, $noncontacts[0]->id); 299 $this->assertEquals($users[6]->id, $noncontacts[1]->id); 300 $this->assertEquals($users[7]->id, $noncontacts[2]->id); 301 $this->assertEquals($users[9]->id, $noncontacts[3]->id); 302 303 $this->assertCount(1, $noncontacts[1]->conversations); 304 $this->assertCount(1, $noncontacts[2]->conversations); 305 $this->assertCount(0, $noncontacts[3]->conversations); 306 307 // Verify the correct conversations were returned for the non-contacts. 308 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF, 309 $noncontacts[0]->conversations[$selfconversation->id]->type); 310 311 $this->assertCount(1, $noncontacts[1]->conversations); 312 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 313 $noncontacts[1]->conversations[$ic2->id]->type); 314 315 $this->assertCount(1, $noncontacts[2]->conversations); 316 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type); 317 318 $this->assertCount(0, $noncontacts[3]->conversations); 319 } 320 321 /** 322 * Verify searching for users find themselves when they have self-conversations. 323 */ 324 public function test_message_search_users_self_conversations() { 325 $this->resetAfterTest(); 326 327 // Create some users. 328 $user1 = new \stdClass(); 329 $user1->firstname = 'User'; 330 $user1->lastname = 'One'; 331 $user1 = $this->getDataGenerator()->create_user($user1); 332 $user2 = new \stdClass(); 333 $user2->firstname = 'User'; 334 $user2->lastname = 'Two'; 335 $user2 = $this->getDataGenerator()->create_user($user2); 336 337 // Get self-conversation for user1. 338 $sc1 = api::get_self_conversation($user1->id); 339 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi myself!'); 340 341 // Perform a search as user1. 342 $this->setUser($user1); 343 $result = api::message_search_users($user1->id, 'One'); 344 345 // Check user1 is found as non-contacts. 346 $this->assertCount(0, $result[0]); 347 $this->assertCount(1, $result[1]); 348 } 349 350 /** 351 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found. 352 */ 353 public function test_message_search_users_with_empty_result() { 354 $this->resetAfterTest(); 355 356 // Create some users, but make sure neither will match the search term. 357 $user1 = new \stdClass(); 358 $user1->firstname = 'User'; 359 $user1->lastname = 'One'; 360 $user1 = $this->getDataGenerator()->create_user($user1); 361 $user2 = new \stdClass(); 362 $user2->firstname = 'User'; 363 $user2->lastname = 'Two'; 364 $user2 = $this->getDataGenerator()->create_user($user2); 365 366 // Perform a search as user1. 367 $this->setUser($user1); 368 $result = api::message_search_users($user1->id, 'search'); 369 370 // Check results are empty. 371 $this->assertCount(0, $result[0]); 372 $this->assertCount(0, $result[1]); 373 } 374 375 /** 376 * Test verifying that limits and offsets work for both the contacts and non-contacts return data. 377 */ 378 public function test_message_search_users_limit_offset() { 379 $this->resetAfterTest(); 380 381 // Create 20 users. 382 $users = []; 383 foreach (range(1, 20) as $i) { 384 $user = new \stdClass(); 385 $user->firstname = "User search"; 386 $user->lastname = $i; 387 $user = $this->getDataGenerator()->create_user($user); 388 $users[$i] = $user; 389 } 390 391 // Enrol the first 9 users in the same course, but leave them as non-contacts. 392 $this->setAdminUser(); 393 $course1 = $this->getDataGenerator()->create_course(); 394 foreach (range(1, 8) as $i) { 395 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id); 396 } 397 398 // Add 5 users, starting at the 11th user, as contacts for user1. 399 foreach (range(11, 15) as $i) { 400 api::add_contact($users[1]->id, $users[$i]->id); 401 } 402 403 // Set as the user performing the search. 404 $this->setUser($users[1]); 405 406 // Search using a limit of 3. 407 // This tests the case where we have more results than the limit for both contacts and non-contacts. 408 $result = api::message_search_users($users[1]->id, 'search', 0, 3); 409 $contacts = $result[0]; 410 $noncontacts = $result[1]; 411 412 // Check that we retrieved the correct contacts. 413 $this->assertCount(3, $contacts); 414 $this->assertEquals($users[11]->id, $contacts[0]->id); 415 $this->assertEquals($users[12]->id, $contacts[1]->id); 416 $this->assertEquals($users[13]->id, $contacts[2]->id); 417 418 // Check that we retrieved the correct non-contacts. 419 // Consider first conversations is self-conversation. 420 $this->assertCount(3, $noncontacts); 421 $this->assertEquals($users[1]->id, $noncontacts[0]->id); 422 $this->assertEquals($users[2]->id, $noncontacts[1]->id); 423 $this->assertEquals($users[3]->id, $noncontacts[2]->id); 424 425 // Now, offset to get the next batch of results. 426 // We expect to see 2 contacts, and 3 non-contacts. 427 $result = api::message_search_users($users[1]->id, 'search', 3, 3); 428 $contacts = $result[0]; 429 $noncontacts = $result[1]; 430 $this->assertCount(2, $contacts); 431 $this->assertEquals($users[14]->id, $contacts[0]->id); 432 $this->assertEquals($users[15]->id, $contacts[1]->id); 433 434 $this->assertCount(3, $noncontacts); 435 $this->assertEquals($users[4]->id, $noncontacts[0]->id); 436 $this->assertEquals($users[5]->id, $noncontacts[1]->id); 437 $this->assertEquals($users[6]->id, $noncontacts[2]->id); 438 439 // Now, offset to get the next batch of results. 440 // We expect to see 0 contacts, and 2 non-contacts. 441 $result = api::message_search_users($users[1]->id, 'search', 6, 3); 442 $contacts = $result[0]; 443 $noncontacts = $result[1]; 444 $this->assertCount(0, $contacts); 445 446 $this->assertCount(2, $noncontacts); 447 $this->assertEquals($users[7]->id, $noncontacts[0]->id); 448 $this->assertEquals($users[8]->id, $noncontacts[1]->id); 449 } 450 451 /** 452 * Tests searching users as a user having the 'moodle/user:viewdetails' capability. 453 */ 454 public function test_message_search_users_with_cap() { 455 $this->resetAfterTest(); 456 global $DB; 457 458 // Create some users. 459 $users = []; 460 foreach (range(1, 8) as $i) { 461 $user = new \stdClass(); 462 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 463 $user->lastname = $i; 464 $user = $this->getDataGenerator()->create_user($user); 465 $users[$i] = $user; 466 } 467 468 // Enrol a few users in the same course, but leave them as non-contacts. 469 $course1 = $this->getDataGenerator()->create_course(); 470 $this->setAdminUser(); 471 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id); 472 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id); 473 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id); 474 475 // Add some other users as contacts. 476 api::add_contact($users[1]->id, $users[2]->id); 477 api::add_contact($users[3]->id, $users[1]->id); 478 api::add_contact($users[1]->id, $users[4]->id); 479 480 // Set as the user performing the search. 481 $this->setUser($users[1]); 482 483 // Grant the authenticated user role the capability 'user:viewdetails' at site context. 484 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST); 485 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, \context_system::instance()); 486 487 // Perform a search with $CFG->messagingallusers disabled. 488 set_config('messagingallusers', 0); 489 $result = api::message_search_users($users[1]->id, 'search'); 490 $contacts = $result[0]; 491 $noncontacts = $result[1]; 492 493 // Check that we retrieved the correct contacts. 494 $this->assertCount(2, $contacts); 495 $this->assertEquals($users[2]->id, $contacts[0]->id); 496 $this->assertEquals($users[3]->id, $contacts[1]->id); 497 498 // Check that we retrieved the correct non-contacts. 499 // Site-wide messaging is disabled, so we expect to be able to search for any users whose profiles we can view. 500 // Consider first conversations is self-conversation. 501 $this->assertCount(3, $noncontacts); 502 $this->assertEquals($users[1]->id, $noncontacts[0]->id); 503 $this->assertEquals($users[6]->id, $noncontacts[1]->id); 504 $this->assertEquals($users[7]->id, $noncontacts[2]->id); 505 } 506 507 /** 508 * Tests searching users with messaging disabled. 509 */ 510 public function test_message_search_users_messaging_disabled() { 511 $this->resetAfterTest(); 512 513 // Create a user. 514 $user = $this->getDataGenerator()->create_user(); 515 516 // Disable messaging. 517 set_config('messaging', 0); 518 519 // Ensure an exception is thrown. 520 $this->expectException('moodle_exception'); 521 api::message_search_users($user->id, 'User'); 522 } 523 524 /** 525 * Tests getting conversations between 2 users. 526 */ 527 public function test_get_conversations_between_users() { 528 // Create some users. 529 $user1 = new \stdClass(); 530 $user1->firstname = 'User'; 531 $user1->lastname = 'One'; 532 $user1 = self::getDataGenerator()->create_user($user1); 533 534 $user2 = new \stdClass(); 535 $user2->firstname = 'User'; 536 $user2->lastname = 'Two'; 537 $user2 = self::getDataGenerator()->create_user($user2); 538 539 $user3 = new \stdClass(); 540 $user3->firstname = 'User search'; 541 $user3->lastname = 'Three'; 542 $user3 = self::getDataGenerator()->create_user($user3); 543 544 $user4 = new \stdClass(); 545 $user4->firstname = 'User'; 546 $user4->lastname = 'Four'; 547 $user4 = self::getDataGenerator()->create_user($user4); 548 549 $user5 = new \stdClass(); 550 $user5->firstname = 'User'; 551 $user5->lastname = 'Five'; 552 $user5 = self::getDataGenerator()->create_user($user5); 553 554 $user6 = new \stdClass(); 555 $user6->firstname = 'User search'; 556 $user6->lastname = 'Six'; 557 $user6 = self::getDataGenerator()->create_user($user6); 558 559 // Add some users as contacts. 560 api::add_contact($user1->id, $user2->id); 561 api::add_contact($user6->id, $user1->id); 562 563 // Create private conversations with some users. 564 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 565 array($user1->id, $user2->id)); 566 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 567 array($user3->id, $user1->id)); 568 569 // Create a group conversation with users. 570 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 571 array($user1->id, $user2->id, $user3->id, $user4->id), 572 'Project chat'); 573 574 // Check that we retrieved the correct conversations. 575 $this->assertCount(2, api::get_conversations_between_users($user1->id, $user2->id)); 576 $this->assertCount(2, api::get_conversations_between_users($user2->id, $user1->id)); 577 $this->assertCount(2, api::get_conversations_between_users($user1->id, $user3->id)); 578 $this->assertCount(2, api::get_conversations_between_users($user3->id, $user1->id)); 579 $this->assertCount(1, api::get_conversations_between_users($user1->id, $user4->id)); 580 $this->assertCount(1, api::get_conversations_between_users($user4->id, $user1->id)); 581 $this->assertCount(0, api::get_conversations_between_users($user1->id, $user5->id)); 582 $this->assertCount(0, api::get_conversations_between_users($user5->id, $user1->id)); 583 $this->assertCount(0, api::get_conversations_between_users($user1->id, $user6->id)); 584 $this->assertCount(0, api::get_conversations_between_users($user6->id, $user1->id)); 585 } 586 587 /** 588 * Tests getting self-conversations. 589 */ 590 public function test_get_self_conversation() { 591 // Create some users. 592 $user1 = new \stdClass(); 593 $user1->firstname = 'User'; 594 $user1->lastname = 'One'; 595 $user1 = self::getDataGenerator()->create_user($user1); 596 597 $user2 = new \stdClass(); 598 $user2->firstname = 'User'; 599 $user2->lastname = 'Two'; 600 $user2 = self::getDataGenerator()->create_user($user2); 601 602 $user3 = new \stdClass(); 603 $user3->firstname = 'User search'; 604 $user3->lastname = 'Three'; 605 $user3 = self::getDataGenerator()->create_user($user3); 606 607 // Add some users as contacts. 608 api::add_contact($user1->id, $user2->id); 609 api::add_contact($user3->id, $user1->id); 610 611 // Create private conversations with some users. 612 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 613 array($user1->id, $user2->id)); 614 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 615 array($user3->id, $user1->id)); 616 617 // Create a group conversation with users. 618 $gc = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 619 array($user1->id, $user2->id, $user3->id), 620 'Project chat'); 621 622 // Get self-conversations. 623 $rsc1 = api::get_self_conversation($user1->id); 624 $rsc2 = api::get_self_conversation($user2->id); 625 $rsc3 = api::get_self_conversation($user3->id); 626 627 // Send message to self-conversation. 628 testhelper::send_fake_message_to_conversation($user1, $rsc1->id, 'Message to myself!'); 629 630 // Check that we retrieved the correct conversations. 631 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc1->type); 632 $members = api::get_conversation_members($user1->id, $rsc1->id); 633 $this->assertCount(1, $members); 634 $member = reset($members); 635 $this->assertEquals($user1->id, $member->id); 636 637 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc2->type); 638 $members = api::get_conversation_members($user2->id, $rsc2->id); 639 $this->assertCount(1, $members); 640 $member = reset($members); 641 $this->assertEquals($user2->id, $member->id); 642 643 api::delete_all_conversation_data($rsc3->id); 644 $selfconversation = api::get_self_conversation($user3->id); 645 $members = api::get_conversation_members($user1->id, $selfconversation->id); 646 $this->assertCount(1, $members); 647 } 648 649 /** 650 * Tests searching messages. 651 */ 652 public function test_search_messages() { 653 $this->resetAfterTest(); 654 655 // Create some users. 656 $user1 = self::getDataGenerator()->create_user(); 657 $user2 = self::getDataGenerator()->create_user(); 658 $user3 = self::getDataGenerator()->create_user(); 659 660 // The person doing the search. 661 $this->setUser($user1); 662 663 // Get self-conversation. 664 $sc = api::get_self_conversation($user1->id); 665 666 // Create group conversation. 667 $gc = api::create_conversation( 668 api::MESSAGE_CONVERSATION_TYPE_GROUP, 669 [$user1->id, $user2->id, $user3->id] 670 ); 671 672 // Send some messages back and forth. 673 $time = 1; 674 testhelper::send_fake_message_to_conversation($user1, $sc->id, 'Test message to self!', $time); 675 testhelper::send_fake_message_to_conversation($user1, $gc->id, 'My hero!', $time + 1); 676 $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time + 2); 677 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 3); 678 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 4); 679 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 5); 680 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 6); 681 682 $convid = api::get_conversation_between_users([$user1->id, $user2->id]); 683 $conv2id = api::get_conversation_between_users([$user1->id, $user3->id]); 684 685 // Block user 3. 686 api::block_user($user1->id, $user3->id); 687 688 // Perform a search. 689 $messages = api::search_messages($user1->id, 'o'); 690 691 // Confirm the data is correct. 692 $this->assertEquals(5, count($messages)); 693 $message1 = $messages[0]; 694 $message2 = $messages[1]; 695 $message3 = $messages[2]; 696 $message4 = $messages[3]; 697 $message5 = $messages[4]; 698 699 $this->assertEquals($user2->id, $message1->userid); 700 $this->assertEquals($user2->id, $message1->useridfrom); 701 $this->assertEquals(fullname($user2), $message1->fullname); 702 $this->assertTrue($message1->ismessaging); 703 $this->assertEquals('Word.', $message1->lastmessage); 704 $this->assertNotEmpty($message1->messageid); 705 $this->assertNull($message1->isonline); 706 $this->assertFalse($message1->isread); 707 $this->assertFalse($message1->isblocked); 708 $this->assertNull($message1->unreadcount); 709 $this->assertEquals($convid, $message1->conversationid); 710 711 $this->assertEquals($user2->id, $message2->userid); 712 $this->assertEquals($user1->id, $message2->useridfrom); 713 $this->assertEquals(fullname($user2), $message2->fullname); 714 $this->assertTrue($message2->ismessaging); 715 $this->assertEquals('Yo!', $message2->lastmessage); 716 $this->assertNotEmpty($message2->messageid); 717 $this->assertNull($message2->isonline); 718 $this->assertTrue($message2->isread); 719 $this->assertFalse($message2->isblocked); 720 $this->assertNull($message2->unreadcount); 721 $this->assertEquals($convid, $message2->conversationid); 722 723 $this->assertEquals($user3->id, $message3->userid); 724 $this->assertEquals($user3->id, $message3->useridfrom); 725 $this->assertEquals(fullname($user3), $message3->fullname); 726 $this->assertTrue($message3->ismessaging); 727 $this->assertEquals('Don\'t block me.', $message3->lastmessage); 728 $this->assertNotEmpty($message3->messageid); 729 $this->assertNull($message3->isonline); 730 $this->assertFalse($message3->isread); 731 $this->assertTrue($message3->isblocked); 732 $this->assertNull($message3->unreadcount); 733 $this->assertEquals($conv2id, $message3->conversationid); 734 735 // This is a group conversation. For now, search_messages returns only one of the other users on the conversation. It can't 736 // be guaranteed who will be returned in the first place, so we need to use the in_array to check all the possibilities. 737 $this->assertTrue(in_array($message4->userid, [$user2->id, $user3->id])); 738 $this->assertEquals($user1->id, $message4->useridfrom); 739 $this->assertTrue($message4->ismessaging); 740 $this->assertEquals('My hero!', $message4->lastmessage); 741 $this->assertNotEmpty($message4->messageid); 742 $this->assertNull($message4->isonline); 743 $this->assertTrue($message4->isread); 744 $this->assertNull($message4->unreadcount); 745 $this->assertEquals($gc->id, $message4->conversationid); 746 747 $this->assertEquals($user1->id, $message5->userid); 748 $this->assertEquals($user1->id, $message5->useridfrom); 749 $this->assertEquals(fullname($user1), $message5->fullname); 750 $this->assertTrue($message5->ismessaging); 751 $this->assertEquals('Test message to self!', $message5->lastmessage); 752 $this->assertNotEmpty($message5->messageid); 753 $this->assertFalse($message5->isonline); 754 $this->assertTrue($message5->isread); 755 $this->assertFalse($message5->isblocked); 756 $this->assertNull($message5->unreadcount); 757 $this->assertEquals($sc->id, $message5->conversationid); 758 } 759 760 /** 761 * Test verifying that favourited conversations can be retrieved. 762 */ 763 public function test_get_favourite_conversations() { 764 // Create some users. 765 $user1 = self::getDataGenerator()->create_user(); 766 $user2 = self::getDataGenerator()->create_user(); 767 $user3 = self::getDataGenerator()->create_user(); 768 $user4 = self::getDataGenerator()->create_user(); 769 770 // The person doing the search. 771 $this->setUser($user1); 772 773 // Only self-conversation created. 774 $this->assertCount(1, api::get_conversations($user1->id)); 775 776 // Create some conversations for user1. 777 $time = 1; 778 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 779 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 780 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 781 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 782 783 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 784 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 785 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 786 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 787 788 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9); 789 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10); 790 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11); 791 792 // Favourite the first 2 conversations for user1. 793 $convoids = []; 794 $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]); 795 $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]); 796 $user1context = \context_user::instance($user1->id); 797 $service = \core_favourites\service_factory::get_service_for_user_context($user1context); 798 foreach ($convoids as $convoid) { 799 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context); 800 } 801 802 // We should have 4 conversations. 803 // Consider first conversations is self-conversation. 804 $this->assertCount(4, api::get_conversations($user1->id)); 805 806 // And 3 favourited conversations (self-conversation included). 807 $conversations = api::get_conversations($user1->id, 0, 20, null, true); 808 $this->assertCount(3, $conversations); 809 $conversations = api::get_conversations( 810 $user1->id, 811 0, 812 20, 813 api::MESSAGE_CONVERSATION_TYPE_SELF, 814 true 815 ); 816 $this->assertCount(1, $conversations); 817 } 818 819 /** 820 * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly. 821 */ 822 public function test_get_favourite_conversations_limit_offset() { 823 // Create some users. 824 $user1 = self::getDataGenerator()->create_user(); 825 $user2 = self::getDataGenerator()->create_user(); 826 $user3 = self::getDataGenerator()->create_user(); 827 $user4 = self::getDataGenerator()->create_user(); 828 829 // The person doing the search. 830 $this->setUser($user1); 831 832 // Only self-conversation created. 833 $this->assertCount(1, api::get_conversations($user1->id)); 834 835 // Create some conversations for user1. 836 $time = 1; 837 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 838 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 839 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 840 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 841 842 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 843 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 844 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 845 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 846 847 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9); 848 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10); 849 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11); 850 851 // Favourite the all conversations for user1. 852 $convoids = []; 853 $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]); 854 $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]); 855 $convoids[] = api::get_conversation_between_users([$user1->id, $user4->id]); 856 $user1context = \context_user::instance($user1->id); 857 $service = \core_favourites\service_factory::get_service_for_user_context($user1context); 858 foreach ($convoids as $convoid) { 859 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context); 860 } 861 862 // Consider first conversations is self-conversation. 863 // Get all records, using offset 0 and large limit. 864 $this->assertCount(4, api::get_conversations($user1->id, 0, 20, null, true)); 865 866 // Now, get 10 conversations starting at the second record. We should see 2 conversations. 867 $this->assertCount(3, api::get_conversations($user1->id, 1, 10, null, true)); 868 869 // Now, try to get favourited conversations using an invalid offset. 870 $this->assertCount(0, api::get_conversations($user1->id, 5, 10, null, true)); 871 } 872 873 /** 874 * Tests retrieving favourite conversations when a conversation contains a deleted user. 875 */ 876 public function test_get_favourite_conversations_with_deleted_user() { 877 // Create some users. 878 $user1 = self::getDataGenerator()->create_user(); 879 $user2 = self::getDataGenerator()->create_user(); 880 $user3 = self::getDataGenerator()->create_user(); 881 882 // Send some messages back and forth, have some different conversations with different users. 883 $time = 1; 884 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 885 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 886 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 887 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 888 889 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 890 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 891 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 892 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 893 894 // Favourite the all conversations for user1. 895 $convoids = []; 896 $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]); 897 $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]); 898 $user1context = \context_user::instance($user1->id); 899 $service = \core_favourites\service_factory::get_service_for_user_context($user1context); 900 foreach ($convoids as $convoid) { 901 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context); 902 } 903 904 // Delete the second user. 905 delete_user($user2); 906 907 // Retrieve the conversations. 908 $conversations = api::get_conversations($user1->id, 0, 20, null, true); 909 910 // We should have both conversations, despite the other user being soft-deleted. 911 // Consider first conversations is self-conversation. 912 $this->assertCount(3, $conversations); 913 914 // Confirm the conversation is from the non-deleted user. 915 $conversation = reset($conversations); 916 $this->assertEquals($convoids[1], $conversation->id); 917 } 918 919 /** 920 * Test confirming that conversations can be marked as favourites. 921 */ 922 public function test_set_favourite_conversation() { 923 // Create some users. 924 $user1 = self::getDataGenerator()->create_user(); 925 $user2 = self::getDataGenerator()->create_user(); 926 $user3 = self::getDataGenerator()->create_user(); 927 928 // Send some messages back and forth, have some different conversations with different users. 929 $time = 1; 930 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 931 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 932 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 933 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 934 935 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 936 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 937 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 938 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 939 940 // Favourite the first conversation as user 1. 941 $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]); 942 $favourite = api::set_favourite_conversation($conversationid1, $user1->id); 943 944 // Verify we have two favourite conversations a user 1. 945 // Consider first conversations is self-conversation. 946 $this->assertCount(2, api::get_conversations($user1->id, 0, 20, null, true)); 947 948 // Verify we have only one favourite as user2, despite being a member in that conversation. 949 // Consider first conversations is self-conversation. 950 $this->assertCount(1, api::get_conversations($user2->id, 0, 20, null, true)); 951 952 // Try to favourite the same conversation again should just return the existing favourite. 953 $repeatresult = api::set_favourite_conversation($conversationid1, $user1->id); 954 $this->assertEquals($favourite->id, $repeatresult->id); 955 } 956 957 /** 958 * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception. 959 */ 960 public function test_set_favourite_conversation_nonexistent_conversation() { 961 // Create some users. 962 $user1 = self::getDataGenerator()->create_user(); 963 // Try to favourite a non-existent conversation. 964 $this->expectException(\moodle_exception::class); 965 api::set_favourite_conversation(0, $user1->id); 966 } 967 968 /** 969 * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation. 970 */ 971 public function test_set_favourite_conversation_non_member() { 972 // Create some users. 973 $user1 = self::getDataGenerator()->create_user(); 974 $user2 = self::getDataGenerator()->create_user(); 975 $user3 = self::getDataGenerator()->create_user(); 976 977 // Send some messages back and forth, have some different conversations with different users. 978 $time = 1; 979 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 980 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 981 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 982 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 983 984 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 985 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 986 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 987 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 988 989 // Try to favourite the first conversation as user 3, who is not a member. 990 $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]); 991 $this->expectException(\moodle_exception::class); 992 api::set_favourite_conversation($conversationid1, $user3->id); 993 } 994 995 /** 996 * Test confirming that those conversations marked as favourites can be unfavourited. 997 */ 998 public function test_unset_favourite_conversation() { 999 // Create some users. 1000 $user1 = self::getDataGenerator()->create_user(); 1001 $user2 = self::getDataGenerator()->create_user(); 1002 $user3 = self::getDataGenerator()->create_user(); 1003 1004 // Send some messages back and forth, have some different conversations with different users. 1005 $time = 1; 1006 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 1007 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 1008 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 1009 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 1010 1011 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5); 1012 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6); 1013 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7); 1014 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8); 1015 1016 // Favourite the first conversation as user 1 and the second as user 3. 1017 $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]); 1018 $conversationid2 = api::get_conversation_between_users([$user1->id, $user3->id]); 1019 api::set_favourite_conversation($conversationid1, $user1->id); 1020 api::set_favourite_conversation($conversationid2, $user3->id); 1021 1022 // Verify we have two favourite conversations for both user 1 and user 3, counting self conversations. 1023 $this->assertCount(2, api::get_conversations($user1->id, 0, 20, null, true)); 1024 $this->assertCount(2, api::get_conversations($user3->id, 0, 20, null, true)); 1025 1026 // Now unfavourite the conversation as user 1. 1027 api::unset_favourite_conversation($conversationid1, $user1->id); 1028 1029 // Verify we have two favourite conversations user 3 only, and one for user1, counting self conversations. 1030 $this->assertCount(2, api::get_conversations($user3->id, 0, 20, null, true)); 1031 $this->assertCount(1, api::get_conversations($user1->id, 0, 20, null, true)); 1032 1033 // Try to favourite the same conversation again as user 1. 1034 $this->expectException(\moodle_exception::class); 1035 api::unset_favourite_conversation($conversationid1, $user1->id); 1036 } 1037 1038 /** 1039 * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite. 1040 */ 1041 public function test_unset_favourite_conversation_not_favourite() { 1042 // Create some users. 1043 $user1 = self::getDataGenerator()->create_user(); 1044 $user2 = self::getDataGenerator()->create_user(); 1045 1046 // Send some messages back and forth, have some different conversations with different users. 1047 $time = 1; 1048 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 1049 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 1050 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 1051 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 1052 1053 // Now try to unfavourite the conversation as user 1. 1054 $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]); 1055 $this->expectException(\moodle_exception::class); 1056 api::unset_favourite_conversation($conversationid1, $user1->id); 1057 } 1058 1059 /** 1060 * Test verifying that a non-existent conversation cannot be unset as a favourite. 1061 */ 1062 public function test_unset_favourite_conversation_non_existent_conversation() { 1063 // Create some users. 1064 $user1 = self::getDataGenerator()->create_user(); 1065 1066 // Now try to unfavourite the conversation as user 1. 1067 $this->expectException(\moodle_exception::class); 1068 api::unset_favourite_conversation(0, $user1->id); 1069 } 1070 1071 /** 1072 * Helper to seed the database with initial state. 1073 */ 1074 protected function create_conversation_test_data() { 1075 // Create some users. 1076 $user1 = self::getDataGenerator()->create_user(); 1077 $user2 = self::getDataGenerator()->create_user(); 1078 $user3 = self::getDataGenerator()->create_user(); 1079 $user4 = self::getDataGenerator()->create_user(); 1080 1081 $time = 1; 1082 1083 // Create some conversations. We want: 1084 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message. 1085 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message. 1086 // 3) At least one of each type (group, individual) of which user1 IS NOT a member. 1087 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering). 1088 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member. 1089 1090 // Individual conversation, user1 is a member, last message from other user. 1091 $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1092 [$user1->id, $user2->id]); 1093 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time); 1094 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1); 1095 1096 // Individual conversation, user1 is a member, last message from user1. 1097 $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1098 [$user1->id, $user3->id]); 1099 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2); 1100 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3); 1101 1102 // Individual conversation, user1 is not a member. 1103 $ic3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1104 [$user2->id, $user3->id]); 1105 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4); 1106 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5); 1107 1108 // Group conversation, user1 is not a member. 1109 $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1110 [$user2->id, $user3->id, $user4->id], 'Project discussions'); 1111 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6); 1112 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7); 1113 1114 // Group conversation, user1 is a member, last message from another user. 1115 $gc2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1116 [$user1->id, $user3->id, $user4->id], 'Group chat'); 1117 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8); 1118 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9); 1119 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10); 1120 1121 // Group conversation, user1 is a member, last message from user1. 1122 $gc3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1123 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!'); 1124 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11); 1125 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12); 1126 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13); 1127 1128 // Empty group conversations (x2), user1 is a member. 1129 $gc4 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1130 [$user1->id, $user2->id, $user3->id], 'Empty group'); 1131 $gc5 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1132 [$user1->id, $user2->id, $user4->id], 'Another empty group'); 1133 1134 // Empty group conversation, user1 is NOT a member. 1135 $gc6 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1136 [$user2->id, $user3->id, $user4->id], 'Empty group 3'); 1137 1138 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6]; 1139 } 1140 1141 /** 1142 * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used. 1143 */ 1144 public function test_get_conversations_no_restrictions() { 1145 global $DB; 1146 1147 $user1 = self::getDataGenerator()->create_user(); 1148 // Self-conversation should exists. 1149 $this->assertCount(1, api::get_conversations($user1->id)); 1150 1151 // Get a bunch of conversations, some group, some individual and in different states. 1152 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1153 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1154 1155 // Get all conversations for user1. 1156 $conversations = api::get_conversations($user1->id); 1157 1158 // Verify there are 2 individual conversation, 2 group conversations, 2 empty group conversations, 1159 // and a self-conversation. 1160 // The conversations with the most recent messages should be listed first, followed by the empty 1161 // conversations, with the most recently created first. 1162 $this->assertCount(7, $conversations); 1163 $typecounts = array_count_values(array_column($conversations, 'type')); 1164 $this->assertEquals(2, $typecounts[1]); 1165 $this->assertEquals(4, $typecounts[2]); 1166 $this->assertEquals(1, $typecounts[3]); 1167 1168 // Those conversations having messages should be listed after self-conversation, ordered by most recent message time. 1169 $this->assertEquals($gc3->id, $conversations[0]->id); 1170 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type); 1171 $this->assertFalse($conversations[1]->isfavourite); 1172 $this->assertCount(1, $conversations[0]->members); 1173 $this->assertEquals(4, $conversations[0]->membercount); 1174 $this->assertCount(1, $conversations[0]->messages); 1175 $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]); 1176 $expectedmessagetext = message_format_message_text($message); 1177 $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text); 1178 $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom); 1179 1180 $this->assertEquals($gc2->id, $conversations[1]->id); 1181 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type); 1182 $this->assertFalse($conversations[1]->isfavourite); 1183 $this->assertCount(1, $conversations[1]->members); 1184 $this->assertEquals(3, $conversations[1]->membercount); 1185 $this->assertCount(1, $conversations[1]->messages); 1186 $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]); 1187 $expectedmessagetext = message_format_message_text($message); 1188 $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text); 1189 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom); 1190 1191 $this->assertEquals($ic2->id, $conversations[2]->id); 1192 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type); 1193 $this->assertFalse($conversations[2]->isfavourite); 1194 $this->assertCount(1, $conversations[2]->members); 1195 $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id); 1196 $this->assertEquals(2, $conversations[2]->membercount); 1197 $this->assertCount(1, $conversations[2]->messages); 1198 $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]); 1199 $expectedmessagetext = message_format_message_text($message); 1200 $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text); 1201 $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom); 1202 1203 $this->assertEquals($ic1->id, $conversations[3]->id); 1204 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type); 1205 $this->assertFalse($conversations[3]->isfavourite); 1206 $this->assertCount(1, $conversations[3]->members); 1207 $this->assertEquals(2, $conversations[3]->membercount); 1208 $this->assertCount(1, $conversations[3]->messages); 1209 $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]); 1210 $expectedmessagetext = message_format_message_text($message); 1211 $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text); 1212 $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom); 1213 1214 // Of the groups without messages, we expect to see the most recently created first. 1215 $this->assertEquals($gc5->id, $conversations[4]->id); 1216 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type); 1217 $this->assertFalse($conversations[4]->isfavourite); 1218 $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist. 1219 $this->assertEquals(3, $conversations[4]->membercount); 1220 $this->assertEmpty($conversations[4]->messages); 1221 1222 $this->assertEquals($gc4->id, $conversations[5]->id); 1223 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type); 1224 $this->assertFalse($conversations[5]->isfavourite); 1225 $this->assertCount(0, $conversations[5]->members); 1226 $this->assertEquals(3, $conversations[5]->membercount); 1227 $this->assertEmpty($conversations[5]->messages); 1228 1229 // Verify format of the return structure. 1230 foreach ($conversations as $conv) { 1231 $this->assertObjectHasAttribute('id', $conv); 1232 $this->assertObjectHasAttribute('name', $conv); 1233 $this->assertObjectHasAttribute('subname', $conv); 1234 $this->assertObjectHasAttribute('imageurl', $conv); 1235 $this->assertObjectHasAttribute('type', $conv); 1236 $this->assertObjectHasAttribute('isfavourite', $conv); 1237 $this->assertObjectHasAttribute('membercount', $conv); 1238 $this->assertObjectHasAttribute('isread', $conv); 1239 $this->assertObjectHasAttribute('unreadcount', $conv); 1240 $this->assertObjectHasAttribute('members', $conv); 1241 foreach ($conv->members as $member) { 1242 $this->assertObjectHasAttribute('id', $member); 1243 $this->assertObjectHasAttribute('fullname', $member); 1244 $this->assertObjectHasAttribute('profileimageurl', $member); 1245 $this->assertObjectHasAttribute('profileimageurlsmall', $member); 1246 $this->assertObjectHasAttribute('isonline', $member); 1247 $this->assertObjectHasAttribute('showonlinestatus', $member); 1248 $this->assertObjectHasAttribute('isblocked', $member); 1249 $this->assertObjectHasAttribute('iscontact', $member); 1250 $this->assertObjectHasAttribute('isdeleted', $member); 1251 $this->assertObjectHasAttribute('canmessage', $member); 1252 $this->assertObjectHasAttribute('requirescontact', $member); 1253 $this->assertObjectHasAttribute('contactrequests', $member); 1254 } 1255 $this->assertObjectHasAttribute('messages', $conv); 1256 foreach ($conv->messages as $message) { 1257 $this->assertObjectHasAttribute('id', $message); 1258 $this->assertObjectHasAttribute('useridfrom', $message); 1259 $this->assertObjectHasAttribute('text', $message); 1260 $this->assertObjectHasAttribute('timecreated', $message); 1261 } 1262 } 1263 } 1264 1265 /** 1266 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately. 1267 */ 1268 public function test_get_conversations_message_format() { 1269 global $DB; 1270 // Create some users. 1271 $user1 = self::getDataGenerator()->create_user(); 1272 $user2 = self::getDataGenerator()->create_user(); 1273 1274 // Create conversation. 1275 $conversation = api::create_conversation( 1276 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1277 [$user1->id, $user2->id] 1278 ); 1279 1280 // Send some messages back and forth. 1281 $time = 1; 1282 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1); 1283 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2); 1284 1285 // Verify the format of the html message. 1286 $message = $DB->get_record('messages', ['id' => $mid]); 1287 $expectedmessagetext = message_format_message_text($message); 1288 $conversations = api::get_conversations($user1->id); 1289 $messages = $conversations[0]->messages; 1290 $this->assertEquals($expectedmessagetext, $messages[0]->text); 1291 } 1292 1293 /** 1294 * Test verifying get_conversations identifies if a conversation is muted or not. 1295 */ 1296 public function test_get_conversations_some_muted() { 1297 // Create some users. 1298 $user1 = self::getDataGenerator()->create_user(); 1299 $user2 = self::getDataGenerator()->create_user(); 1300 $user3 = self::getDataGenerator()->create_user(); 1301 1302 $conversation1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1303 [$user1->id, $user2->id]); 1304 testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1'); 1305 testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2'); 1306 api::mute_conversation($user1->id, $conversation1->id); 1307 1308 $conversation2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1309 [$user1->id, $user3->id]); 1310 testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 1'); 1311 testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2'); 1312 1313 $conversation3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1314 [$user1->id, $user2->id]); 1315 api::mute_conversation($user1->id, $conversation3->id); 1316 1317 $conversation4 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, 1318 [$user1->id, $user3->id]); 1319 1320 $conversations = api::get_conversations($user1->id); 1321 1322 usort($conversations, function($first, $second){ 1323 return $first->id <=> $second->id; 1324 }); 1325 1326 // Consider first conversations is self-conversation. 1327 $selfconversation = array_shift($conversations); 1328 $conv1 = array_shift($conversations); 1329 $conv2 = array_shift($conversations); 1330 $conv3 = array_shift($conversations); 1331 $conv4 = array_shift($conversations); 1332 1333 $this->assertTrue($conv1->ismuted); 1334 $this->assertFalse($conv2->ismuted); 1335 $this->assertTrue($conv3->ismuted); 1336 $this->assertFalse($conv4->ismuted); 1337 } 1338 1339 /** 1340 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly. 1341 */ 1342 public function test_get_conversations_limit_offset() { 1343 // Get a bunch of conversations, some group, some individual and in different states. 1344 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1345 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1346 1347 // Get all conversations for user1, limited to 1 result. 1348 $conversations = api::get_conversations($user1->id, 0, 1); 1349 1350 // Verify the first conversation. 1351 $this->assertCount(1, $conversations); 1352 $conversation = array_shift($conversations); 1353 $this->assertEquals($conversation->id, $gc3->id); 1354 1355 // Verify the next conversation. 1356 $conversations = api::get_conversations($user1->id, 1, 1); 1357 $this->assertCount(1, $conversations); 1358 $this->assertEquals($gc2->id, $conversations[0]->id); 1359 1360 // Verify the next conversation. 1361 $conversations = api::get_conversations($user1->id, 2, 1); 1362 $this->assertCount(1, $conversations); 1363 $this->assertEquals($ic2->id, $conversations[0]->id); 1364 1365 // Skip one and get both empty conversations. 1366 $conversations = api::get_conversations($user1->id, 4, 2); 1367 $this->assertCount(2, $conversations); 1368 $this->assertEquals($gc5->id, $conversations[0]->id); 1369 $this->assertEmpty($conversations[0]->messages); 1370 $this->assertEquals($gc4->id, $conversations[1]->id); 1371 $this->assertEmpty($conversations[1]->messages); 1372 1373 // Ask for an offset that doesn't exist and verify no conversations are returned. 1374 $conversations = api::get_conversations($user1->id, 10, 1); 1375 $this->assertCount(0, $conversations); 1376 } 1377 1378 /** 1379 * Test verifying the type filtering behaviour of the 1380 */ 1381 public function test_get_conversations_type_filter() { 1382 // Get a bunch of conversations, some group, some individual and in different states. 1383 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1384 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1385 1386 // Verify we can ask for only individual conversations. 1387 $conversations = api::get_conversations($user1->id, 0, 20, 1388 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL); 1389 $this->assertCount(2, $conversations); 1390 1391 // Verify we can ask for only group conversations. 1392 $conversations = api::get_conversations($user1->id, 0, 20, 1393 api::MESSAGE_CONVERSATION_TYPE_GROUP); 1394 $this->assertCount(4, $conversations); 1395 1396 // Verify an exception is thrown if an unrecognized type is specified. 1397 $this->expectException(\moodle_exception::class); 1398 $conversations = api::get_conversations($user1->id, 0, 20, 0); 1399 } 1400 1401 /** 1402 * Tests retrieving conversations when a 'self' conversation exists. 1403 */ 1404 public function test_get_conversations_self_conversations() { 1405 global $DB; 1406 1407 // Create a conversation between one user and themself. 1408 $user1 = self::getDataGenerator()->create_user(); 1409 $user2 = self::getDataGenerator()->create_user(); 1410 $user3 = self::getDataGenerator()->create_user(); 1411 $user4 = self::getDataGenerator()->create_user(); 1412 1413 // Create some individual conversations. 1414 $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1415 [$user1->id, $user2->id]); 1416 $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1417 [$user1->id, $user3->id]); 1418 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message from user1 to user2'); 1419 1420 // Get some self-conversations. 1421 $sc1 = api::get_self_conversation($user1->id); 1422 $sc4 = api::get_self_conversation($user4->id); 1423 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Test message to self 1!'); 1424 1425 // Verify we are in a 'self' conversation state. 1426 $members = $DB->get_records('message_conversation_members', ['conversationid' => $sc1->id]); 1427 $this->assertCount(1, $members); 1428 $member = array_pop($members); 1429 $this->assertEquals($user1->id, $member->userid); 1430 1431 // Verify the self-conversations are returned by the method. 1432 $conversations = api::get_conversations($user1->id, 0, 20, api::MESSAGE_CONVERSATION_TYPE_SELF); 1433 $this->assertCount(1, $conversations); 1434 $conversation = array_pop($conversations); 1435 $this->assertEquals($conversation->id, $sc1->id); 1436 1437 $conversations = api::get_conversations($user4->id); 1438 // The self-conversation. 1439 $this->assertCount(1, $conversations); 1440 1441 // Get only private conversations for user1 (empty conversations, like $ic2, are not returned). 1442 $conversations = api::get_conversations($user1->id, 0, 20, 1443 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL); 1444 $this->assertCount(1, $conversations); 1445 1446 // Merge self with private conversations for user1. 1447 $conversations = api::get_conversations($user1->id, 0, 20, 1448 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true); 1449 $this->assertCount(2, $conversations); 1450 1451 // Get only private conversations for user2. 1452 $conversations = api::get_conversations($user2->id, 0, 20, 1453 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL); 1454 $this->assertCount(1, $conversations); 1455 1456 // Merge self with private conversations for user2. 1457 $conversations = api::get_conversations($user2->id, 0, 20, 1458 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true); 1459 $this->assertCount(2, $conversations); 1460 } 1461 1462 /** 1463 * Tests retrieving conversations when a conversation contains a deleted user. 1464 */ 1465 public function test_get_conversations_with_deleted_user() { 1466 // Get a bunch of conversations, some group, some individual and in different states. 1467 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1468 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1469 1470 // Delete the second user and retrieve the conversations. 1471 // We should have 6 still, as conversations with soft-deleted users are still returned. 1472 // Group conversations are also present, albeit with less members. 1473 delete_user($user2); 1474 // This is to confirm an exception is not thrown when a user AND the user context is deleted. 1475 // We no longer delete the user context, but historically we did. 1476 \context_helper::delete_instance(CONTEXT_USER, $user2->id); 1477 $conversations = api::get_conversations($user1->id); 1478 // Consider there's a self-conversation (the last one). 1479 $this->assertCount(7, $conversations); 1480 $this->assertEquals($gc3->id, $conversations[0]->id); 1481 $this->assertcount(1, $conversations[0]->members); 1482 $this->assertEquals($gc2->id, $conversations[1]->id); 1483 $this->assertcount(1, $conversations[1]->members); 1484 $this->assertEquals($ic2->id, $conversations[2]->id); 1485 $this->assertEquals($ic1->id, $conversations[3]->id); 1486 $this->assertEquals($gc5->id, $conversations[4]->id); 1487 $this->assertEquals($gc4->id, $conversations[5]->id); 1488 1489 // Delete a user from a group conversation where that user had sent the most recent message. 1490 // This user will still be present in the members array, as will the message in the messages array. 1491 delete_user($user4); 1492 $conversations = api::get_conversations($user1->id); 1493 1494 // Consider there's a self-conversation (the last one). 1495 $this->assertCount(7, $conversations); 1496 $this->assertEquals($gc2->id, $conversations[1]->id); 1497 $this->assertcount(1, $conversations[1]->members); 1498 $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id); 1499 $this->assertcount(1, $conversations[1]->messages); 1500 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom); 1501 1502 // Delete the third user and retrieve the conversations. 1503 // We should have 6 still, as conversations with soft-deleted users are still returned. 1504 // Group conversations are also present, albeit with less members. 1505 delete_user($user3); 1506 $conversations = api::get_conversations($user1->id); 1507 // Consider there's a self-conversation (the last one). 1508 $this->assertCount(7, $conversations); 1509 $this->assertEquals($gc3->id, $conversations[0]->id); 1510 $this->assertcount(1, $conversations[0]->members); 1511 $this->assertEquals($gc2->id, $conversations[1]->id); 1512 $this->assertcount(1, $conversations[1]->members); 1513 $this->assertEquals($ic2->id, $conversations[2]->id); 1514 $this->assertEquals($ic1->id, $conversations[3]->id); 1515 $this->assertEquals($gc5->id, $conversations[4]->id); 1516 $this->assertEquals($gc4->id, $conversations[5]->id); 1517 } 1518 1519 /** 1520 * Test confirming the behaviour of get_conversations() when users delete all messages. 1521 */ 1522 public function test_get_conversations_deleted_messages() { 1523 // Get a bunch of conversations, some group, some individual and in different states. 1524 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1525 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1526 1527 $conversations = api::get_conversations($user1->id); 1528 // Consider first conversations is self-conversation. 1529 $this->assertCount(7, $conversations); 1530 1531 // Delete all messages from a group conversation the user is in - it should be returned. 1532 $this->assertTrue(api::is_user_in_conversation($user1->id, $gc2->id)); 1533 $convmessages = api::get_conversation_messages($user1->id, $gc2->id); 1534 $messages = $convmessages['messages']; 1535 foreach ($messages as $message) { 1536 api::delete_message($user1->id, $message->id); 1537 } 1538 $conversations = api::get_conversations($user1->id); 1539 // Consider first conversations is self-conversation. 1540 $this->assertCount(7, $conversations); 1541 $this->assertContainsEquals($gc2->id, array_column($conversations, 'id')); 1542 1543 // Delete all messages from an individual conversation the user is in - it should not be returned. 1544 $this->assertTrue(api::is_user_in_conversation($user1->id, $ic1->id)); 1545 $convmessages = api::get_conversation_messages($user1->id, $ic1->id); 1546 $messages = $convmessages['messages']; 1547 foreach ($messages as $message) { 1548 api::delete_message($user1->id, $message->id); 1549 } 1550 $conversations = api::get_conversations($user1->id); 1551 // Consider first conversations is self-conversation. 1552 $this->assertCount(6, $conversations); 1553 $this->assertNotContainsEquals($ic1->id, array_column($conversations, 'id')); 1554 } 1555 1556 /** 1557 * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single 1558 * favourite. 1559 */ 1560 public function test_get_conversations_favourite_conversations_single() { 1561 // Get a bunch of conversations, some group, some individual and in different states. 1562 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1563 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1564 1565 // Mark a single conversation as favourites. 1566 api::set_favourite_conversation($ic2->id, $user1->id); 1567 1568 // Get the conversation, first with no restrictions, confirming the favourite status of the conversations. 1569 $conversations = api::get_conversations($user1->id); 1570 // Consider there is a self-conversation. 1571 $selfconversation = api::get_self_conversation($user1->id); 1572 $this->assertCount(7, $conversations); 1573 foreach ($conversations as $conv) { 1574 if (in_array($conv->id, [$ic2->id, $selfconversation->id])) { 1575 $this->assertTrue($conv->isfavourite); 1576 } else { 1577 $this->assertFalse($conv->isfavourite); 1578 } 1579 } 1580 1581 // Now, get ONLY favourite conversations (including self-conversation). 1582 $conversations = api::get_conversations($user1->id, 0, 20, null, true); 1583 $this->assertCount(2, $conversations); 1584 foreach ($conversations as $conv) { 1585 if ($conv->type != api::MESSAGE_CONVERSATION_TYPE_SELF) { 1586 $this->assertTrue($conv->isfavourite); 1587 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conv->type); 1588 $this->assertEquals($ic2->id, $conv->id); 1589 } 1590 } 1591 1592 // Now, try ONLY favourites of type 'group'. 1593 $conversations = api::get_conversations($user1->id, 0, 20, 1594 api::MESSAGE_CONVERSATION_TYPE_GROUP, true); 1595 $this->assertEmpty($conversations); 1596 1597 // And NO favourite conversations. 1598 $conversations = api::get_conversations($user1->id, 0, 20, null, false); 1599 $this->assertCount(5, $conversations); 1600 foreach ($conversations as $conv) { 1601 $this->assertFalse($conv->isfavourite); 1602 $this->assertNotEquals($ic2, $conv->id); 1603 } 1604 } 1605 1606 /** 1607 * Test verifying the behaviour of get_conversations() when fetching favourite conversations. 1608 */ 1609 public function test_get_conversations_favourite_conversations() { 1610 // Get a bunch of conversations, some group, some individual and in different states. 1611 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 1612 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 1613 1614 // Try to get ONLY favourite conversations, when only self-conversation exist. 1615 $this->assertCount(1, api::get_conversations($user1->id, 0, 20, null, true)); 1616 1617 // Unstar self-conversation. 1618 $selfconversation = api::get_self_conversation($user1->id); 1619 api::unset_favourite_conversation($selfconversation->id, $user1->id); 1620 1621 // Try to get ONLY favourite conversations, when no favourites exist. 1622 $this->assertEquals([], api::get_conversations($user1->id, 0, 20, null, true)); 1623 1624 // Try to get NO favourite conversations, when no favourites exist. 1625 $this->assertCount(7, api::get_conversations($user1->id, 0, 20, null, false)); 1626 1627 // Mark a few conversations as favourites. 1628 api::set_favourite_conversation($ic1->id, $user1->id); 1629 api::set_favourite_conversation($gc2->id, $user1->id); 1630 api::set_favourite_conversation($gc5->id, $user1->id); 1631 $favouriteids = [$ic1->id, $gc2->id, $gc5->id]; 1632 1633 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations. 1634 $conversations = api::get_conversations($user1->id); 1635 $this->assertCount(7, $conversations); 1636 foreach ($conversations as $conv) { 1637 if (in_array($conv->id, $favouriteids)) { 1638 $this->assertTrue($conv->isfavourite); 1639 } else { 1640 $this->assertFalse($conv->isfavourite); 1641 } 1642 } 1643 1644 // Now, get ONLY favourite conversations. 1645 $conversations = api::get_conversations($user1->id, 0, 20, null, true); 1646 $this->assertCount(3, $conversations); 1647 foreach ($conversations as $conv) { 1648 $this->assertTrue($conv->isfavourite); 1649 $this->assertNotFalse(array_search($conv->id, $favouriteids)); 1650 } 1651 1652 // Now, try ONLY favourites of type 'group'. 1653 $conversations = api::get_conversations($user1->id, 0, 20, 1654 api::MESSAGE_CONVERSATION_TYPE_GROUP, true); 1655 $this->assertCount(2, $conversations); 1656 foreach ($conversations as $conv) { 1657 $this->assertTrue($conv->isfavourite); 1658 $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id])); 1659 } 1660 1661 // And NO favourite conversations. 1662 $conversations = api::get_conversations($user1->id, 0, 20, null, false); 1663 $this->assertCount(4, $conversations); 1664 foreach ($conversations as $conv) { 1665 $this->assertFalse($conv->isfavourite); 1666 $this->assertFalse(array_search($conv->id, $favouriteids)); 1667 } 1668 } 1669 1670 /** 1671 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this 1672 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want 1673 * to confirm this happens. 1674 */ 1675 public function test_get_conversations_user_in_group_and_individual_chat() { 1676 $this->resetAfterTest(); 1677 1678 $user1 = self::getDataGenerator()->create_user(); 1679 $user2 = self::getDataGenerator()->create_user(); 1680 $user3 = self::getDataGenerator()->create_user(); 1681 1682 $conversation = api::create_conversation( 1683 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1684 [ 1685 $user1->id, 1686 $user2->id 1687 ], 1688 'Individual conversation' 1689 ); 1690 1691 testhelper::send_fake_message_to_conversation($user1, $conversation->id); 1692 1693 $conversation = api::create_conversation( 1694 api::MESSAGE_CONVERSATION_TYPE_GROUP, 1695 [ 1696 $user1->id, 1697 $user2->id, 1698 ], 1699 'Group conversation' 1700 ); 1701 1702 testhelper::send_fake_message_to_conversation($user1, $conversation->id); 1703 1704 api::create_contact_request($user1->id, $user2->id); 1705 api::create_contact_request($user1->id, $user3->id); 1706 1707 $conversations = api::get_conversations($user2->id); 1708 1709 $groupconversation = array_shift($conversations); 1710 $individualconversation = array_shift($conversations); 1711 1712 $this->assertEquals('Group conversation', $groupconversation->name); 1713 $this->assertEquals('Individual conversation', $individualconversation->name); 1714 1715 $this->assertCount(1, $groupconversation->members); 1716 $this->assertCount(1, $individualconversation->members); 1717 1718 $groupmember = reset($groupconversation->members); 1719 $this->assertNull($groupmember->requirescontact); 1720 $this->assertNull($groupmember->canmessage); 1721 $this->assertEmpty($groupmember->contactrequests); 1722 1723 $individualmember = reset($individualconversation->members); 1724 $this->assertNotNull($individualmember->requirescontact); 1725 $this->assertNotNull($individualmember->canmessage); 1726 $this->assertNotEmpty($individualmember->contactrequests); 1727 } 1728 1729 /** 1730 * Test verifying that group linked conversations are returned and contain a subname matching the course name. 1731 */ 1732 public function test_get_conversations_group_linked() { 1733 global $CFG, $DB; 1734 1735 // Create some users. 1736 $user1 = self::getDataGenerator()->create_user(); 1737 $user2 = self::getDataGenerator()->create_user(); 1738 $user3 = self::getDataGenerator()->create_user(); 1739 1740 $course1 = $this->getDataGenerator()->create_course(); 1741 1742 // Create a group with a linked conversation and a valid image. 1743 $this->setAdminUser(); 1744 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 1745 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 1746 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 1747 $group1 = $this->getDataGenerator()->create_group([ 1748 'courseid' => $course1->id, 1749 'enablemessaging' => 1, 1750 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' 1751 ]); 1752 1753 // Add users to group1. 1754 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 1755 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 1756 1757 // Verify the group with the image works as expected. 1758 $conversations = api::get_conversations($user1->id); 1759 $this->assertEquals(2, $conversations[0]->membercount); 1760 $this->assertEquals($course1->shortname, $conversations[0]->subname); 1761 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true); 1762 $this->assertEquals($groupimageurl, $conversations[0]->imageurl); 1763 1764 // Create a group with a linked conversation and without any image. 1765 $group2 = $this->getDataGenerator()->create_group([ 1766 'courseid' => $course1->id, 1767 'enablemessaging' => 1, 1768 ]); 1769 1770 // Add users to group2. 1771 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)); 1772 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id)); 1773 1774 // Verify the group without any image works as expected too. 1775 $conversations = api::get_conversations($user3->id); 1776 // Consider first conversations is self-conversation. 1777 $this->assertEquals(2, $conversations[0]->membercount); 1778 $this->assertEquals($course1->shortname, $conversations[0]->subname); 1779 $this->assertEquals('https://www.example.com/moodle/theme/image.php/_s/boost/core/1/g/g1', $conversations[0]->imageurl); 1780 1781 // Now, disable the conversation linked to the group and verify it's no longer returned. 1782 $DB->set_field('message_conversations', 'enabled', 0, ['id' => $conversations[0]->id]); 1783 $conversations = api::get_conversations($user3->id); 1784 $this->assertCount(1, $conversations); 1785 } 1786 1787 /** 1788 * The data provider for get_conversations_mixed. 1789 * 1790 * This provides sets of data to for testing. 1791 * @return array 1792 */ 1793 public function get_conversations_mixed_provider() { 1794 return array( 1795 'Test that conversations with messages contacts is correctly ordered.' => array( 1796 'users' => array( 1797 'user1', 1798 'user2', 1799 'user3', 1800 ), 1801 'contacts' => array( 1802 ), 1803 'messages' => array( 1804 array( 1805 'from' => 'user1', 1806 'to' => 'user2', 1807 'state' => 'unread', 1808 'subject' => 'S1', 1809 ), 1810 array( 1811 'from' => 'user2', 1812 'to' => 'user1', 1813 'state' => 'unread', 1814 'subject' => 'S2', 1815 ), 1816 array( 1817 'from' => 'user1', 1818 'to' => 'user2', 1819 'state' => 'unread', 1820 'timecreated' => 0, 1821 'subject' => 'S3', 1822 ), 1823 array( 1824 'from' => 'user1', 1825 'to' => 'user3', 1826 'state' => 'read', 1827 'timemodifier' => 1, 1828 'subject' => 'S4', 1829 ), 1830 array( 1831 'from' => 'user3', 1832 'to' => 'user1', 1833 'state' => 'read', 1834 'timemodifier' => 1, 1835 'subject' => 'S5', 1836 ), 1837 array( 1838 'from' => 'user1', 1839 'to' => 'user3', 1840 'state' => 'read', 1841 'timecreated' => 0, 1842 'subject' => 'S6', 1843 ), 1844 ), 1845 'expectations' => array( 1846 'user1' => array( 1847 // User1 has conversed most recently with user3. The most recent message is M5. 1848 array( 1849 'messageposition' => 0, 1850 'with' => 'user3', 1851 'subject' => '<p>S5</p>', 1852 'unreadcount' => 0, 1853 ), 1854 // User1 has also conversed with user2. The most recent message is S2. 1855 array( 1856 'messageposition' => 1, 1857 'with' => 'user2', 1858 'subject' => '<p>S2</p>', 1859 'unreadcount' => 1, 1860 ), 1861 ), 1862 'user2' => array( 1863 // User2 has only conversed with user1. Their most recent shared message was S2. 1864 array( 1865 'messageposition' => 0, 1866 'with' => 'user1', 1867 'subject' => '<p>S2</p>', 1868 'unreadcount' => 2, 1869 ), 1870 ), 1871 'user3' => array( 1872 // User3 has only conversed with user1. Their most recent shared message was S5. 1873 array( 1874 'messageposition' => 0, 1875 'with' => 'user1', 1876 'subject' => '<p>S5</p>', 1877 'unreadcount' => 0, 1878 ), 1879 ), 1880 ), 1881 ), 1882 'Test conversations with a single user, where some messages are read and some are not.' => array( 1883 'users' => array( 1884 'user1', 1885 'user2', 1886 ), 1887 'contacts' => array( 1888 ), 1889 'messages' => array( 1890 array( 1891 'from' => 'user1', 1892 'to' => 'user2', 1893 'state' => 'read', 1894 'subject' => 'S1', 1895 ), 1896 array( 1897 'from' => 'user2', 1898 'to' => 'user1', 1899 'state' => 'read', 1900 'subject' => 'S2', 1901 ), 1902 array( 1903 'from' => 'user1', 1904 'to' => 'user2', 1905 'state' => 'unread', 1906 'timemodifier' => 1, 1907 'subject' => 'S3', 1908 ), 1909 array( 1910 'from' => 'user1', 1911 'to' => 'user2', 1912 'state' => 'unread', 1913 'timemodifier' => 1, 1914 'subject' => 'S4', 1915 ), 1916 ), 1917 'expectations' => array( 1918 // The most recent message between user1 and user2 was S4. 1919 'user1' => array( 1920 array( 1921 'messageposition' => 0, 1922 'with' => 'user2', 1923 'subject' => '<p>S4</p>', 1924 'unreadcount' => 0, 1925 ), 1926 ), 1927 'user2' => array( 1928 // The most recent message between user1 and user2 was S4. 1929 array( 1930 'messageposition' => 0, 1931 'with' => 'user1', 1932 'subject' => '<p>S4</p>', 1933 'unreadcount' => 2, 1934 ), 1935 ), 1936 ), 1937 ), 1938 'Test conversations with a single user, where some messages are read and some are not, and messages ' . 1939 'are out of order' => array( 1940 // This can happen through a combination of factors including multi-master DB replication with messages 1941 // read somehow (e.g. API). 1942 'users' => array( 1943 'user1', 1944 'user2', 1945 ), 1946 'contacts' => array( 1947 ), 1948 'messages' => array( 1949 array( 1950 'from' => 'user1', 1951 'to' => 'user2', 1952 'state' => 'read', 1953 'subject' => 'S1', 1954 'timemodifier' => 1, 1955 ), 1956 array( 1957 'from' => 'user2', 1958 'to' => 'user1', 1959 'state' => 'read', 1960 'subject' => 'S2', 1961 'timemodifier' => 2, 1962 ), 1963 array( 1964 'from' => 'user1', 1965 'to' => 'user2', 1966 'state' => 'unread', 1967 'subject' => 'S3', 1968 ), 1969 array( 1970 'from' => 'user1', 1971 'to' => 'user2', 1972 'state' => 'unread', 1973 'subject' => 'S4', 1974 ), 1975 ), 1976 'expectations' => array( 1977 // The most recent message between user1 and user2 was S2, even though later IDs have not been read. 1978 'user1' => array( 1979 array( 1980 'messageposition' => 0, 1981 'with' => 'user2', 1982 'subject' => '<p>S2</p>', 1983 'unreadcount' => 0, 1984 ), 1985 ), 1986 'user2' => array( 1987 array( 1988 'messageposition' => 0, 1989 'with' => 'user1', 1990 'subject' => '<p>S2</p>', 1991 'unreadcount' => 2 1992 ), 1993 ), 1994 ), 1995 ), 1996 'Test unread message count is correct for both users' => array( 1997 'users' => array( 1998 'user1', 1999 'user2', 2000 ), 2001 'contacts' => array( 2002 ), 2003 'messages' => array( 2004 array( 2005 'from' => 'user1', 2006 'to' => 'user2', 2007 'state' => 'read', 2008 'subject' => 'S1', 2009 'timemodifier' => 1, 2010 ), 2011 array( 2012 'from' => 'user2', 2013 'to' => 'user1', 2014 'state' => 'read', 2015 'subject' => 'S2', 2016 'timemodifier' => 2, 2017 ), 2018 array( 2019 'from' => 'user1', 2020 'to' => 'user2', 2021 'state' => 'read', 2022 'subject' => 'S3', 2023 'timemodifier' => 3, 2024 ), 2025 array( 2026 'from' => 'user1', 2027 'to' => 'user2', 2028 'state' => 'read', 2029 'subject' => 'S4', 2030 'timemodifier' => 4, 2031 ), 2032 array( 2033 'from' => 'user1', 2034 'to' => 'user2', 2035 'state' => 'unread', 2036 'subject' => 'S5', 2037 'timemodifier' => 5, 2038 ), 2039 array( 2040 'from' => 'user2', 2041 'to' => 'user1', 2042 'state' => 'unread', 2043 'subject' => 'S6', 2044 'timemodifier' => 6, 2045 ), 2046 array( 2047 'from' => 'user1', 2048 'to' => 'user2', 2049 'state' => 'unread', 2050 'subject' => 'S7', 2051 'timemodifier' => 7, 2052 ), 2053 array( 2054 'from' => 'user1', 2055 'to' => 'user2', 2056 'state' => 'unread', 2057 'subject' => 'S8', 2058 'timemodifier' => 8, 2059 ), 2060 ), 2061 'expectations' => array( 2062 // The most recent message between user1 and user2 was S2, even though later IDs have not been read. 2063 'user1' => array( 2064 array( 2065 'messageposition' => 0, 2066 'with' => 'user2', 2067 'subject' => '<p>S8</p>', 2068 'unreadcount' => 1, 2069 ), 2070 ), 2071 'user2' => array( 2072 array( 2073 'messageposition' => 0, 2074 'with' => 'user1', 2075 'subject' => '<p>S8</p>', 2076 'unreadcount' => 3, 2077 ), 2078 ), 2079 ), 2080 ), 2081 ); 2082 } 2083 2084 /** 2085 * Test that creation can't create the same conversation twice for 1:1 conversations. 2086 */ 2087 public function test_create_conversation_duplicate_conversations() { 2088 global $DB; 2089 $user1 = $this::getDataGenerator()->create_user(); 2090 2091 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]); 2092 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]); 2093 2094 $convhash = helper::get_conversation_hash([$user1->id]); 2095 $countconversations = $DB->count_records('message_conversations', ['convhash' => $convhash]); 2096 $this->assertEquals(1, $countconversations); 2097 $this->assertNotEmpty($conversation = api::get_self_conversation($user1->id)); 2098 } 2099 2100 /** 2101 * Test get_conversations with a mixture of messages. 2102 * 2103 * @dataProvider get_conversations_mixed_provider 2104 * @param array $usersdata The list of users to create for this test. 2105 * @param array $messagesdata The list of messages to create. 2106 * @param array $expectations The list of expected outcomes. 2107 */ 2108 public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) { 2109 global $DB; 2110 2111 // Create all of the users. 2112 $users = array(); 2113 foreach ($usersdata as $username) { 2114 $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username)); 2115 } 2116 2117 foreach ($contacts as $username => $contact) { 2118 foreach ($contact as $contactname => $blocked) { 2119 $record = new \stdClass(); 2120 $record->userid = $users[$username]->id; 2121 $record->contactid = $users[$contactname]->id; 2122 $record->blocked = $blocked; 2123 $record->id = $DB->insert_record('message_contacts', $record); 2124 } 2125 } 2126 2127 $defaulttimecreated = time(); 2128 foreach ($messagesdata as $messagedata) { 2129 $from = $users[$messagedata['from']]; 2130 $to = $users[$messagedata['to']]; 2131 $subject = $messagedata['subject']; 2132 2133 if (isset($messagedata['state']) && $messagedata['state'] == 'unread') { 2134 $messageid = $this->send_fake_message($from, $to, $subject); 2135 } else { 2136 // If there is no state, or the state is not 'unread', assume the message is read. 2137 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN); 2138 } 2139 2140 $updatemessage = new \stdClass(); 2141 $updatemessage->id = $messageid; 2142 if (isset($messagedata['timecreated'])) { 2143 $updatemessage->timecreated = $messagedata['timecreated']; 2144 } else if (isset($messagedata['timemodifier'])) { 2145 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier']; 2146 } else { 2147 $updatemessage->timecreated = $defaulttimecreated; 2148 } 2149 2150 $DB->update_record('messages', $updatemessage); 2151 } 2152 2153 foreach ($expectations as $username => $data) { 2154 // Get the recent conversations for the specified user. 2155 $user = $users[$username]; 2156 $conversations = array_values(api::get_conversations($user->id)); 2157 foreach ($data as $expectation) { 2158 $otheruser = $users[$expectation['with']]; 2159 $conversation = $conversations[$expectation['messageposition']]; 2160 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id); 2161 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text); 2162 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount); 2163 } 2164 } 2165 } 2166 2167 /** 2168 * Tests retrieving user contacts. 2169 */ 2170 public function test_get_user_contacts() { 2171 // Create some users. 2172 $user1 = self::getDataGenerator()->create_user(); 2173 2174 // Set as the user. 2175 $this->setUser($user1); 2176 2177 $user2 = new \stdClass(); 2178 $user2->firstname = 'User'; 2179 $user2->lastname = 'A'; 2180 $user2 = self::getDataGenerator()->create_user($user2); 2181 2182 $user3 = new \stdClass(); 2183 $user3->firstname = 'User'; 2184 $user3->lastname = 'B'; 2185 $user3 = self::getDataGenerator()->create_user($user3); 2186 2187 $user4 = new \stdClass(); 2188 $user4->firstname = 'User'; 2189 $user4->lastname = 'C'; 2190 $user4 = self::getDataGenerator()->create_user($user4); 2191 2192 $user5 = new \stdClass(); 2193 $user5->firstname = 'User'; 2194 $user5->lastname = 'D'; 2195 $user5 = self::getDataGenerator()->create_user($user5); 2196 2197 // Add some users as contacts. 2198 api::add_contact($user1->id, $user2->id); 2199 api::add_contact($user1->id, $user3->id); 2200 api::add_contact($user1->id, $user4->id); 2201 2202 // Retrieve the contacts. 2203 $contacts = api::get_user_contacts($user1->id); 2204 2205 // Confirm the data is correct. 2206 $this->assertEquals(3, count($contacts)); 2207 2208 ksort($contacts); 2209 2210 $contact1 = array_shift($contacts); 2211 $contact2 = array_shift($contacts); 2212 $contact3 = array_shift($contacts); 2213 2214 $this->assertEquals($user2->id, $contact1->id); 2215 $this->assertEquals(fullname($user2), $contact1->fullname); 2216 $this->assertTrue($contact1->iscontact); 2217 2218 $this->assertEquals($user3->id, $contact2->id); 2219 $this->assertEquals(fullname($user3), $contact2->fullname); 2220 $this->assertTrue($contact2->iscontact); 2221 2222 $this->assertEquals($user4->id, $contact3->id); 2223 $this->assertEquals(fullname($user4), $contact3->fullname); 2224 $this->assertTrue($contact3->iscontact); 2225 } 2226 2227 /** 2228 * Tests retrieving conversation messages. 2229 */ 2230 public function test_get_conversation_messages() { 2231 // Create some users. 2232 $user1 = self::getDataGenerator()->create_user(); 2233 $user2 = self::getDataGenerator()->create_user(); 2234 2235 // Create conversation. 2236 $conversation = api::create_conversation( 2237 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2238 [$user1->id, $user2->id] 2239 ); 2240 2241 // The person doing the search. 2242 $this->setUser($user1); 2243 2244 // Send some messages back and forth. 2245 $time = 1; 2246 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1); 2247 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2); 2248 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3); 2249 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4); 2250 2251 // Retrieve the messages. 2252 $convmessages = api::get_conversation_messages($user1->id, $conversation->id); 2253 2254 // Confirm the conversation id is correct. 2255 $this->assertEquals($conversation->id, $convmessages['id']); 2256 2257 // Confirm the message data is correct. 2258 $messages = $convmessages['messages']; 2259 $this->assertEquals(4, count($messages)); 2260 $message1 = $messages[0]; 2261 $message2 = $messages[1]; 2262 $message3 = $messages[2]; 2263 $message4 = $messages[3]; 2264 2265 $this->assertEquals($user1->id, $message1->useridfrom); 2266 $this->assertStringContainsString('Yo!', $message1->text); 2267 2268 $this->assertEquals($user2->id, $message2->useridfrom); 2269 $this->assertStringContainsString('Sup mang?', $message2->text); 2270 2271 $this->assertEquals($user1->id, $message3->useridfrom); 2272 $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text); 2273 2274 $this->assertEquals($user1->id, $message4->useridfrom); 2275 $this->assertStringContainsString('Word.', $message4->text); 2276 2277 // Confirm the members data is correct. 2278 $members = $convmessages['members']; 2279 $this->assertEquals(2, count($members)); 2280 } 2281 2282 /** 2283 * Tests retrieving group conversation messages. 2284 */ 2285 public function test_get_group_conversation_messages() { 2286 // Create some users. 2287 $user1 = self::getDataGenerator()->create_user(); 2288 $user2 = self::getDataGenerator()->create_user(); 2289 $user3 = self::getDataGenerator()->create_user(); 2290 $user4 = self::getDataGenerator()->create_user(); 2291 2292 // Create group conversation. 2293 $conversation = api::create_conversation( 2294 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2295 [$user1->id, $user2->id, $user3->id, $user4->id] 2296 ); 2297 2298 // The person doing the search. 2299 $this->setUser($user1); 2300 2301 // Send some messages back and forth. 2302 $time = 1; 2303 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1); 2304 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2); 2305 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3); 2306 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4); 2307 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5); 2308 2309 // Retrieve the messages. 2310 $convmessages = api::get_conversation_messages($user1->id, $conversation->id); 2311 2312 // Confirm the conversation id is correct. 2313 $this->assertEquals($conversation->id, $convmessages['id']); 2314 2315 // Confirm the message data is correct. 2316 $messages = $convmessages['messages']; 2317 $this->assertEquals(5, count($messages)); 2318 2319 $message1 = $messages[0]; 2320 $message2 = $messages[1]; 2321 $message3 = $messages[2]; 2322 $message4 = $messages[3]; 2323 $message5 = $messages[4]; 2324 2325 $this->assertEquals($user1->id, $message1->useridfrom); 2326 $this->assertStringContainsString('Yo!', $message1->text); 2327 2328 $this->assertEquals($user2->id, $message2->useridfrom); 2329 $this->assertStringContainsString('Sup mang?', $message2->text); 2330 2331 $this->assertEquals($user3->id, $message3->useridfrom); 2332 $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text); 2333 2334 $this->assertEquals($user1->id, $message4->useridfrom); 2335 $this->assertStringContainsString('Word.', $message4->text); 2336 2337 $this->assertEquals($user2->id, $message5->useridfrom); 2338 $this->assertStringContainsString('Yeah!', $message5->text); 2339 2340 // Confirm the members data is correct. 2341 $members = $convmessages['members']; 2342 $this->assertEquals(3, count($members)); 2343 } 2344 2345 /** 2346 * Test verifying the sorting param for get_conversation_messages is respected(). 2347 */ 2348 public function test_get_conversation_messages_sorting() { 2349 // Create some users. 2350 $user1 = self::getDataGenerator()->create_user(); 2351 $user2 = self::getDataGenerator()->create_user(); 2352 $user3 = self::getDataGenerator()->create_user(); 2353 2354 // Create conversations - 1 group and 1 individual. 2355 $conversation = api::create_conversation( 2356 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2357 [$user1->id, $user2->id] 2358 ); 2359 $conversation2 = api::create_conversation( 2360 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2361 [$user1->id, $user2->id, $user3->id] 2362 ); 2363 2364 // Send some messages back and forth. 2365 $time = 1; 2366 $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1); 2367 $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2); 2368 $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3); 2369 $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4); 2370 2371 $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1); 2372 $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2); 2373 $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3); 2374 $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4); 2375 2376 // The person doing the search. 2377 $this->setUser($user1); 2378 2379 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering. 2380 $convmessages = api::get_conversation_messages($user1->id, $conversation->id); 2381 $messages = $convmessages['messages']; 2382 $this->assertEquals($m1id, $messages[0]->id); 2383 $this->assertEquals($m2id, $messages[1]->id); 2384 $this->assertEquals($m3id, $messages[2]->id); 2385 $this->assertEquals($m4id, $messages[3]->id); 2386 2387 // Retrieve the messages without specifying DESC sort ordering, and verify ordering. 2388 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC'); 2389 $messages = $convmessages['messages']; 2390 $this->assertEquals($m1id, $messages[3]->id); 2391 $this->assertEquals($m2id, $messages[2]->id); 2392 $this->assertEquals($m3id, $messages[1]->id); 2393 $this->assertEquals($m4id, $messages[0]->id); 2394 2395 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering. 2396 $convmessages = api::get_conversation_messages($user1->id, $conversation2->id); 2397 $messages = $convmessages['messages']; 2398 $this->assertEquals($gm1id, $messages[0]->id); 2399 $this->assertEquals($gm2id, $messages[1]->id); 2400 $this->assertEquals($gm3id, $messages[2]->id); 2401 $this->assertEquals($gm4id, $messages[3]->id); 2402 2403 // Retrieve the messages without specifying DESC sort ordering, and verify ordering. 2404 $convmessages = api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC'); 2405 $messages = $convmessages['messages']; 2406 $this->assertEquals($gm1id, $messages[3]->id); 2407 $this->assertEquals($gm2id, $messages[2]->id); 2408 $this->assertEquals($gm3id, $messages[1]->id); 2409 $this->assertEquals($gm4id, $messages[0]->id); 2410 } 2411 2412 /** 2413 * Test retrieving conversation messages by providing a minimum timecreated value. 2414 */ 2415 public function test_get_conversation_messages_time_from_only() { 2416 // Create some users. 2417 $user1 = self::getDataGenerator()->create_user(); 2418 $user2 = self::getDataGenerator()->create_user(); 2419 $user3 = self::getDataGenerator()->create_user(); 2420 $user4 = self::getDataGenerator()->create_user(); 2421 2422 // Create group conversation. 2423 $conversation = api::create_conversation( 2424 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2425 [$user1->id, $user2->id, $user3->id, $user4->id] 2426 ); 2427 2428 // The person doing the search. 2429 $this->setUser($user1); 2430 2431 // Send some messages back and forth. 2432 $time = 1; 2433 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 2434 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 2435 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 2436 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 2437 2438 // Retrieve the messages from $time, which should be all of them. 2439 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time); 2440 2441 // Confirm the conversation id is correct. 2442 $this->assertEquals($conversation->id, $convmessages['id']); 2443 2444 // Confirm the message data is correct. 2445 $messages = $convmessages['messages']; 2446 $this->assertEquals(4, count($messages)); 2447 2448 $message1 = $messages[0]; 2449 $message2 = $messages[1]; 2450 $message3 = $messages[2]; 2451 $message4 = $messages[3]; 2452 2453 $this->assertStringContainsString('Message 1', $message1->text); 2454 $this->assertStringContainsString('Message 2', $message2->text); 2455 $this->assertStringContainsString('Message 3', $message3->text); 2456 $this->assertStringContainsString('Message 4', $message4->text); 2457 2458 // Confirm the members data is correct. 2459 $members = $convmessages['members']; 2460 $this->assertEquals(3, count($members)); 2461 2462 // Retrieve the messages from $time + 3, which should only be the 2 last messages. 2463 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 2464 'timecreated ASC', $time + 3); 2465 2466 // Confirm the conversation id is correct. 2467 $this->assertEquals($conversation->id, $convmessages['id']); 2468 2469 // Confirm the message data is correct. 2470 $messages = $convmessages['messages']; 2471 $this->assertEquals(2, count($messages)); 2472 2473 $message1 = $messages[0]; 2474 $message2 = $messages[1]; 2475 2476 $this->assertStringContainsString('Message 3', $message1->text); 2477 $this->assertStringContainsString('Message 4', $message2->text); 2478 2479 // Confirm the members data is correct. 2480 $members = $convmessages['members']; 2481 $this->assertEquals(2, count($members)); 2482 } 2483 2484 /** 2485 * Test retrieving conversation messages by providing a maximum timecreated value. 2486 */ 2487 public function test_get_conversation_messages_time_to_only() { 2488 // Create some users. 2489 $user1 = self::getDataGenerator()->create_user(); 2490 $user2 = self::getDataGenerator()->create_user(); 2491 $user3 = self::getDataGenerator()->create_user(); 2492 $user4 = self::getDataGenerator()->create_user(); 2493 2494 // Create group conversation. 2495 $conversation = api::create_conversation( 2496 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2497 [$user1->id, $user2->id, $user3->id, $user4->id] 2498 ); 2499 2500 // The person doing the search. 2501 $this->setUser($user1); 2502 2503 // Send some messages back and forth. 2504 $time = 1; 2505 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 2506 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 2507 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 2508 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 2509 2510 // Retrieve the messages up until $time + 4, which should be all of them. 2511 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', 2512 0, $time + 4); 2513 2514 // Confirm the conversation id is correct. 2515 $this->assertEquals($conversation->id, $convmessages['id']); 2516 2517 // Confirm the message data is correct. 2518 $messages = $convmessages['messages']; 2519 $this->assertEquals(4, count($messages)); 2520 2521 $message1 = $messages[0]; 2522 $message2 = $messages[1]; 2523 $message3 = $messages[2]; 2524 $message4 = $messages[3]; 2525 2526 $this->assertStringContainsString('Message 1', $message1->text); 2527 $this->assertStringContainsString('Message 2', $message2->text); 2528 $this->assertStringContainsString('Message 3', $message3->text); 2529 $this->assertStringContainsString('Message 4', $message4->text); 2530 2531 // Confirm the members data is correct. 2532 $members = $convmessages['members']; 2533 $this->assertEquals(3, count($members)); 2534 2535 // Retrieve the messages up until $time + 2, which should be the first two. 2536 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', 2537 0, $time + 2); 2538 2539 // Confirm the conversation id is correct. 2540 $this->assertEquals($conversation->id, $convmessages['id']); 2541 2542 // Confirm the message data is correct. 2543 $messages = $convmessages['messages']; 2544 $this->assertEquals(2, count($messages)); 2545 2546 $message1 = $messages[0]; 2547 $message2 = $messages[1]; 2548 2549 $this->assertStringContainsString('Message 1', $message1->text); 2550 $this->assertStringContainsString('Message 2', $message2->text); 2551 2552 // Confirm the members data is correct. 2553 $members = $convmessages['members']; 2554 $this->assertEquals(2, count($members)); 2555 } 2556 2557 /** 2558 * Test retrieving conversation messages by providing a minimum and maximum timecreated value. 2559 */ 2560 public function test_get_conversation_messages_time_from_and_to() { 2561 // Create some users. 2562 $user1 = self::getDataGenerator()->create_user(); 2563 $user2 = self::getDataGenerator()->create_user(); 2564 $user3 = self::getDataGenerator()->create_user(); 2565 $user4 = self::getDataGenerator()->create_user(); 2566 2567 // Create group conversation. 2568 $conversation = api::create_conversation( 2569 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2570 [$user1->id, $user2->id, $user3->id, $user4->id] 2571 ); 2572 2573 // The person doing the search. 2574 $this->setUser($user1); 2575 2576 // Send some messages back and forth. 2577 $time = 1; 2578 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 2579 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 2580 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 2581 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 2582 2583 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message. 2584 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 2585 'timecreated ASC', $time + 2, $time + 3); 2586 2587 // Confirm the conversation id is correct. 2588 $this->assertEquals($conversation->id, $convmessages['id']); 2589 2590 // Confirm the message data is correct. 2591 $messages = $convmessages['messages']; 2592 $this->assertEquals(2, count($messages)); 2593 2594 $message1 = $messages[0]; 2595 $message2 = $messages[1]; 2596 2597 $this->assertStringContainsString('Message 2', $message1->text); 2598 $this->assertStringContainsString('Message 3', $message2->text); 2599 2600 // Confirm the members data is correct. 2601 $members = $convmessages['members']; 2602 $this->assertEquals(2, count($members)); 2603 } 2604 2605 2606 /** 2607 * Test retrieving conversation messages by providing a limitfrom value. 2608 */ 2609 public function test_get_conversation_messages_limitfrom_only() { 2610 // Create some users. 2611 $user1 = self::getDataGenerator()->create_user(); 2612 $user2 = self::getDataGenerator()->create_user(); 2613 $user3 = self::getDataGenerator()->create_user(); 2614 $user4 = self::getDataGenerator()->create_user(); 2615 2616 // Create group conversation. 2617 $conversation = api::create_conversation( 2618 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2619 [$user1->id, $user2->id, $user3->id, $user4->id] 2620 ); 2621 2622 // The person doing the search. 2623 $this->setUser($user1); 2624 2625 // Send some messages back and forth. 2626 $time = 1; 2627 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 2628 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 2629 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 2630 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 2631 2632 // Retrieve the messages from $time, which should be all of them. 2633 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 2); 2634 2635 // Confirm the conversation id is correct. 2636 $messages = $convmessages['messages']; 2637 $this->assertEquals($conversation->id, $convmessages['id']); 2638 2639 // Confirm the message data is correct. 2640 $this->assertEquals(2, count($messages)); 2641 2642 $message1 = $messages[0]; 2643 $message2 = $messages[1]; 2644 2645 $this->assertStringContainsString('Message 3', $message1->text); 2646 $this->assertStringContainsString('Message 4', $message2->text); 2647 2648 // Confirm the members data is correct. 2649 $members = $convmessages['members']; 2650 $this->assertEquals(2, count($members)); 2651 } 2652 2653 /** 2654 * Test retrieving conversation messages by providing a limitnum value. 2655 */ 2656 public function test_get_conversation_messages_limitnum() { 2657 // Create some users. 2658 $user1 = self::getDataGenerator()->create_user(); 2659 $user2 = self::getDataGenerator()->create_user(); 2660 $user3 = self::getDataGenerator()->create_user(); 2661 $user4 = self::getDataGenerator()->create_user(); 2662 2663 // Create group conversation. 2664 $conversation = api::create_conversation( 2665 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2666 [$user1->id, $user2->id, $user3->id, $user4->id] 2667 ); 2668 2669 // The person doing the search. 2670 $this->setUser($user1); 2671 2672 // Send some messages back and forth. 2673 $time = 1; 2674 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 2675 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 2676 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 2677 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 2678 2679 // Retrieve the messages from $time, which should be all of them. 2680 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 2, 1); 2681 2682 // Confirm the conversation id is correct. 2683 $messages = $convmessages['messages']; 2684 $this->assertEquals($conversation->id, $convmessages['id']); 2685 2686 // Confirm the message data is correct. 2687 $messages = $convmessages['messages']; 2688 $this->assertEquals(1, count($messages)); 2689 2690 $message1 = $messages[0]; 2691 2692 $this->assertStringContainsString('Message 3', $message1->text); 2693 2694 // Confirm the members data is correct. 2695 $members = $convmessages['members']; 2696 $this->assertEquals(1, count($members)); 2697 } 2698 2699 /** 2700 * Tests retrieving most recent conversation message. 2701 */ 2702 public function test_get_most_recent_conversation_message() { 2703 // Create some users. 2704 $user1 = self::getDataGenerator()->create_user(); 2705 $user2 = self::getDataGenerator()->create_user(); 2706 $user3 = self::getDataGenerator()->create_user(); 2707 2708 // Create group conversation. 2709 $conversation = api::create_conversation( 2710 api::MESSAGE_CONVERSATION_TYPE_GROUP, 2711 [$user1->id, $user2->id, $user3->id] 2712 ); 2713 2714 // The person getting the most recent conversation message. 2715 $this->setUser($user1); 2716 2717 // Send some messages back and forth. 2718 $time = 1; 2719 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1); 2720 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2); 2721 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3); 2722 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4); 2723 2724 // Retrieve the most recent messages. 2725 $message = api::get_most_recent_conversation_message($conversation->id, $user1->id); 2726 2727 // Check the results are correct. 2728 $this->assertEquals($user2->id, $message->useridfrom); 2729 $this->assertStringContainsString('Word.', $message->text); 2730 } 2731 2732 /** 2733 * Tests checking if a user can mark all messages as read. 2734 */ 2735 public function test_can_mark_all_messages_as_read() { 2736 // Set as the admin. 2737 $this->setAdminUser(); 2738 2739 // Create some users. 2740 $user1 = self::getDataGenerator()->create_user(); 2741 $user2 = self::getDataGenerator()->create_user(); 2742 $user3 = self::getDataGenerator()->create_user(); 2743 2744 // Send some messages back and forth. 2745 $time = 1; 2746 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 2747 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 2748 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 2749 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 2750 2751 $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]); 2752 2753 // The admin can do anything. 2754 $this->assertTrue(api::can_mark_all_messages_as_read($user1->id, $conversationid)); 2755 2756 // Set as the user 1. 2757 $this->setUser($user1); 2758 2759 // The user can mark the messages as he is in the conversation. 2760 $this->assertTrue(api::can_mark_all_messages_as_read($user1->id, $conversationid)); 2761 2762 // User 1 can not mark the messages read for user 2. 2763 $this->assertFalse(api::can_mark_all_messages_as_read($user2->id, $conversationid)); 2764 2765 // This user is not a part of the conversation. 2766 $this->assertFalse(api::can_mark_all_messages_as_read($user3->id, $conversationid)); 2767 } 2768 2769 /** 2770 * Tests checking if a user can delete a conversation. 2771 */ 2772 public function test_can_delete_conversation() { 2773 // Set as the admin. 2774 $this->setAdminUser(); 2775 2776 // Create some users. 2777 $user1 = self::getDataGenerator()->create_user(); 2778 $user2 = self::getDataGenerator()->create_user(); 2779 2780 // Send some messages back and forth. 2781 $time = 1; 2782 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 2783 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 2784 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 2785 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 2786 2787 $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]); 2788 2789 // The admin can do anything. 2790 $this->assertTrue(api::can_delete_conversation($user1->id, $conversationid)); 2791 2792 // Set as the user 1. 2793 $this->setUser($user1); 2794 2795 // They can delete their own messages. 2796 $this->assertTrue(api::can_delete_conversation($user1->id, $conversationid)); 2797 2798 // They can't delete someone elses. 2799 $this->assertFalse(api::can_delete_conversation($user2->id, $conversationid)); 2800 } 2801 2802 /** 2803 * Tests deleting a conversation by conversation id. 2804 */ 2805 public function test_delete_conversation_by_id() { 2806 global $DB; 2807 2808 // Create some users. 2809 $user1 = self::getDataGenerator()->create_user(); 2810 $user2 = self::getDataGenerator()->create_user(); 2811 2812 // The person doing the search. 2813 $this->setUser($user1); 2814 2815 // Get self-conversation. 2816 $sc1 = api::get_self_conversation($user1->id); 2817 $sc2 = api::get_self_conversation($user2->id); 2818 2819 // Send some messages back and forth. 2820 $time = 1; 2821 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1); 2822 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2); 2823 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3); 2824 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4); 2825 $m5id = testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi to myself!', $time + 5); 2826 $m6id = testhelper::send_fake_message_to_conversation($user2, $sc2->id, 'I am talking with myself', $time + 6); 2827 2828 $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]); 2829 2830 // Delete the individual conversation between user1 and user2 (only for user1). 2831 api::delete_conversation_by_id($user1->id, $conversationid); 2832 2833 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 2834 $this->assertCount(4, $muas); 2835 // Sort by id. 2836 ksort($muas); 2837 2838 $mua1 = array_shift($muas); 2839 $mua2 = array_shift($muas); 2840 $mua3 = array_shift($muas); 2841 $mua4 = array_shift($muas); 2842 2843 $this->assertEquals($user1->id, $mua1->userid); 2844 $this->assertEquals($m1id, $mua1->messageid); 2845 $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua1->action); 2846 2847 $this->assertEquals($user1->id, $mua2->userid); 2848 $this->assertEquals($m2id, $mua2->messageid); 2849 $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua2->action); 2850 2851 $this->assertEquals($user1->id, $mua3->userid); 2852 $this->assertEquals($m3id, $mua3->messageid); 2853 $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua3->action); 2854 2855 $this->assertEquals($user1->id, $mua4->userid); 2856 $this->assertEquals($m4id, $mua4->messageid); 2857 $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua4->action); 2858 2859 // Delete the self-conversation as user 1. 2860 api::delete_conversation_by_id($user1->id, $sc1->id); 2861 2862 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 2863 $this->assertCount(5, $muas); 2864 2865 // Sort by id. 2866 ksort($muas); 2867 2868 $mua1 = array_shift($muas); 2869 $mua2 = array_shift($muas); 2870 $mua3 = array_shift($muas); 2871 $mua4 = array_shift($muas); 2872 $mua5 = array_shift($muas); 2873 2874 // Check only messages in self-conversion for user1 are deleted (self-conversation for user2 shouldn't be removed). 2875 $this->assertEquals($user1->id, $mua5->userid); 2876 $this->assertEquals($m5id, $mua5->messageid); 2877 $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua5->action); 2878 } 2879 2880 /** 2881 * Tests counting unread conversations. 2882 */ 2883 public function test_count_unread_conversations() { 2884 $this->resetAfterTest(true); 2885 2886 // Create some users. 2887 $user1 = self::getDataGenerator()->create_user(); 2888 $user2 = self::getDataGenerator()->create_user(); 2889 $user3 = self::getDataGenerator()->create_user(); 2890 $user4 = self::getDataGenerator()->create_user(); 2891 2892 // The person wanting the conversation count. 2893 $this->setUser($user1); 2894 2895 // Send some messages back and forth, have some different conversations with different users. 2896 $this->send_fake_message($user1, $user2, 'Yo!'); 2897 $this->send_fake_message($user2, $user1, 'Sup mang?'); 2898 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!'); 2899 $this->send_fake_message($user2, $user1, 'Word.'); 2900 2901 $this->send_fake_message($user1, $user3, 'Booyah'); 2902 $this->send_fake_message($user3, $user1, 'Whaaat?'); 2903 $this->send_fake_message($user1, $user3, 'Nothing.'); 2904 $this->send_fake_message($user3, $user1, 'Cool.'); 2905 2906 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 2907 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 2908 $this->send_fake_message($user1, $user4, 'Dope.'); 2909 2910 // Check the amount for the current user. 2911 $this->assertEquals(3, api::count_unread_conversations()); 2912 2913 // Check the amount for the second user. 2914 $this->assertEquals(1, api::count_unread_conversations($user2)); 2915 } 2916 2917 /** 2918 * Tests counting unread conversations where one conversation is disabled. 2919 */ 2920 public function test_count_unread_conversations_disabled() { 2921 $this->resetAfterTest(true); 2922 2923 // Create some users. 2924 $user1 = self::getDataGenerator()->create_user(); 2925 $user2 = self::getDataGenerator()->create_user(); 2926 $user3 = self::getDataGenerator()->create_user(); 2927 $user4 = self::getDataGenerator()->create_user(); 2928 2929 // The person wanting the conversation count. 2930 $this->setUser($user1); 2931 2932 // Send some messages back and forth, have some different conversations with different users. 2933 $this->send_fake_message($user1, $user2, 'Yo!'); 2934 $this->send_fake_message($user2, $user1, 'Sup mang?'); 2935 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!'); 2936 $this->send_fake_message($user2, $user1, 'Word.'); 2937 2938 $this->send_fake_message($user1, $user3, 'Booyah'); 2939 $this->send_fake_message($user3, $user1, 'Whaaat?'); 2940 $this->send_fake_message($user1, $user3, 'Nothing.'); 2941 $this->send_fake_message($user3, $user1, 'Cool.'); 2942 2943 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 2944 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 2945 $this->send_fake_message($user1, $user4, 'Dope.'); 2946 2947 // Let's disable the last conversation. 2948 $conversationid = api::get_conversation_between_users([$user1->id, $user4->id]); 2949 api::disable_conversation($conversationid); 2950 2951 // Check that the disabled conversation was not included. 2952 $this->assertEquals(2, api::count_unread_conversations()); 2953 } 2954 2955 /** 2956 * Tests deleting a conversation. 2957 */ 2958 public function test_get_all_message_preferences() { 2959 $user = self::getDataGenerator()->create_user(); 2960 $this->setUser($user); 2961 2962 // Set a couple of preferences to test. 2963 set_user_preference('message_provider_mod_assign_assign_notification_enabled', 'popup', $user); 2964 set_user_preference('message_provider_mod_feedback_submission_enabled', 'email', $user); 2965 2966 $processors = get_message_processors(); 2967 $providers = message_get_providers_for_user($user->id); 2968 $prefs = api::get_all_message_preferences($processors, $providers, $user); 2969 2970 $this->assertEquals(1, $prefs->mod_assign_assign_notification_enabled['popup']); 2971 $this->assertEquals(1, $prefs->mod_feedback_submission_enabled['email']); 2972 } 2973 2974 /** 2975 * Tests the user can send a message. 2976 */ 2977 public function test_can_send_message() { 2978 // Create some users. 2979 $user1 = self::getDataGenerator()->create_user(); 2980 $user2 = self::getDataGenerator()->create_user(); 2981 2982 // Set as the first user. 2983 $this->setUser($user1); 2984 2985 // With the default privacy setting, users can't message them. 2986 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 2987 2988 // Enrol users to the same course. 2989 $course = $this->getDataGenerator()->create_course(); 2990 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 2991 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 2992 // After enrolling users to the course, they should be able to message them with the default privacy setting. 2993 $this->assertTrue(api::can_send_message($user2->id, $user1->id)); 2994 } 2995 2996 /** 2997 * Tests the user can't send a message without proper capability. 2998 */ 2999 public function test_can_send_message_without_sendmessage_cap() { 3000 global $DB; 3001 3002 // Create some users. 3003 $user1 = self::getDataGenerator()->create_user(); 3004 $user2 = self::getDataGenerator()->create_user(); 3005 3006 // Set as the user 1. 3007 $this->setUser($user1); 3008 3009 // Remove the capability to send a message. 3010 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); 3011 unassign_capability('moodle/site:sendmessage', $roleids['user'], 3012 \context_system::instance()); 3013 3014 // Check that we can not post a message without the capability. 3015 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3016 } 3017 3018 /** 3019 * Tests the user can send a message when they are contact. 3020 */ 3021 public function test_can_send_message_when_contact() { 3022 // Create some users. 3023 $user1 = self::getDataGenerator()->create_user(); 3024 $user2 = self::getDataGenerator()->create_user(); 3025 3026 // Set as the first user. 3027 $this->setUser($user1); 3028 3029 // Check that we can not send user2 a message. 3030 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3031 3032 // Add users as contacts. 3033 api::add_contact($user1->id, $user2->id); 3034 3035 // Check that the return result is now true. 3036 $this->assertTrue(api::can_send_message($user2->id, $user1->id)); 3037 } 3038 3039 /** 3040 * Tests the user can't send a message if they are not a contact and the user 3041 * has requested messages only from contacts. 3042 */ 3043 public function test_can_send_message_when_not_contact() { 3044 // Create some users. 3045 $user1 = self::getDataGenerator()->create_user(); 3046 $user2 = self::getDataGenerator()->create_user(); 3047 3048 // Set as the first user. 3049 $this->setUser($user1); 3050 3051 // Set the second user's preference to not receive messages from non-contacts. 3052 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3053 3054 // Check that we can not send user 2 a message. 3055 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3056 } 3057 3058 /** 3059 * Tests the user can't send a message if they are blocked. 3060 */ 3061 public function test_can_send_message_when_blocked() { 3062 // Create some users. 3063 $user1 = self::getDataGenerator()->create_user(); 3064 $user2 = self::getDataGenerator()->create_user(); 3065 3066 // Set the user. 3067 $this->setUser($user1); 3068 3069 // Block the second user. 3070 api::block_user($user1->id, $user2->id); 3071 3072 // Check that the second user can no longer send the first user a message. 3073 $this->assertFalse(api::can_send_message($user1->id, $user2->id)); 3074 } 3075 3076 /** 3077 * Tests the user can send a message when site-wide messaging setting is enabled, 3078 * even if they are not a contact and are not members of the same course. 3079 */ 3080 public function test_can_send_message_site_messaging_setting() { 3081 // Create some users. 3082 $user1 = self::getDataGenerator()->create_user(); 3083 $user2 = self::getDataGenerator()->create_user(); 3084 3085 // Set as the first user. 3086 $this->setUser($user1); 3087 3088 // By default, user only can be messaged by contacts and members of any of his/her courses. 3089 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3090 3091 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody. 3092 set_config('messagingallusers', true); 3093 3094 // Set the second user's preference to receive messages from everybody. 3095 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user2->id); 3096 3097 // Check that we can send user2 a message. 3098 $this->assertTrue(api::can_send_message($user2->id, $user1->id)); 3099 3100 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts 3101 // and members sharing a course with her. 3102 set_config('messagingallusers', false); 3103 3104 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER. 3105 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3106 3107 // Enrol users to the same course. 3108 $course = $this->getDataGenerator()->create_course(); 3109 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3110 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3111 // Check that we can send user2 a message because they are sharing a course. 3112 $this->assertTrue(api::can_send_message($user2->id, $user1->id)); 3113 3114 // Set the second user's preference to receive messages only from contacts. 3115 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3116 // Check that now the user2 can't be contacted because user1 is not their contact. 3117 $this->assertFalse(api::can_send_message($user2->id, $user1->id)); 3118 3119 // Make contacts user1 and user2. 3120 api::add_contact($user2->id, $user1->id); 3121 // Check that we can send user2 a message because they are contacts. 3122 $this->assertTrue(api::can_send_message($user2->id, $user1->id)); 3123 } 3124 3125 /** 3126 * Tests the user with the messageanyuser capability can send a message. 3127 */ 3128 public function test_can_send_message_with_messageanyuser_cap() { 3129 global $DB; 3130 3131 // Create some users. 3132 $teacher1 = self::getDataGenerator()->create_user(); 3133 $student1 = self::getDataGenerator()->create_user(); 3134 $student2 = self::getDataGenerator()->create_user(); 3135 3136 // Create users not enrolled in any course. 3137 $user1 = self::getDataGenerator()->create_user(); 3138 3139 // Create a course. 3140 $course1 = $this->getDataGenerator()->create_course(); 3141 3142 // Enrol the users in the course. 3143 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher'); 3144 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student'); 3145 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student'); 3146 3147 // Set some student preferences to not receive messages from non-contacts. 3148 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id); 3149 3150 // Check that we can send student1 a message because teacher has the messageanyuser cap by default. 3151 $this->assertTrue(api::can_send_message($student1->id, $teacher1->id)); 3152 3153 // Check that the teacher can't contact user1 because it's not his teacher. 3154 $this->assertFalse(api::can_send_message($user1->id, $teacher1->id)); 3155 3156 // Remove the messageanyuser capability from the course1 for teachers. 3157 $coursecontext = \context_course::instance($course1->id); 3158 $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']); 3159 assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id); 3160 $coursecontext->mark_dirty(); 3161 3162 // Check that we can't send user1 a message because they are not contacts. 3163 $this->assertFalse(api::can_send_message($student1->id, $teacher1->id)); 3164 3165 // However, teacher can message student2 because they are sharing a course. 3166 $this->assertTrue(api::can_send_message($student2->id, $teacher1->id)); 3167 } 3168 3169 /** 3170 * Tests the user when blocked will not be able to send messages if they are blocked. 3171 */ 3172 public function test_can_send_message_even_if_blocked() { 3173 $this->resetAfterTest(); 3174 3175 $user1 = self::getDataGenerator()->create_user(); 3176 $user2 = self::getDataGenerator()->create_user(); 3177 3178 $this->assertFalse(api::can_send_message($user2->id, $user1->id, true)); 3179 } 3180 3181 /** 3182 * Tests the user will be able to send a message even if they are blocked as the user 3183 * has the capability 'moodle/site:messageanyuser'. 3184 */ 3185 public function test_can_send_message_even_if_blocked_with_message_any_user_cap() { 3186 global $DB; 3187 3188 $this->resetAfterTest(); 3189 3190 $user1 = self::getDataGenerator()->create_user(); 3191 $user2 = self::getDataGenerator()->create_user(); 3192 3193 $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user')); 3194 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduserrole->id, \context_system::instance(), true); 3195 3196 $this->assertTrue(api::can_send_message($user2->id, $user1->id, true)); 3197 } 3198 3199 /** 3200 * Tests the user will be able to send a message even if they are blocked as the user 3201 * has the capability 'moodle/site:readallmessages'. 3202 */ 3203 public function test_can_send_message_even_if_blocked_with_read_all_message_cap() { 3204 global $DB; 3205 3206 $this->resetAfterTest(); 3207 3208 $user1 = self::getDataGenerator()->create_user(); 3209 $user2 = self::getDataGenerator()->create_user(); 3210 3211 $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user')); 3212 assign_capability('moodle/site:readallmessages', CAP_ALLOW, $authenticateduserrole->id, \context_system::instance(), true); 3213 3214 $this->assertTrue(api::can_send_message($user2->id, $user1->id, true)); 3215 } 3216 3217 /** 3218 * Tests the user can not always send a message if they are blocked just because they share a course. 3219 */ 3220 public function test_can_send_message_even_if_blocked_shared_course() { 3221 $this->resetAfterTest(); 3222 3223 // Create some users. 3224 $user1 = self::getDataGenerator()->create_user(); 3225 $user2 = self::getDataGenerator()->create_user(); 3226 3227 $course = self::getDataGenerator()->create_course(); 3228 3229 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3230 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3231 3232 $this->assertFalse(api::can_send_message($user2->id, $user1->id, true)); 3233 } 3234 3235 /** 3236 * Tests the user can always send a message even if they are blocked because they share a course and 3237 * have the capability 'moodle/site:messageanyuser' at the course context. 3238 */ 3239 public function test_can_send_message_even_if_blocked_shared_course_with_message_any_user_cap() { 3240 global $DB; 3241 3242 $this->resetAfterTest(); 3243 3244 $editingteacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 3245 3246 $teacher = self::getDataGenerator()->create_user(); 3247 $student = self::getDataGenerator()->create_user(); 3248 3249 $course = self::getDataGenerator()->create_course(); 3250 3251 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $editingteacherrole->id); 3252 $this->getDataGenerator()->enrol_user($student->id, $course->id); 3253 3254 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $editingteacherrole->id, 3255 \context_course::instance($course->id), true); 3256 3257 // Check that the second user can no longer send the first user a message. 3258 $this->assertTrue(api::can_send_message($student->id, $teacher->id, true)); 3259 } 3260 3261 /** 3262 * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings. 3263 */ 3264 public function test_can_send_message_to_conversation_basic() { 3265 // Create some users. 3266 $user1 = self::getDataGenerator()->create_user(); 3267 $user2 = self::getDataGenerator()->create_user(); 3268 $user3 = self::getDataGenerator()->create_user(); 3269 3270 // Create an individual conversation between user1 and user2. 3271 $ic1 = api::create_conversation( 3272 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3273 [ 3274 $user1->id, 3275 $user2->id 3276 ] 3277 ); 3278 3279 // Create a group conversation between and users 1, 2 and 3. 3280 $gc1 = api::create_conversation( 3281 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3282 [ 3283 $user1->id, 3284 $user2->id, 3285 $user3->id 3286 ] 3287 ); 3288 3289 // Get a self-conversation for user1. 3290 $sc1 = api::get_self_conversation($user1->id); 3291 3292 // For group conversations, there are no user privacy checks, so only membership in the conversation is needed. 3293 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3294 3295 // For self conversations, there are no user privacy checks, so only membership in the conversation is needed. 3296 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $sc1->id)); 3297 3298 // For individual conversations, the default privacy setting of 'only contacts and course members' applies. 3299 // Users are not in the same course, nor are they contacts, so messages cannot be sent. 3300 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3301 3302 // Enrol the users into the same course. 3303 $course = $this->getDataGenerator()->create_course(); 3304 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3305 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3306 3307 // After enrolling users to the course, they should be able to message them with the default privacy setting. 3308 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3309 } 3310 3311 /** 3312 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability. 3313 */ 3314 public function test_can_send_message_to_conversation_sendmessage_cap() { 3315 global $DB; 3316 3317 $user1 = self::getDataGenerator()->create_user(); 3318 $user2 = self::getDataGenerator()->create_user(); 3319 $user3 = self::getDataGenerator()->create_user(); 3320 3321 // Enrol the users into the same course. 3322 $course = $this->getDataGenerator()->create_course(); 3323 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3324 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3325 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3326 3327 // Create an individual conversation between user1 and user2. 3328 $ic1 = api::create_conversation( 3329 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3330 [ 3331 $user1->id, 3332 $user2->id 3333 ] 3334 ); 3335 3336 // Group conversation between and users 1, 2 and 3. 3337 $gc1 = api::create_conversation( 3338 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3339 [ 3340 $user1->id, 3341 $user2->id, 3342 $user3->id 3343 ] 3344 ); 3345 3346 // Default settings - user1 can send a message to both conversations. 3347 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3348 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3349 3350 // Remove the capability to send a message. 3351 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); 3352 unassign_capability('moodle/site:sendmessage', $roleids['user'], \context_system::instance()); 3353 3354 // Verify that a user cannot send a message to either an individual or a group conversation. 3355 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3356 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3357 } 3358 3359 /** 3360 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the messageanyuser capability. 3361 */ 3362 public function test_can_send_message_to_conversation_messageanyuser_cap() { 3363 global $DB; 3364 3365 $user1 = self::getDataGenerator()->create_user(); 3366 $user2 = self::getDataGenerator()->create_user(); 3367 $user3 = self::getDataGenerator()->create_user(); 3368 3369 // Enrol the users into the same course. 3370 $course = $this->getDataGenerator()->create_course(); 3371 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3372 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3373 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3374 3375 // Create an individual conversation between user1 and user2. 3376 $ic1 = api::create_conversation( 3377 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3378 [ 3379 $user1->id, 3380 $user2->id 3381 ] 3382 ); 3383 3384 // Group conversation between and users 1, 2 and 3. 3385 $gc1 = api::create_conversation( 3386 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3387 [ 3388 $user1->id, 3389 $user2->id, 3390 $user3->id 3391 ] 3392 ); 3393 3394 // Update the message preference for user2, so they can only be messaged by contacts. 3395 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3396 3397 // Verify that the user cannot be contacted in the individual conversation and that groups are unaffected. 3398 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3399 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3400 3401 // Assign the 'messageanyuser' capability to user1 at system context. 3402 $systemcontext = \context_system::instance(); 3403 $authenticateduser = $DB->get_record('role', ['shortname' => 'user']); 3404 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, $systemcontext->id); 3405 3406 // Check that user1 can now message user2 due to the capability, and that group conversations is again unaffected. 3407 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3408 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3409 } 3410 3411 /** 3412 * Test verifying that users cannot send messages to conversations they are not a part of. 3413 */ 3414 public function test_can_send_message_to_conversation_non_member() { 3415 // Create some users. 3416 $user1 = self::getDataGenerator()->create_user(); 3417 $user2 = self::getDataGenerator()->create_user(); 3418 $user3 = self::getDataGenerator()->create_user(); 3419 $user4 = self::getDataGenerator()->create_user(); 3420 3421 // Enrol the users into the same course. 3422 $course = $this->getDataGenerator()->create_course(); 3423 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3424 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3425 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3426 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 3427 3428 // Create an individual conversation between user1 and user2. 3429 $ic1 = api::create_conversation( 3430 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3431 [ 3432 $user1->id, 3433 $user2->id 3434 ] 3435 ); 3436 3437 // Create a group conversation between and users 1, 2 and 3. 3438 $gc1 = api::create_conversation( 3439 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3440 [ 3441 $user1->id, 3442 $user2->id, 3443 $user3->id 3444 ] 3445 ); 3446 3447 // Get a self-conversation for user1. 3448 $sc1 = api::get_self_conversation($user1->id); 3449 3450 // Verify, non members cannot send a message. 3451 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $gc1->id)); 3452 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $ic1->id)); 3453 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $sc1->id)); 3454 } 3455 3456 /** 3457 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts only. 3458 */ 3459 public function test_can_send_message_to_conversation_privacy_contacts_only() { 3460 // Create some users. 3461 $user1 = self::getDataGenerator()->create_user(); 3462 $user2 = self::getDataGenerator()->create_user(); 3463 $user3 = self::getDataGenerator()->create_user(); 3464 3465 // Create an individual conversation between user1 and user2. 3466 $ic1 = api::create_conversation( 3467 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3468 [ 3469 $user1->id, 3470 $user2->id 3471 ] 3472 ); 3473 3474 // Create a group conversation between and users 1, 2 and 3. 3475 $gc1 = api::create_conversation( 3476 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3477 [ 3478 $user1->id, 3479 $user2->id, 3480 $user3->id 3481 ] 3482 ); 3483 3484 // Set the message privacy preference to 'contacts only' for user 2. 3485 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3486 3487 // Verify that user1 cannot send a message to the individual conversation, but that the group conversation is unaffected. 3488 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3489 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3490 3491 // Now, simulate a contact request (and approval) between user1 and user2. 3492 api::create_contact_request($user1->id, $user2->id); 3493 api::confirm_contact_request($user1->id, $user2->id); 3494 3495 // Verify user1 can now message user2 again via their individual conversation. 3496 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3497 } 3498 3499 /** 3500 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts / course members. 3501 */ 3502 public function test_can_send_message_to_conversation_privacy_contacts_course() { 3503 // Create some users. 3504 $user1 = self::getDataGenerator()->create_user(); 3505 $user2 = self::getDataGenerator()->create_user(); 3506 $user3 = self::getDataGenerator()->create_user(); 3507 3508 // Set the message privacy preference to 'contacts + course members' for user 2. 3509 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id); 3510 3511 // Create an individual conversation between user1 and user2. 3512 $ic1 = api::create_conversation( 3513 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3514 [ 3515 $user1->id, 3516 $user2->id 3517 ] 3518 ); 3519 3520 // Create a group conversation between and users 1, 2 and 3. 3521 $gc1 = api::create_conversation( 3522 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3523 [ 3524 $user1->id, 3525 $user2->id, 3526 $user3->id 3527 ] 3528 ); 3529 3530 // Verify that users in a group conversation can message one another (i.e. privacy controls ignored). 3531 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3532 3533 // Verify that user1 can not message user2 unless they are either contacts, or share a course. 3534 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3535 3536 // Enrol the users into the same course. 3537 $course = $this->getDataGenerator()->create_course(); 3538 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3539 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3540 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3541 3542 // Verify that user1 can send a message to user2, based on the shared course, without being a contact. 3543 $this->assertFalse(api::is_contact($user1->id, $user2->id)); 3544 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3545 } 3546 3547 /** 3548 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to any user. 3549 */ 3550 public function test_can_send_message_to_conversation_privacy_sitewide() { 3551 // Create some users. 3552 $user1 = self::getDataGenerator()->create_user(); 3553 $user2 = self::getDataGenerator()->create_user(); 3554 $user3 = self::getDataGenerator()->create_user(); 3555 3556 // Create an individual conversation between user1 and user2. 3557 $ic1 = api::create_conversation( 3558 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3559 [ 3560 $user1->id, 3561 $user2->id 3562 ] 3563 ); 3564 3565 // Create a group conversation between and users 1, 2 and 3. 3566 $gc1 = api::create_conversation( 3567 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3568 [ 3569 $user1->id, 3570 $user2->id, 3571 $user3->id 3572 ] 3573 ); 3574 3575 // By default, the messaging privacy dictates that users can only be contacted by contacts, and members of their courses. 3576 // Verify also, that groups are not restricted in this way. 3577 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3578 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3579 3580 // Enable site-wide messagging privacy setting. 3581 // This enables a privacy option for users, allowing them to choose to be contactable by anybody on the site. 3582 set_config('messagingallusers', true); 3583 3584 // Set the second user's preference to receive messages from everybody. 3585 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user2->id); 3586 3587 // Check that user1 can send user2 a message, and that the group conversation is unaffected. 3588 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3589 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3590 3591 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts 3592 // and members sharing a course with her. 3593 set_config('messagingallusers', false); 3594 3595 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER. 3596 // Verify also that the group conversation is unaffected. 3597 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3598 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3599 } 3600 3601 /** 3602 * Test verifying the behaviour of the can_send_message_to_conversation method when a user is blocked. 3603 */ 3604 public function test_can_send_message_to_conversation_when_blocked() { 3605 $user1 = self::getDataGenerator()->create_user(); 3606 $user2 = self::getDataGenerator()->create_user(); 3607 $user3 = self::getDataGenerator()->create_user(); 3608 3609 // Create an individual conversation between user1 and user2. 3610 $ic1 = api::create_conversation( 3611 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3612 [ 3613 $user1->id, 3614 $user2->id 3615 ] 3616 ); 3617 3618 // Create a group conversation between and users 1, 2 and 3. 3619 $gc1 = api::create_conversation( 3620 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3621 [ 3622 $user1->id, 3623 $user2->id, 3624 $user3->id 3625 ] 3626 ); 3627 3628 // Enrol the users into the same course. 3629 $course = $this->getDataGenerator()->create_course(); 3630 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3631 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3632 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3633 3634 // Block the second user. 3635 api::block_user($user1->id, $user2->id); 3636 3637 // Check that user2 can not send user1 a message in their individual conversation. 3638 $this->assertFalse(api::can_send_message_to_conversation($user2->id, $ic1->id)); 3639 3640 // Verify that group conversations are unaffected. 3641 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3642 $this->assertTrue(api::can_send_message_to_conversation($user2->id, $gc1->id)); 3643 } 3644 3645 /** 3646 * Tests get_user_privacy_messaging_preference method. 3647 */ 3648 public function test_get_user_privacy_messaging_preference() { 3649 // Create some users. 3650 $user1 = self::getDataGenerator()->create_user(); 3651 $user2 = self::getDataGenerator()->create_user(); 3652 $user3 = self::getDataGenerator()->create_user(); 3653 3654 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody. 3655 set_config('messagingallusers', true); 3656 3657 // Set some user preferences. 3658 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user1->id); 3659 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3660 3661 // Check the returned value for each user. 3662 $this->assertEquals( 3663 api::MESSAGE_PRIVACY_SITE, 3664 api::get_user_privacy_messaging_preference($user1->id) 3665 ); 3666 $this->assertEquals( 3667 api::MESSAGE_PRIVACY_ONLYCONTACTS, 3668 api::get_user_privacy_messaging_preference($user2->id) 3669 ); 3670 $this->assertEquals( 3671 api::MESSAGE_PRIVACY_SITE, 3672 api::get_user_privacy_messaging_preference($user3->id) 3673 ); 3674 3675 // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course. 3676 set_config('messagingallusers', false); 3677 3678 // Check the returned value for each user. 3679 $this->assertEquals( 3680 api::MESSAGE_PRIVACY_COURSEMEMBER, 3681 api::get_user_privacy_messaging_preference($user1->id) 3682 ); 3683 $this->assertEquals( 3684 api::MESSAGE_PRIVACY_ONLYCONTACTS, 3685 api::get_user_privacy_messaging_preference($user2->id) 3686 ); 3687 $this->assertEquals( 3688 api::MESSAGE_PRIVACY_COURSEMEMBER, 3689 api::get_user_privacy_messaging_preference($user3->id) 3690 ); 3691 } 3692 3693 /* 3694 * Tes get_message_processor api. 3695 */ 3696 public function test_get_message_processor() { 3697 $processors = get_message_processors(true); 3698 if (empty($processors)) { 3699 $this->markTestSkipped("No message processors found"); 3700 } 3701 3702 $name = key($processors); 3703 $processor = current($processors); 3704 $testprocessor = api::get_message_processor($name); 3705 $this->assertEquals($processor->name, $testprocessor->name); 3706 $this->assertEquals($processor->enabled, $testprocessor->enabled); 3707 $this->assertEquals($processor->available, $testprocessor->available); 3708 $this->assertEquals($processor->configured, $testprocessor->configured); 3709 3710 // Disable processor and test. 3711 api::update_processor_status($testprocessor, 0); 3712 $testprocessor = api::get_message_processor($name, true); 3713 $this->assertEmpty($testprocessor); 3714 $testprocessor = api::get_message_processor($name); 3715 $this->assertEquals($processor->name, $testprocessor->name); 3716 $this->assertEquals(0, $testprocessor->enabled); 3717 3718 // Enable again and test. 3719 api::update_processor_status($testprocessor, 1); 3720 $testprocessor = api::get_message_processor($name, true); 3721 $this->assertEquals($processor->name, $testprocessor->name); 3722 $this->assertEquals(1, $testprocessor->enabled); 3723 $testprocessor = api::get_message_processor($name); 3724 $this->assertEquals($processor->name, $testprocessor->name); 3725 $this->assertEquals(1, $testprocessor->enabled); 3726 } 3727 3728 /** 3729 * Test method update_processor_status. 3730 */ 3731 public function test_update_processor_status() { 3732 $processors = get_message_processors(); 3733 if (empty($processors)) { 3734 $this->markTestSkipped("No message processors found"); 3735 } 3736 $name = key($processors); 3737 $testprocessor = current($processors); 3738 3739 // Enable. 3740 api::update_processor_status($testprocessor, 1); 3741 $testprocessor = api::get_message_processor($name); 3742 $this->assertEquals(1, $testprocessor->enabled); 3743 3744 // Disable. 3745 api::update_processor_status($testprocessor, 0); 3746 $testprocessor = api::get_message_processor($name); 3747 $this->assertEquals(0, $testprocessor->enabled); 3748 3749 // Enable again. 3750 api::update_processor_status($testprocessor, 1); 3751 $testprocessor = api::get_message_processor($name); 3752 $this->assertEquals(1, $testprocessor->enabled); 3753 } 3754 3755 /** 3756 * Test method is_user_enabled. 3757 */ 3758 public function is_user_enabled() { 3759 $processors = get_message_processors(); 3760 if (empty($processors)) { 3761 $this->markTestSkipped("No message processors found"); 3762 } 3763 $name = key($processors); 3764 $testprocessor = current($processors); 3765 3766 // Enable. 3767 api::update_processor_status($testprocessor, 1); 3768 $status = api::is_processor_enabled($name); 3769 $this->assertEquals(1, $status); 3770 3771 // Disable. 3772 api::update_processor_status($testprocessor, 0); 3773 $status = api::is_processor_enabled($name); 3774 $this->assertEquals(0, $status); 3775 3776 // Enable again. 3777 api::update_processor_status($testprocessor, 1); 3778 $status = api::is_processor_enabled($name); 3779 $this->assertEquals(1, $status); 3780 } 3781 3782 /** 3783 * Test returning blocked users. 3784 */ 3785 public function test_get_blocked_users() { 3786 global $USER; 3787 3788 // Set this user as the admin. 3789 $this->setAdminUser(); 3790 3791 // Create a user to add to the admin's contact list. 3792 $user1 = $this->getDataGenerator()->create_user(); 3793 $user2 = $this->getDataGenerator()->create_user(); 3794 3795 // Add users to the admin's contact list. 3796 api::block_user($USER->id, $user2->id); 3797 3798 $this->assertCount(1, api::get_blocked_users($USER->id)); 3799 3800 // Block other user. 3801 api::block_user($USER->id, $user1->id); 3802 $this->assertCount(2, api::get_blocked_users($USER->id)); 3803 3804 // Test deleting users. 3805 delete_user($user1); 3806 $this->assertCount(1, api::get_blocked_users($USER->id)); 3807 } 3808 3809 /** 3810 * Test returning contacts with unread message count. 3811 * MDL-69643 3812 */ 3813 public function test_get_contacts_with_unread_message_count() { 3814 global $DB; 3815 3816 $user1 = self::getDataGenerator()->create_user(); 3817 $user2 = self::getDataGenerator()->create_user(); 3818 $user3 = self::getDataGenerator()->create_user(); 3819 $user4 = self::getDataGenerator()->create_user(); 3820 3821 // Add the users to each of their contacts. 3822 api::add_contact($user1->id, $user2->id); 3823 api::add_contact($user2->id, $user3->id); 3824 3825 $this->send_fake_message($user1, $user2); 3826 $this->send_fake_message($user1, $user2); 3827 $this->send_fake_message($user1, $user2); 3828 $message4id = $this->send_fake_message($user1, $user2); 3829 3830 $this->send_fake_message($user3, $user2); 3831 $message6id = $this->send_fake_message($user3, $user2); 3832 $this->send_fake_message($user3, $user2); 3833 $this->send_fake_message($user3, $user2); 3834 $this->send_fake_message($user3, $user2); 3835 3836 // Send a message that should never be included as the user is not a contact. 3837 $this->send_fake_message($user4, $user2); 3838 3839 // Get the contacts and the unread message count. 3840 $messages = api::get_contacts_with_unread_message_count($user2->id); 3841 $this->assertDebuggingCalled(); 3842 3843 // Confirm the size is correct. 3844 $this->assertCount(2, $messages); 3845 ksort($messages); 3846 3847 $messageinfo1 = array_shift($messages); 3848 $messageinfo2 = array_shift($messages); 3849 3850 $this->assertEquals($user1->id, $messageinfo1->id); 3851 $this->assertEquals(4, $messageinfo1->messagecount); 3852 $this->assertEquals($user3->id, $messageinfo2->id); 3853 $this->assertEquals(5, $messageinfo2->messagecount); 3854 3855 // Mark some of the messages as read. 3856 $m4 = $DB->get_record('messages', ['id' => $message4id]); 3857 $m6 = $DB->get_record('messages', ['id' => $message6id]); 3858 api::mark_message_as_read($user2->id, $m4); 3859 api::mark_message_as_read($user2->id, $m6); 3860 3861 // Get the contacts and the unread message count. 3862 $messages = api::get_contacts_with_unread_message_count($user2->id); 3863 $this->assertDebuggingCalled(); 3864 3865 // Confirm the size is correct. 3866 $this->assertCount(2, $messages); 3867 ksort($messages); 3868 3869 // Confirm read messages are not included. 3870 $messageinfo1 = array_shift($messages); 3871 $messageinfo2 = array_shift($messages); 3872 $this->assertEquals($user1->id, $messageinfo1->id); 3873 $this->assertEquals(3, $messageinfo1->messagecount); 3874 $this->assertEquals($user3->id, $messageinfo2->id); 3875 $this->assertEquals(4, $messageinfo2->messagecount); 3876 3877 // Now, let's populate the database with messages from user2 to user 1. 3878 $this->send_fake_message($user2, $user1); 3879 $this->send_fake_message($user2, $user1); 3880 $messageid = $this->send_fake_message($user2, $user1); 3881 3882 // Send a message that should never be included as the user is not a contact. 3883 $this->send_fake_message($user4, $user1); 3884 3885 // Get the contacts and the unread message count. 3886 $messages = api::get_contacts_with_unread_message_count($user1->id); 3887 $this->assertDebuggingCalled(); 3888 3889 // Confirm the size is correct. 3890 $this->assertCount(1, $messages); 3891 $messageinfo1 = array_shift($messages); 3892 $this->assertEquals($user2->id, $messageinfo1->id); 3893 $this->assertEquals(3, $messageinfo1->messagecount); 3894 3895 // Mark the last message as read. 3896 $m = $DB->get_record('messages', ['id' => $messageid]); 3897 api::mark_message_as_read($user1->id, $m); 3898 3899 $messages = api::get_contacts_with_unread_message_count($user1->id); 3900 $this->assertDebuggingCalled(); 3901 3902 // Confirm the size is correct. 3903 $this->assertCount(1, $messages); 3904 3905 // Confirm read messages are not included. 3906 $messageinfo1 = array_shift($messages); 3907 $this->assertEquals($user2->id, $messageinfo1->id); 3908 $this->assertEquals(2, $messageinfo1->messagecount); 3909 } 3910 3911 /** 3912 * Test returning contacts with unread message count when there are no messages. 3913 */ 3914 public function test_get_contacts_with_unread_message_count_no_messages() { 3915 $user1 = self::getDataGenerator()->create_user(); 3916 $user2 = self::getDataGenerator()->create_user(); 3917 3918 // Add the users to each of their contacts. 3919 api::add_contact($user2->id, $user1->id); 3920 3921 // Check we get the correct message count. 3922 $messages = api::get_contacts_with_unread_message_count($user2->id); 3923 $this->assertDebuggingCalled(); 3924 3925 // Confirm the size is correct. 3926 $this->assertCount(1, $messages); 3927 3928 $messageinfo = array_shift($messages); 3929 3930 $this->assertEquals($user1->id, $messageinfo->id); 3931 $this->assertEquals(0, $messageinfo->messagecount); 3932 } 3933 3934 /** 3935 * Test returning non-contacts with unread message count. 3936 * MDL-69643 3937 */ 3938 public function test_get_non_contacts_with_unread_message_count() { 3939 global $DB; 3940 3941 $user1 = self::getDataGenerator()->create_user(); 3942 $user2 = self::getDataGenerator()->create_user(); 3943 $user3 = self::getDataGenerator()->create_user(); 3944 $user4 = self::getDataGenerator()->create_user(); 3945 3946 // Add a user to the contact list of the users we are testing this function with. 3947 api::add_contact($user1->id, $user4->id); 3948 api::add_contact($user2->id, $user4->id); 3949 3950 $this->send_fake_message($user1, $user2); 3951 $this->send_fake_message($user1, $user2); 3952 $this->send_fake_message($user1, $user2); 3953 $message4id = $this->send_fake_message($user1, $user2); 3954 3955 $this->send_fake_message($user3, $user2); 3956 $message6id = $this->send_fake_message($user3, $user2); 3957 $this->send_fake_message($user3, $user2); 3958 $this->send_fake_message($user3, $user2); 3959 $this->send_fake_message($user3, $user2); 3960 3961 // Send a message that should never be included as the user is a contact. 3962 $this->send_fake_message($user4, $user2); 3963 3964 3965 // Get the non-contacts and the unread message count. 3966 $messages = api::get_non_contacts_with_unread_message_count($user2->id); 3967 $this->assertDebuggingCalled(); 3968 3969 // Check we get the correct message count. 3970 ksort($messages); 3971 $this->assertCount(2, $messages); 3972 $messageinfo1 = array_shift($messages); 3973 $messageinfo2 = array_shift($messages); 3974 $this->assertEquals($user1->id, $messageinfo1->id); 3975 $this->assertEquals(4, $messageinfo1->messagecount); 3976 $this->assertEquals($user3->id, $messageinfo2->id); 3977 $this->assertEquals(5, $messageinfo2->messagecount); 3978 3979 // Mark some of the messages as read. 3980 $m4 = $DB->get_record('messages', ['id' => $message4id]); 3981 $m6 = $DB->get_record('messages', ['id' => $message6id]); 3982 api::mark_message_as_read($user2->id, $m4); 3983 api::mark_message_as_read($user2->id, $m6); 3984 3985 // Get the non-contacts and the unread message count. 3986 $messages = api::get_non_contacts_with_unread_message_count($user2->id); 3987 $this->assertDebuggingCalled(); 3988 3989 // Check the marked message is not returned in the message count. 3990 ksort($messages); 3991 $this->assertCount(2, $messages); 3992 $messageinfo1 = array_shift($messages); 3993 $messageinfo2 = array_shift($messages); 3994 $this->assertEquals($user1->id, $messageinfo1->id); 3995 $this->assertEquals(3, $messageinfo1->messagecount); 3996 $this->assertEquals($user3->id, $messageinfo2->id); 3997 $this->assertEquals(4, $messageinfo2->messagecount); 3998 3999 // Now, let's populate the database with messages from user2 to user 1. 4000 $this->send_fake_message($user2, $user1); 4001 $this->send_fake_message($user2, $user1); 4002 $messageid = $this->send_fake_message($user2, $user1); 4003 4004 // Send a message that should never be included as the user is a contact. 4005 $this->send_fake_message($user4, $user1); 4006 4007 // Get the non-contacts and the unread message count. 4008 $messages = api::get_non_contacts_with_unread_message_count($user1->id); 4009 $this->assertDebuggingCalled(); 4010 4011 // Confirm the size is correct. 4012 $this->assertCount(1, $messages); 4013 $messageinfo1 = array_shift($messages); 4014 $this->assertEquals($user2->id, $messageinfo1->id); 4015 $this->assertEquals(3, $messageinfo1->messagecount); 4016 4017 // Mark the last message as read. 4018 $m = $DB->get_record('messages', ['id' => $messageid]); 4019 api::mark_message_as_read($user1->id, $m); 4020 4021 // Get the non-contacts and the unread message count. 4022 $messages = api::get_non_contacts_with_unread_message_count($user1->id); 4023 $this->assertDebuggingCalled(); 4024 4025 // Check the marked message is not returned in the message count. 4026 $this->assertCount(1, $messages); 4027 $messageinfo1 = array_shift($messages); 4028 $this->assertEquals($user2->id, $messageinfo1->id); 4029 $this->assertEquals(2, $messageinfo1->messagecount); 4030 } 4031 4032 /** 4033 * Test marking a message as read. 4034 */ 4035 public function test_mark_message_as_read() { 4036 global $DB; 4037 4038 $user1 = self::getDataGenerator()->create_user(); 4039 $user2 = self::getDataGenerator()->create_user(); 4040 4041 $this->send_fake_message($user1, $user2); 4042 $m2id = $this->send_fake_message($user1, $user2); 4043 $this->send_fake_message($user2, $user1); 4044 $m4id = $this->send_fake_message($user2, $user1); 4045 4046 $m2 = $DB->get_record('messages', ['id' => $m2id]); 4047 $m4 = $DB->get_record('messages', ['id' => $m4id]); 4048 api::mark_message_as_read($user2->id, $m2, 11); 4049 api::mark_message_as_read($user1->id, $m4, 12); 4050 4051 // Confirm there are two user actions. 4052 $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC'); 4053 $this->assertEquals(2, count($muas)); 4054 4055 // Confirm they are correct. 4056 $mua1 = array_shift($muas); 4057 $mua2 = array_shift($muas); 4058 4059 // Confirm first action. 4060 $this->assertEquals($user2->id, $mua1->userid); 4061 $this->assertEquals($m2id, $mua1->messageid); 4062 $this->assertEquals(api::MESSAGE_ACTION_READ, $mua1->action); 4063 $this->assertEquals(11, $mua1->timecreated); 4064 4065 // Confirm second action. 4066 $this->assertEquals($user1->id, $mua2->userid); 4067 $this->assertEquals($m4id, $mua2->messageid); 4068 $this->assertEquals(api::MESSAGE_ACTION_READ, $mua2->action); 4069 $this->assertEquals(12, $mua2->timecreated); 4070 } 4071 4072 /** 4073 * Test marking a notification as read. 4074 */ 4075 public function test_mark_notification_as_read() { 4076 global $DB; 4077 4078 $user1 = self::getDataGenerator()->create_user(); 4079 $user2 = self::getDataGenerator()->create_user(); 4080 4081 $this->send_fake_message($user1, $user2, 'Notification 1', 1); 4082 $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1); 4083 $this->send_fake_message($user2, $user1, 'Notification 3', 1); 4084 $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1); 4085 4086 $n2 = $DB->get_record('notifications', ['id' => $n2id]); 4087 $n4 = $DB->get_record('notifications', ['id' => $n4id]); 4088 4089 api::mark_notification_as_read($n2, 11); 4090 api::mark_notification_as_read($n4, 12); 4091 4092 // Retrieve the notifications. 4093 $n2 = $DB->get_record('notifications', ['id' => $n2id]); 4094 $n4 = $DB->get_record('notifications', ['id' => $n4id]); 4095 4096 // Confirm they have been marked as read. 4097 $this->assertEquals(11, $n2->timeread); 4098 $this->assertEquals(12, $n4->timeread); 4099 } 4100 4101 /** 4102 * Test a conversation is not returned if there is none. 4103 */ 4104 public function test_get_conversation_between_users_no_conversation() { 4105 $user1 = self::getDataGenerator()->create_user(); 4106 $user2 = self::getDataGenerator()->create_user(); 4107 4108 $this->assertFalse(api::get_conversation_between_users([$user1->id, $user2->id])); 4109 } 4110 4111 /** 4112 * Test count_conversation_members for non existing conversation. 4113 */ 4114 public function test_count_conversation_members_no_existing_conversation() { 4115 $this->assertEquals(0, 4116 api::count_conversation_members(0)); 4117 } 4118 4119 /** 4120 * Test count_conversation_members for existing conversation. 4121 */ 4122 public function test_count_conversation_members_existing_conversation() { 4123 $user1 = self::getDataGenerator()->create_user(); 4124 $user2 = self::getDataGenerator()->create_user(); 4125 4126 $conversation = api::create_conversation( 4127 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4128 [ 4129 $user1->id, 4130 $user2->id 4131 ] 4132 ); 4133 $conversationid = $conversation->id; 4134 4135 $this->assertEquals(2, 4136 api::count_conversation_members($conversationid)); 4137 } 4138 4139 /** 4140 * Test add_members_to_conversation for an individual conversation. 4141 */ 4142 public function test_add_members_to_individual_conversation() { 4143 $user1 = self::getDataGenerator()->create_user(); 4144 $user2 = self::getDataGenerator()->create_user(); 4145 $user3 = self::getDataGenerator()->create_user(); 4146 4147 $conversation = api::create_conversation( 4148 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4149 [ 4150 $user1->id, 4151 $user2->id 4152 ] 4153 ); 4154 $conversationid = $conversation->id; 4155 4156 $this->expectException('moodle_exception'); 4157 api::add_members_to_conversation([$user3->id], $conversationid); 4158 } 4159 4160 /** 4161 * Test add_members_to_conversation for existing conversation. 4162 */ 4163 public function test_add_members_to_existing_conversation() { 4164 $user1 = self::getDataGenerator()->create_user(); 4165 $user2 = self::getDataGenerator()->create_user(); 4166 $user3 = self::getDataGenerator()->create_user(); 4167 4168 $conversation = api::create_conversation( 4169 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4170 [ 4171 $user1->id, 4172 $user2->id 4173 ] 4174 ); 4175 $conversationid = $conversation->id; 4176 4177 $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid)); 4178 $this->assertEquals(3, 4179 api::count_conversation_members($conversationid)); 4180 } 4181 4182 /** 4183 * Test add_members_to_conversation for non existing conversation. 4184 */ 4185 public function test_add_members_to_no_existing_conversation() { 4186 $user1 = self::getDataGenerator()->create_user(); 4187 4188 // Throw dml_missing_record_exception for non existing conversation. 4189 $this->expectException('dml_missing_record_exception'); 4190 api::add_members_to_conversation([$user1->id], 0); 4191 } 4192 4193 /** 4194 * Test add_member_to_conversation for non existing user. 4195 */ 4196 public function test_add_members_to_no_existing_user() { 4197 $user1 = self::getDataGenerator()->create_user(); 4198 $user2 = self::getDataGenerator()->create_user(); 4199 4200 $conversation = api::create_conversation( 4201 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4202 [ 4203 $user1->id, 4204 $user2->id 4205 ] 4206 ); 4207 $conversationid = $conversation->id; 4208 4209 // Don't throw an error for non existing user, but don't add it as a member. 4210 $this->assertNull(api::add_members_to_conversation([0], $conversationid)); 4211 $this->assertEquals(2, 4212 api::count_conversation_members($conversationid)); 4213 } 4214 4215 /** 4216 * Test add_members_to_conversation for current conversation member. 4217 */ 4218 public function test_add_members_to_current_conversation_member() { 4219 $user1 = self::getDataGenerator()->create_user(); 4220 $user2 = self::getDataGenerator()->create_user(); 4221 4222 $conversation = api::create_conversation( 4223 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4224 [ 4225 $user1->id, 4226 $user2->id 4227 ] 4228 ); 4229 $conversationid = $conversation->id; 4230 4231 // Don't add as a member a user that is already conversation member. 4232 $this->assertNull(api::add_members_to_conversation([$user1->id], $conversationid)); 4233 $this->assertEquals(2, 4234 api::count_conversation_members($conversationid)); 4235 } 4236 4237 /** 4238 * Test add_members_to_conversation for multiple users. 4239 */ 4240 public function test_add_members_for_multiple_users() { 4241 $user1 = self::getDataGenerator()->create_user(); 4242 $user2 = self::getDataGenerator()->create_user(); 4243 $user3 = self::getDataGenerator()->create_user(); 4244 $user4 = self::getDataGenerator()->create_user(); 4245 4246 $conversation = api::create_conversation( 4247 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4248 [ 4249 $user1->id, 4250 $user2->id 4251 ] 4252 ); 4253 $conversationid = $conversation->id; 4254 4255 $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid)); 4256 $this->assertEquals(4, 4257 api::count_conversation_members($conversationid)); 4258 } 4259 4260 /** 4261 * Test add_members_to_conversation for multiple users, included non existing and current conversation members 4262 */ 4263 public function test_add_members_for_multiple_not_valid_users() { 4264 $user1 = self::getDataGenerator()->create_user(); 4265 $user2 = self::getDataGenerator()->create_user(); 4266 $user3 = self::getDataGenerator()->create_user(); 4267 4268 $conversation = api::create_conversation( 4269 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4270 [ 4271 $user1->id, 4272 $user2->id 4273 ] 4274 ); 4275 $conversationid = $conversation->id; 4276 4277 // Don't throw errors, but don't add as members users don't exist or are already conversation members. 4278 $this->assertNull(api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid)); 4279 $this->assertEquals(3, 4280 api::count_conversation_members($conversationid)); 4281 } 4282 4283 /** 4284 * Test remove_members_from_conversation for individual conversation. 4285 */ 4286 public function test_remove_members_from_individual_conversation() { 4287 $user1 = self::getDataGenerator()->create_user(); 4288 $user2 = self::getDataGenerator()->create_user(); 4289 4290 $conversation = api::create_conversation( 4291 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4292 [ 4293 $user1->id, 4294 $user2->id 4295 ] 4296 ); 4297 $conversationid = $conversation->id; 4298 4299 $this->expectException('moodle_exception'); 4300 api::remove_members_from_conversation([$user1->id], $conversationid); 4301 } 4302 4303 /** 4304 * Test remove_members_from_conversation for existing conversation. 4305 */ 4306 public function test_remove_members_from_existing_conversation() { 4307 $user1 = self::getDataGenerator()->create_user(); 4308 $user2 = self::getDataGenerator()->create_user(); 4309 4310 $conversation = api::create_conversation( 4311 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4312 [ 4313 $user1->id, 4314 $user2->id 4315 ] 4316 ); 4317 $conversationid = $conversation->id; 4318 4319 $this->assertNull(api::remove_members_from_conversation([$user1->id], $conversationid)); 4320 $this->assertEquals(1, 4321 api::count_conversation_members($conversationid)); 4322 } 4323 4324 /** 4325 * Test remove_members_from_conversation for non existing conversation. 4326 */ 4327 public function test_remove_members_from_no_existing_conversation() { 4328 $user1 = self::getDataGenerator()->create_user(); 4329 4330 // Throw dml_missing_record_exception for non existing conversation. 4331 $this->expectException('dml_missing_record_exception'); 4332 api::remove_members_from_conversation([$user1->id], 0); 4333 } 4334 4335 /** 4336 * Test remove_members_from_conversation for non existing user. 4337 */ 4338 public function test_remove_members_for_no_existing_user() { 4339 $user1 = self::getDataGenerator()->create_user(); 4340 $user2 = self::getDataGenerator()->create_user(); 4341 4342 $conversation = api::create_conversation( 4343 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4344 [ 4345 $user1->id, 4346 $user2->id 4347 ] 4348 ); 4349 $conversationid = $conversation->id; 4350 4351 $this->assertNull(api::remove_members_from_conversation([0], $conversationid)); 4352 $this->assertEquals(2, 4353 api::count_conversation_members($conversationid)); 4354 } 4355 4356 /** 4357 * Test remove_members_from_conversation for multiple users. 4358 */ 4359 public function test_remove_members_for_multiple_users() { 4360 $user1 = self::getDataGenerator()->create_user(); 4361 $user2 = self::getDataGenerator()->create_user(); 4362 $user3 = self::getDataGenerator()->create_user(); 4363 $user4 = self::getDataGenerator()->create_user(); 4364 4365 $conversation = api::create_conversation( 4366 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4367 [ 4368 $user1->id, 4369 $user2->id 4370 ] 4371 ); 4372 $conversationid = $conversation->id; 4373 4374 $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid)); 4375 $this->assertNull(api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid)); 4376 $this->assertEquals(2, 4377 api::count_conversation_members($conversationid)); 4378 } 4379 4380 /** 4381 * Test remove_members_from_conversation for multiple non valid users. 4382 */ 4383 public function test_remove_members_for_multiple_no_valid_users() { 4384 $user1 = self::getDataGenerator()->create_user(); 4385 $user2 = self::getDataGenerator()->create_user(); 4386 $user3 = self::getDataGenerator()->create_user(); 4387 $user4 = self::getDataGenerator()->create_user(); 4388 4389 $conversation = api::create_conversation( 4390 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4391 [ 4392 $user1->id, 4393 $user2->id 4394 ] 4395 ); 4396 $conversationid = $conversation->id; 4397 4398 $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid)); 4399 $this->assertNull( 4400 api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid) 4401 ); 4402 $this->assertEquals(1, 4403 api::count_conversation_members($conversationid)); 4404 } 4405 4406 /** 4407 * Test count_conversation_members for empty conversation. 4408 */ 4409 public function test_count_conversation_members_empty_conversation() { 4410 $user1 = self::getDataGenerator()->create_user(); 4411 $user2 = self::getDataGenerator()->create_user(); 4412 4413 $conversation = api::create_conversation( 4414 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4415 [ 4416 $user1->id, 4417 $user2->id 4418 ] 4419 ); 4420 $conversationid = $conversation->id; 4421 4422 $this->assertNull(api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid)); 4423 4424 $this->assertEquals(0, 4425 api::count_conversation_members($conversationid)); 4426 } 4427 4428 /** 4429 * Test can create a contact request. 4430 */ 4431 public function test_can_create_contact_request() { 4432 global $CFG; 4433 4434 $user1 = self::getDataGenerator()->create_user(); 4435 $user2 = self::getDataGenerator()->create_user(); 4436 4437 // Disable messaging. 4438 $CFG->messaging = 0; 4439 $this->assertFalse(api::can_create_contact($user1->id, $user2->id)); 4440 4441 // Re-enable messaging. 4442 $CFG->messaging = 1; 4443 4444 // Allow users to message anyone site-wide. 4445 $CFG->messagingallusers = 1; 4446 $this->assertTrue(api::can_create_contact($user1->id, $user2->id)); 4447 4448 // Disallow users from messaging anyone site-wide. 4449 $CFG->messagingallusers = 0; 4450 $this->assertFalse(api::can_create_contact($user1->id, $user2->id)); 4451 4452 // Put the users in the same course so a contact request should be possible. 4453 $course = self::getDataGenerator()->create_course(); 4454 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 4455 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 4456 $this->assertTrue(api::can_create_contact($user1->id, $user2->id)); 4457 } 4458 4459 /** 4460 * Test creating a contact request. 4461 */ 4462 public function test_create_contact_request() { 4463 global $DB; 4464 4465 $user1 = self::getDataGenerator()->create_user(); 4466 $user2 = self::getDataGenerator()->create_user(); 4467 4468 $sink = $this->redirectMessages(); 4469 $request = api::create_contact_request($user1->id, $user2->id); 4470 $messages = $sink->get_messages(); 4471 $sink->close(); 4472 // Test customdata. 4473 $customdata = json_decode($messages[0]->customdata); 4474 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 4475 $this->assertObjectHasAttribute('actionbuttons', $customdata); 4476 $this->assertCount(2, (array) $customdata->actionbuttons); 4477 4478 $this->assertEquals($user1->id, $request->userid); 4479 $this->assertEquals($user2->id, $request->requesteduserid); 4480 } 4481 4482 /** 4483 * Test confirming a contact request. 4484 */ 4485 public function test_confirm_contact_request() { 4486 global $DB; 4487 4488 $user1 = self::getDataGenerator()->create_user(); 4489 $user2 = self::getDataGenerator()->create_user(); 4490 4491 api::create_contact_request($user1->id, $user2->id); 4492 4493 api::confirm_contact_request($user1->id, $user2->id); 4494 4495 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 4496 4497 $contact = $DB->get_records('message_contacts'); 4498 4499 $this->assertCount(1, $contact); 4500 4501 $contact = reset($contact); 4502 4503 $this->assertEquals($user1->id, $contact->userid); 4504 $this->assertEquals($user2->id, $contact->contactid); 4505 } 4506 4507 /** 4508 * Test declining a contact request. 4509 */ 4510 public function test_decline_contact_request() { 4511 global $DB; 4512 4513 $user1 = self::getDataGenerator()->create_user(); 4514 $user2 = self::getDataGenerator()->create_user(); 4515 4516 api::create_contact_request($user1->id, $user2->id); 4517 4518 api::decline_contact_request($user1->id, $user2->id); 4519 4520 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 4521 $this->assertEquals(0, $DB->count_records('message_contacts')); 4522 } 4523 4524 /** 4525 * Test retrieving contact requests. 4526 */ 4527 public function test_get_contact_requests() { 4528 global $PAGE; 4529 4530 $user1 = self::getDataGenerator()->create_user(); 4531 $user2 = self::getDataGenerator()->create_user(); 4532 $user3 = self::getDataGenerator()->create_user(); 4533 4534 // Block one user, their request should not show up. 4535 api::block_user($user1->id, $user3->id); 4536 4537 api::create_contact_request($user2->id, $user1->id); 4538 api::create_contact_request($user3->id, $user1->id); 4539 4540 $requests = api::get_contact_requests($user1->id); 4541 4542 $this->assertCount(1, $requests); 4543 4544 $request = reset($requests); 4545 $userpicture = new \user_picture($user2); 4546 $profileimageurl = $userpicture->get_url($PAGE)->out(false); 4547 4548 $this->assertEquals($user2->id, $request->id); 4549 $this->assertEquals(fullname($user2), $request->fullname); 4550 $this->assertObjectHasAttribute('profileimageurl', $request); 4551 $this->assertObjectHasAttribute('profileimageurlsmall', $request); 4552 $this->assertObjectHasAttribute('isonline', $request); 4553 $this->assertObjectHasAttribute('showonlinestatus', $request); 4554 $this->assertObjectHasAttribute('isblocked', $request); 4555 $this->assertObjectHasAttribute('iscontact', $request); 4556 } 4557 4558 /** 4559 * Test the get_contact_requests() function when the user has blocked the sender of the request. 4560 */ 4561 public function test_get_contact_requests_blocked_sender() { 4562 $user1 = self::getDataGenerator()->create_user(); 4563 $user2 = self::getDataGenerator()->create_user(); 4564 4565 // User1 blocks User2. 4566 api::block_user($user1->id, $user2->id); 4567 4568 // User2 tries to add User1 as a contact. 4569 api::create_contact_request($user2->id, $user1->id); 4570 4571 // Verify we don't see the contact request from the blocked user User2 in the requests for User1. 4572 $requests = api::get_contact_requests($user1->id); 4573 $this->assertEmpty($requests); 4574 } 4575 4576 /** 4577 * Test getting contact requests when there are none. 4578 */ 4579 public function test_get_contact_requests_no_requests() { 4580 $this->resetAfterTest(); 4581 4582 $user1 = self::getDataGenerator()->create_user(); 4583 4584 $requests = api::get_contact_requests($user1->id); 4585 4586 $this->assertEmpty($requests); 4587 } 4588 4589 /** 4590 * Test getting contact requests with limits. 4591 */ 4592 public function test_get_contact_requests_with_limits() { 4593 $this->resetAfterTest(); 4594 4595 $user1 = self::getDataGenerator()->create_user(); 4596 $user2 = self::getDataGenerator()->create_user(); 4597 $user3 = self::getDataGenerator()->create_user(); 4598 4599 api::create_contact_request($user2->id, $user1->id); 4600 api::create_contact_request($user3->id, $user1->id); 4601 4602 $requests = api::get_contact_requests($user1->id, 0, 1); 4603 4604 $this->assertCount(1, $requests); 4605 } 4606 4607 /** 4608 * Test adding contacts. 4609 */ 4610 public function test_add_contact() { 4611 global $DB; 4612 4613 $user1 = self::getDataGenerator()->create_user(); 4614 $user2 = self::getDataGenerator()->create_user(); 4615 4616 api::add_contact($user1->id, $user2->id); 4617 4618 $contact = $DB->get_records('message_contacts'); 4619 4620 $this->assertCount(1, $contact); 4621 4622 $contact = reset($contact); 4623 4624 $this->assertEquals($user1->id, $contact->userid); 4625 $this->assertEquals($user2->id, $contact->contactid); 4626 } 4627 4628 /** 4629 * Test removing contacts. 4630 */ 4631 public function test_remove_contact() { 4632 global $DB; 4633 4634 $user1 = self::getDataGenerator()->create_user(); 4635 $user2 = self::getDataGenerator()->create_user(); 4636 4637 api::add_contact($user1->id, $user2->id); 4638 api::remove_contact($user1->id, $user2->id); 4639 4640 $this->assertEquals(0, $DB->count_records('message_contacts')); 4641 } 4642 4643 /** 4644 * Test blocking users. 4645 */ 4646 public function test_block_user() { 4647 global $DB; 4648 4649 $user1 = self::getDataGenerator()->create_user(); 4650 $user2 = self::getDataGenerator()->create_user(); 4651 4652 api::block_user($user1->id, $user2->id); 4653 4654 $blockedusers = $DB->get_records('message_users_blocked'); 4655 4656 $this->assertCount(1, $blockedusers); 4657 4658 $blockeduser = reset($blockedusers); 4659 4660 $this->assertEquals($user1->id, $blockeduser->userid); 4661 $this->assertEquals($user2->id, $blockeduser->blockeduserid); 4662 } 4663 4664 /** 4665 * Test unblocking users. 4666 */ 4667 public function test_unblock_user() { 4668 global $DB; 4669 4670 $user1 = self::getDataGenerator()->create_user(); 4671 $user2 = self::getDataGenerator()->create_user(); 4672 4673 api::block_user($user1->id, $user2->id); 4674 api::unblock_user($user1->id, $user2->id); 4675 4676 $this->assertEquals(0, $DB->count_records('message_users_blocked')); 4677 } 4678 4679 /** 4680 * Test muting a conversation. 4681 */ 4682 public function test_mute_conversation() { 4683 global $DB; 4684 4685 $user1 = self::getDataGenerator()->create_user(); 4686 $user2 = self::getDataGenerator()->create_user(); 4687 4688 $conversation = api::create_conversation( 4689 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4690 [ 4691 $user1->id, 4692 $user2->id 4693 ] 4694 ); 4695 $conversationid = $conversation->id; 4696 4697 api::mute_conversation($user1->id, $conversationid); 4698 4699 $mutedconversation = $DB->get_records('message_conversation_actions'); 4700 4701 $this->assertCount(1, $mutedconversation); 4702 4703 $mutedconversation = reset($mutedconversation); 4704 4705 $this->assertEquals($user1->id, $mutedconversation->userid); 4706 $this->assertEquals($conversationid, $mutedconversation->conversationid); 4707 $this->assertEquals(api::CONVERSATION_ACTION_MUTED, $mutedconversation->action); 4708 } 4709 4710 /** 4711 * Test unmuting a conversation. 4712 */ 4713 public function test_unmute_conversation() { 4714 global $DB; 4715 4716 $user1 = self::getDataGenerator()->create_user(); 4717 $user2 = self::getDataGenerator()->create_user(); 4718 4719 $conversation = api::create_conversation( 4720 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4721 [ 4722 $user1->id, 4723 $user2->id 4724 ] 4725 ); 4726 $conversationid = $conversation->id; 4727 4728 api::mute_conversation($user1->id, $conversationid); 4729 api::unmute_conversation($user1->id, $conversationid); 4730 4731 $this->assertEquals(0, $DB->count_records('message_conversation_actions')); 4732 } 4733 4734 /** 4735 * Test if a conversation is muted. 4736 */ 4737 public function test_is_conversation_muted() { 4738 $user1 = self::getDataGenerator()->create_user(); 4739 $user2 = self::getDataGenerator()->create_user(); 4740 4741 $conversation = api::create_conversation( 4742 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4743 [ 4744 $user1->id, 4745 $user2->id 4746 ] 4747 ); 4748 $conversationid = $conversation->id; 4749 4750 $this->assertFalse(api::is_conversation_muted($user1->id, $conversationid)); 4751 4752 api::mute_conversation($user1->id, $conversationid); 4753 4754 $this->assertTrue(api::is_conversation_muted($user1->id, $conversationid)); 4755 } 4756 4757 /** 4758 * Test is contact check. 4759 */ 4760 public function test_is_contact() { 4761 $user1 = self::getDataGenerator()->create_user(); 4762 $user2 = self::getDataGenerator()->create_user(); 4763 $user3 = self::getDataGenerator()->create_user(); 4764 4765 api::add_contact($user1->id, $user2->id); 4766 4767 $this->assertTrue(api::is_contact($user1->id, $user2->id)); 4768 $this->assertTrue(api::is_contact($user2->id, $user1->id)); 4769 $this->assertFalse(api::is_contact($user2->id, $user3->id)); 4770 } 4771 4772 /** 4773 * Test get contact. 4774 */ 4775 public function test_get_contact() { 4776 $user1 = self::getDataGenerator()->create_user(); 4777 $user2 = self::getDataGenerator()->create_user(); 4778 4779 api::add_contact($user1->id, $user2->id); 4780 4781 $contact = api::get_contact($user1->id, $user2->id); 4782 4783 $this->assertEquals($user1->id, $contact->userid); 4784 $this->assertEquals($user2->id, $contact->contactid); 4785 } 4786 4787 /** 4788 * Test is blocked checked. 4789 */ 4790 public function test_is_blocked() { 4791 $user1 = self::getDataGenerator()->create_user(); 4792 $user2 = self::getDataGenerator()->create_user(); 4793 4794 $this->assertFalse(api::is_blocked($user1->id, $user2->id)); 4795 $this->assertFalse(api::is_blocked($user2->id, $user1->id)); 4796 4797 api::block_user($user1->id, $user2->id); 4798 4799 $this->assertTrue(api::is_blocked($user1->id, $user2->id)); 4800 $this->assertFalse(api::is_blocked($user2->id, $user1->id)); 4801 } 4802 4803 /** 4804 * Test the contact request exist check. 4805 */ 4806 public function test_does_contact_request_exist() { 4807 $user1 = self::getDataGenerator()->create_user(); 4808 $user2 = self::getDataGenerator()->create_user(); 4809 4810 $this->assertFalse(api::does_contact_request_exist($user1->id, $user2->id)); 4811 $this->assertFalse(api::does_contact_request_exist($user2->id, $user1->id)); 4812 4813 api::create_contact_request($user1->id, $user2->id); 4814 4815 $this->assertTrue(api::does_contact_request_exist($user1->id, $user2->id)); 4816 $this->assertTrue(api::does_contact_request_exist($user2->id, $user1->id)); 4817 } 4818 4819 /** 4820 * Test the get_received_contact_requests_count() function. 4821 */ 4822 public function test_get_received_contact_requests_count() { 4823 $user1 = self::getDataGenerator()->create_user(); 4824 $user2 = self::getDataGenerator()->create_user(); 4825 $user3 = self::getDataGenerator()->create_user(); 4826 $user4 = self::getDataGenerator()->create_user(); 4827 4828 $this->assertEquals(0, api::get_received_contact_requests_count($user1->id)); 4829 4830 api::create_contact_request($user2->id, $user1->id); 4831 4832 $this->assertEquals(1, api::get_received_contact_requests_count($user1->id)); 4833 4834 api::create_contact_request($user3->id, $user1->id); 4835 4836 $this->assertEquals(2, api::get_received_contact_requests_count($user1->id)); 4837 4838 api::create_contact_request($user1->id, $user4->id); 4839 // Function should ignore sent requests. 4840 $this->assertEquals(2, api::get_received_contact_requests_count($user1->id)); 4841 } 4842 4843 /** 4844 * Test the get_received_contact_requests_count() function when the user has blocked the sender of the request. 4845 */ 4846 public function test_get_received_contact_requests_count_blocked_sender() { 4847 $user1 = self::getDataGenerator()->create_user(); 4848 $user2 = self::getDataGenerator()->create_user(); 4849 4850 // User1 blocks User2. 4851 api::block_user($user1->id, $user2->id); 4852 4853 // User2 tries to add User1 as a contact. 4854 api::create_contact_request($user2->id, $user1->id); 4855 4856 // Verify we don't see the contact request from the blocked user User2 in the count for User1. 4857 $this->assertEquals(0, api::get_received_contact_requests_count($user1->id)); 4858 } 4859 4860 /** 4861 * Test the get_contact_requests_between_users() function. 4862 */ 4863 public function test_get_contact_requests_between_users() { 4864 $user1 = self::getDataGenerator()->create_user(); 4865 $user2 = self::getDataGenerator()->create_user(); 4866 $user3 = self::getDataGenerator()->create_user(); 4867 $user4 = self::getDataGenerator()->create_user(); 4868 4869 $this->assertEquals([], api::get_contact_requests_between_users($user1->id, $user2->id)); 4870 4871 $request1 = api::create_contact_request($user2->id, $user1->id); 4872 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4873 $results = array_values($results); 4874 4875 $this->assertCount(1, $results); 4876 $result = $results[0]; 4877 $this->assertEquals($request1->id, $result->id); 4878 4879 $request2 = api::create_contact_request($user1->id, $user2->id); 4880 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4881 $results = array_values($results); 4882 4883 $this->assertCount(2, $results); 4884 $actual = [(int) $results[0]->id, (int) $results[1]->id]; 4885 $expected = [(int) $request1->id, (int) $request2->id]; 4886 4887 sort($actual); 4888 sort($expected); 4889 4890 $this->assertEquals($expected, $actual); 4891 4892 // Request from a different user. 4893 api::create_contact_request($user3->id, $user1->id); 4894 4895 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4896 $results = array_values($results); 4897 4898 $this->assertCount(2, $results); 4899 $actual = [(int) $results[0]->id, (int) $results[1]->id]; 4900 $expected = [(int) $request1->id, (int) $request2->id]; 4901 4902 sort($actual); 4903 sort($expected); 4904 4905 $this->assertEquals($expected, $actual); 4906 } 4907 4908 /** 4909 * Test the user in conversation check. 4910 */ 4911 public function test_is_user_in_conversation() { 4912 $user1 = self::getDataGenerator()->create_user(); 4913 $user2 = self::getDataGenerator()->create_user(); 4914 4915 $conversation = api::create_conversation( 4916 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4917 [ 4918 $user1->id, 4919 $user2->id 4920 ] 4921 ); 4922 $conversationid = $conversation->id; 4923 4924 $this->assertTrue(api::is_user_in_conversation($user1->id, $conversationid)); 4925 } 4926 4927 /** 4928 * Test the user in conversation check when they are not. 4929 */ 4930 public function test_is_user_in_conversation_when_not() { 4931 $user1 = self::getDataGenerator()->create_user(); 4932 $user2 = self::getDataGenerator()->create_user(); 4933 $user3 = self::getDataGenerator()->create_user(); 4934 4935 $conversation = api::create_conversation( 4936 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4937 [ 4938 $user1->id, 4939 $user2->id 4940 ] 4941 ); 4942 $conversationid = $conversation->id; 4943 4944 $this->assertFalse(api::is_user_in_conversation($user3->id, $conversationid)); 4945 } 4946 4947 /** 4948 * Test can create a group conversation. 4949 */ 4950 public function test_can_create_group_conversation() { 4951 global $CFG; 4952 4953 $student = self::getDataGenerator()->create_user(); 4954 $teacher = self::getDataGenerator()->create_user(); 4955 $course = self::getDataGenerator()->create_course(); 4956 4957 $coursecontext = \context_course::instance($course->id); 4958 4959 $this->getDataGenerator()->enrol_user($student->id, $course->id); 4960 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher'); 4961 4962 // Disable messaging. 4963 $CFG->messaging = 0; 4964 $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext)); 4965 4966 // Re-enable messaging. 4967 $CFG->messaging = 1; 4968 4969 // Student shouldn't be able to. 4970 $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext)); 4971 4972 // Teacher should. 4973 $this->assertTrue(api::can_create_group_conversation($teacher->id, $coursecontext)); 4974 } 4975 4976 /** 4977 * Test creating an individual conversation. 4978 */ 4979 public function test_create_conversation_individual() { 4980 $user1 = self::getDataGenerator()->create_user(); 4981 $user2 = self::getDataGenerator()->create_user(); 4982 4983 $conversation = api::create_conversation( 4984 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4985 [ 4986 $user1->id, 4987 $user2->id 4988 ], 4989 'A conversation name' 4990 ); 4991 4992 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type); 4993 $this->assertEquals('A conversation name', $conversation->name); 4994 $this->assertEquals(helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash); 4995 4996 $this->assertCount(2, $conversation->members); 4997 4998 $member1 = array_shift($conversation->members); 4999 $member2 = array_shift($conversation->members); 5000 5001 $this->assertEquals($user1->id, $member1->userid); 5002 $this->assertEquals($conversation->id, $member1->conversationid); 5003 5004 $this->assertEquals($user2->id, $member2->userid); 5005 $this->assertEquals($conversation->id, $member2->conversationid); 5006 } 5007 5008 /** 5009 * Test creating a group conversation. 5010 */ 5011 public function test_create_conversation_group() { 5012 $user1 = self::getDataGenerator()->create_user(); 5013 $user2 = self::getDataGenerator()->create_user(); 5014 $user3 = self::getDataGenerator()->create_user(); 5015 5016 $conversation = api::create_conversation( 5017 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5018 [ 5019 $user1->id, 5020 $user2->id, 5021 $user3->id 5022 ], 5023 'A conversation name' 5024 ); 5025 5026 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type); 5027 $this->assertEquals('A conversation name', $conversation->name); 5028 $this->assertNull($conversation->convhash); 5029 5030 $this->assertCount(3, $conversation->members); 5031 5032 $member1 = array_shift($conversation->members); 5033 $member2 = array_shift($conversation->members); 5034 $member3 = array_shift($conversation->members); 5035 5036 $this->assertEquals($user1->id, $member1->userid); 5037 $this->assertEquals($conversation->id, $member1->conversationid); 5038 5039 $this->assertEquals($user2->id, $member2->userid); 5040 $this->assertEquals($conversation->id, $member2->conversationid); 5041 5042 $this->assertEquals($user3->id, $member3->userid); 5043 $this->assertEquals($conversation->id, $member3->conversationid); 5044 } 5045 5046 /** 5047 * Test creating an invalid conversation. 5048 */ 5049 public function test_create_conversation_invalid() { 5050 $this->expectException('moodle_exception'); 5051 api::create_conversation(3, [1, 2, 3]); 5052 } 5053 5054 /** 5055 * Test creating an individual conversation with too many members. 5056 */ 5057 public function test_create_conversation_individual_too_many_members() { 5058 $this->expectException('moodle_exception'); 5059 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]); 5060 } 5061 5062 /** 5063 * Test create message conversation with area. 5064 */ 5065 public function test_create_conversation_with_area() { 5066 $contextid = 111; 5067 $itemid = 222; 5068 $name = 'Name of conversation'; 5069 $conversation = api::create_conversation( 5070 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5071 [], 5072 $name, 5073 api::MESSAGE_CONVERSATION_DISABLED, 5074 'core_group', 5075 'groups', 5076 $itemid, 5077 $contextid 5078 ); 5079 5080 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5081 $this->assertEquals('core_group', $conversation->component); 5082 $this->assertEquals('groups', $conversation->itemtype); 5083 $this->assertEquals($itemid, $conversation->itemid); 5084 $this->assertEquals($contextid, $conversation->contextid); 5085 } 5086 5087 /** 5088 * Test get_conversation_by_area. 5089 */ 5090 public function test_get_conversation_by_area() { 5091 $contextid = 111; 5092 $itemid = 222; 5093 $name = 'Name of conversation'; 5094 $createconversation = api::create_conversation( 5095 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5096 [], 5097 $name, 5098 api::MESSAGE_CONVERSATION_DISABLED, 5099 'core_group', 5100 'groups', 5101 $itemid, 5102 $contextid 5103 ); 5104 $conversation = api::get_conversation_by_area('core_group', 'groups', $itemid, $contextid); 5105 5106 $this->assertEquals($createconversation->id, $conversation->id); 5107 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5108 $this->assertEquals('core_group', $conversation->component); 5109 $this->assertEquals('groups', $conversation->itemtype); 5110 $this->assertEquals($itemid, $conversation->itemid); 5111 $this->assertEquals($contextid, $conversation->contextid); 5112 } 5113 5114 /** 5115 * Test enable_conversation. 5116 */ 5117 public function test_enable_conversation() { 5118 global $DB; 5119 5120 $name = 'Name of conversation'; 5121 5122 $conversation = api::create_conversation( 5123 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5124 [], 5125 $name, 5126 api::MESSAGE_CONVERSATION_DISABLED 5127 ); 5128 5129 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5130 api::enable_conversation($conversation->id); 5131 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]); 5132 $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversationenabled); 5133 } 5134 5135 /** 5136 * Test disable_conversation. 5137 */ 5138 public function test_disable_conversation() { 5139 global $DB; 5140 5141 $name = 'Name of conversation'; 5142 5143 $conversation = api::create_conversation( 5144 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5145 [], 5146 $name, 5147 api::MESSAGE_CONVERSATION_ENABLED 5148 ); 5149 5150 $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversation->enabled); 5151 api::disable_conversation($conversation->id); 5152 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]); 5153 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversationenabled); 5154 } 5155 5156 /** 5157 * Test update_conversation_name. 5158 */ 5159 public function test_update_conversation_name() { 5160 global $DB; 5161 5162 $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, []); 5163 5164 $newname = 'New name of conversation'; 5165 api::update_conversation_name($conversation->id, $newname); 5166 5167 $this->assertEquals( 5168 $newname, 5169 $DB->get_field('message_conversations', 'name', ['id' => $conversation->id]) 5170 ); 5171 } 5172 5173 /** 5174 * Test returning members in a conversation with no contact requests. 5175 */ 5176 public function test_get_conversation_members() { 5177 $lastaccess = new \stdClass(); 5178 $lastaccess->lastaccess = time(); 5179 5180 $user1 = self::getDataGenerator()->create_user($lastaccess); 5181 $user2 = self::getDataGenerator()->create_user(); 5182 $user3 = self::getDataGenerator()->create_user(); 5183 5184 // This user will not be in the conversation, but a contact request will exist for them. 5185 $user4 = self::getDataGenerator()->create_user(); 5186 5187 // Add some contact requests. 5188 api::create_contact_request($user1->id, $user3->id); 5189 api::create_contact_request($user1->id, $user4->id); 5190 api::create_contact_request($user2->id, $user3->id); 5191 5192 // User 1 and 2 are already contacts. 5193 api::add_contact($user1->id, $user2->id); 5194 5195 // User 1 has blocked user 3. 5196 api::block_user($user1->id, $user3->id); 5197 $conversation = api::create_conversation( 5198 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5199 [ 5200 $user1->id, 5201 $user2->id, 5202 $user3->id 5203 ] 5204 ); 5205 $conversationid = $conversation->id; 5206 $members = api::get_conversation_members($user1->id, $conversationid, false); 5207 5208 // Sort them by id. 5209 ksort($members); 5210 $this->assertCount(3, $members); 5211 $member1 = array_shift($members); 5212 $member2 = array_shift($members); 5213 $member3 = array_shift($members); 5214 5215 // Confirm the standard fields are OK. 5216 $this->assertEquals($user1->id, $member1->id); 5217 $this->assertEquals(fullname($user1), $member1->fullname); 5218 $this->assertEquals(true, $member1->isonline); 5219 $this->assertEquals(true, $member1->showonlinestatus); 5220 $this->assertEquals(false, $member1->iscontact); 5221 $this->assertEquals(false, $member1->isblocked); 5222 $this->assertObjectHasAttribute('contactrequests', $member1); 5223 $this->assertEmpty($member1->contactrequests); 5224 5225 $this->assertEquals($user2->id, $member2->id); 5226 $this->assertEquals(fullname($user2), $member2->fullname); 5227 $this->assertEquals(false, $member2->isonline); 5228 $this->assertEquals(true, $member2->showonlinestatus); 5229 $this->assertEquals(true, $member2->iscontact); 5230 $this->assertEquals(false, $member2->isblocked); 5231 $this->assertObjectHasAttribute('contactrequests', $member2); 5232 $this->assertEmpty($member2->contactrequests); 5233 5234 $this->assertEquals($user3->id, $member3->id); 5235 $this->assertEquals(fullname($user3), $member3->fullname); 5236 $this->assertEquals(false, $member3->isonline); 5237 $this->assertEquals(true, $member3->showonlinestatus); 5238 $this->assertEquals(false, $member3->iscontact); 5239 $this->assertEquals(true, $member3->isblocked); 5240 $this->assertObjectHasAttribute('contactrequests', $member3); 5241 $this->assertEmpty($member3->contactrequests); 5242 } 5243 5244 /** 5245 * Test returning members in a conversation with contact requests. 5246 */ 5247 public function test_get_conversation_members_with_contact_requests() { 5248 $lastaccess = new \stdClass(); 5249 $lastaccess->lastaccess = time(); 5250 5251 $user1 = self::getDataGenerator()->create_user($lastaccess); 5252 $user2 = self::getDataGenerator()->create_user(); 5253 $user3 = self::getDataGenerator()->create_user(); 5254 5255 // This user will not be in the conversation, but a contact request will exist for them. 5256 $user4 = self::getDataGenerator()->create_user(); 5257 // Add some contact requests. 5258 api::create_contact_request($user1->id, $user2->id); 5259 api::create_contact_request($user1->id, $user3->id); 5260 api::create_contact_request($user1->id, $user4->id); 5261 api::create_contact_request($user2->id, $user3->id); 5262 5263 // User 1 and 2 are already contacts. 5264 api::add_contact($user1->id, $user2->id); 5265 // User 1 has blocked user 3. 5266 api::block_user($user1->id, $user3->id); 5267 5268 $conversation = api::create_conversation( 5269 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5270 [ 5271 $user1->id, 5272 $user2->id, 5273 $user3->id 5274 ] 5275 ); 5276 $conversationid = $conversation->id; 5277 5278 $members = api::get_conversation_members($user1->id, $conversationid, true); 5279 5280 // Sort them by id. 5281 ksort($members); 5282 5283 $this->assertCount(3, $members); 5284 5285 $member1 = array_shift($members); 5286 $member2 = array_shift($members); 5287 $member3 = array_shift($members); 5288 5289 // Confirm the standard fields are OK. 5290 $this->assertEquals($user1->id, $member1->id); 5291 $this->assertEquals(fullname($user1), $member1->fullname); 5292 $this->assertEquals(true, $member1->isonline); 5293 $this->assertEquals(true, $member1->showonlinestatus); 5294 $this->assertEquals(false, $member1->iscontact); 5295 $this->assertEquals(false, $member1->isblocked); 5296 $this->assertCount(2, $member1->contactrequests); 5297 5298 $this->assertEquals($user2->id, $member2->id); 5299 $this->assertEquals(fullname($user2), $member2->fullname); 5300 $this->assertEquals(false, $member2->isonline); 5301 $this->assertEquals(true, $member2->showonlinestatus); 5302 $this->assertEquals(true, $member2->iscontact); 5303 $this->assertEquals(false, $member2->isblocked); 5304 $this->assertCount(1, $member2->contactrequests); 5305 5306 $this->assertEquals($user3->id, $member3->id); 5307 $this->assertEquals(fullname($user3), $member3->fullname); 5308 $this->assertEquals(false, $member3->isonline); 5309 $this->assertEquals(true, $member3->showonlinestatus); 5310 $this->assertEquals(false, $member3->iscontact); 5311 $this->assertEquals(true, $member3->isblocked); 5312 $this->assertCount(1, $member3->contactrequests); 5313 5314 // Confirm the contact requests are OK. 5315 $request1 = array_shift($member1->contactrequests); 5316 $request2 = array_shift($member1->contactrequests); 5317 5318 $this->assertEquals($user1->id, $request1->userid); 5319 $this->assertEquals($user2->id, $request1->requesteduserid); 5320 5321 $this->assertEquals($user1->id, $request2->userid); 5322 $this->assertEquals($user3->id, $request2->requesteduserid); 5323 5324 $request1 = array_shift($member2->contactrequests); 5325 5326 $this->assertEquals($user1->id, $request1->userid); 5327 $this->assertEquals($user2->id, $request1->requesteduserid); 5328 5329 $request1 = array_shift($member3->contactrequests); 5330 5331 $this->assertEquals($user1->id, $request1->userid); 5332 $this->assertEquals($user3->id, $request1->requesteduserid); 5333 } 5334 5335 /** 5336 * Test returning members of a self conversation. 5337 */ 5338 public function test_get_conversation_members_with_self_conversation() { 5339 $lastaccess = new \stdClass(); 5340 $lastaccess->lastaccess = time(); 5341 5342 $user1 = self::getDataGenerator()->create_user($lastaccess); 5343 5344 $selfconversation = api::get_self_conversation($user1->id); 5345 testhelper::send_fake_message_to_conversation($user1, $selfconversation->id, 'This is a self-message!'); 5346 5347 // Get the members for the self-conversation. 5348 $members = api::get_conversation_members($user1->id, $selfconversation->id); 5349 $this->assertCount(1, $members); 5350 5351 $member1 = array_shift($members); 5352 5353 // Confirm the standard fields are OK. 5354 $this->assertEquals($user1->id, $member1->id); 5355 $this->assertEquals(fullname($user1), $member1->fullname); 5356 $this->assertEquals(true, $member1->isonline); 5357 $this->assertEquals(true, $member1->showonlinestatus); 5358 $this->assertEquals(false, $member1->iscontact); 5359 $this->assertEquals(false, $member1->isblocked); 5360 } 5361 5362 /** 5363 * Test verifying that messages can be sent to existing individual conversations. 5364 */ 5365 public function test_send_message_to_conversation_individual_conversation() { 5366 // Get a bunch of conversations, some group, some individual and in different states. 5367 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5368 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5369 5370 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5371 $course = $this->getDataGenerator()->create_course(); 5372 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5373 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5374 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5375 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5376 5377 // Redirect messages. 5378 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5379 // based on the message_viewed events generated as part of marking the message as read for each user. 5380 $this->preventResetByRollback(); 5381 $sink = $this->redirectMessages(); 5382 5383 // Send a message to an individual conversation. 5384 $sink = $this->redirectEvents(); 5385 $messagessink = $this->redirectMessages(); 5386 $message1 = api::send_message_to_conversation($user1->id, $ic1->id, 'this is a message', FORMAT_MOODLE); 5387 $events = $sink->get_events(); 5388 $messages = $messagessink->get_messages(); 5389 // Test customdata. 5390 $customdata = json_decode($messages[0]->customdata); 5391 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 5392 $this->assertObjectHasAttribute('actionbuttons', $customdata); 5393 $this->assertCount(1, (array) $customdata->actionbuttons); 5394 $this->assertObjectHasAttribute('placeholders', $customdata); 5395 $this->assertCount(1, (array) $customdata->placeholders); 5396 5397 // Verify the message returned. 5398 $this->assertInstanceOf(\stdClass::class, $message1); 5399 $this->assertObjectHasAttribute('id', $message1); 5400 $this->assertEquals($user1->id, $message1->useridfrom); 5401 $this->assertEquals('this is a message', $message1->text); 5402 $this->assertObjectHasAttribute('timecreated', $message1); 5403 5404 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(), 5405 // however, we can still determine the number and ids of any recipients this way. 5406 $this->assertCount(1, $events); 5407 $userids = array_column($events, 'userid'); 5408 $this->assertNotContainsEquals($user1->id, $userids); 5409 $this->assertContainsEquals($user2->id, $userids); 5410 } 5411 5412 /** 5413 * Test verifying that messages can be sent to existing group conversations. 5414 */ 5415 public function test_send_message_to_conversation_group_conversation() { 5416 // Get a bunch of conversations, some group, some individual and in different states. 5417 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5418 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5419 5420 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5421 $course = $this->getDataGenerator()->create_course(); 5422 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5423 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5424 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5425 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5426 5427 // Redirect messages. 5428 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5429 // based on the message_viewed events generated as part of marking the message as read for each user. 5430 $this->preventResetByRollback(); 5431 $sink = $this->redirectMessages(); 5432 5433 // Send a message to a group conversation. 5434 $sink = $this->redirectEvents(); 5435 $messagessink = $this->redirectMessages(); 5436 $message1 = api::send_message_to_conversation($user1->id, $gc2->id, 'message to the group', FORMAT_MOODLE); 5437 $events = $sink->get_events(); 5438 $messages = $messagessink->get_messages(); 5439 // Verify the message returned. 5440 $this->assertInstanceOf(\stdClass::class, $message1); 5441 $this->assertObjectHasAttribute('id', $message1); 5442 $this->assertEquals($user1->id, $message1->useridfrom); 5443 $this->assertEquals('message to the group', $message1->text); 5444 $this->assertObjectHasAttribute('timecreated', $message1); 5445 // Test customdata. 5446 $customdata = json_decode($messages[0]->customdata); 5447 $this->assertObjectHasAttribute('actionbuttons', $customdata); 5448 $this->assertCount(1, (array) $customdata->actionbuttons); 5449 $this->assertObjectHasAttribute('placeholders', $customdata); 5450 $this->assertCount(1, (array) $customdata->placeholders); 5451 $this->assertObjectNotHasAttribute('notificationiconurl', $customdata); // No group image means no image. 5452 5453 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(), 5454 // however, we can still determine the number and ids of any recipients this way. 5455 $this->assertCount(2, $events); 5456 $userids = array_column($events, 'userid'); 5457 $this->assertNotContainsEquals($user1->id, $userids); 5458 $this->assertContainsEquals($user3->id, $userids); 5459 $this->assertContainsEquals($user4->id, $userids); 5460 } 5461 5462 /** 5463 * Test verifying that messages can be sent to existing linked group conversations. 5464 */ 5465 public function test_send_message_to_conversation_linked_group_conversation() { 5466 global $CFG, $PAGE; 5467 5468 // Create some users. 5469 $user1 = self::getDataGenerator()->create_user(); 5470 $user2 = self::getDataGenerator()->create_user(); 5471 $user3 = self::getDataGenerator()->create_user(); 5472 5473 $course = $this->getDataGenerator()->create_course(); 5474 5475 // Create a group with a linked conversation and a valid image. 5476 $this->setAdminUser(); 5477 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5478 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5479 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5480 $group = $this->getDataGenerator()->create_group([ 5481 'courseid' => $course->id, 5482 'enablemessaging' => 1, 5483 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' 5484 ]); 5485 5486 // Add users to group. 5487 $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user1->id)); 5488 $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user2->id)); 5489 5490 // Verify the group with the image works as expected. 5491 $conversations = api::get_conversations($user1->id); 5492 $this->assertEquals(2, $conversations[0]->membercount); 5493 $this->assertEquals($course->shortname, $conversations[0]->subname); 5494 $groupimageurl = get_group_picture_url($group, $group->courseid, true); 5495 $this->assertEquals($groupimageurl, $conversations[0]->imageurl); 5496 5497 // Redirect messages. 5498 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5499 // based on the message_viewed events generated as part of marking the message as read for each user. 5500 $this->preventResetByRollback(); 5501 $sink = $this->redirectMessages(); 5502 5503 // Send a message to a group conversation. 5504 $messagessink = $this->redirectMessages(); 5505 $message1 = api::send_message_to_conversation($user1->id, $conversations[0]->id, 5506 'message to the group', FORMAT_MOODLE); 5507 $messages = $messagessink->get_messages(); 5508 // Verify the message returned. 5509 $this->assertInstanceOf(\stdClass::class, $message1); 5510 $this->assertObjectHasAttribute('id', $message1); 5511 $this->assertEquals($user1->id, $message1->useridfrom); 5512 $this->assertEquals('message to the group', $message1->text); 5513 $this->assertObjectHasAttribute('timecreated', $message1); 5514 // Test customdata. 5515 $customdata = json_decode($messages[0]->customdata); 5516 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 5517 $this->assertObjectHasAttribute('notificationsendericonurl', $customdata); 5518 $this->assertEquals($groupimageurl, $customdata->notificationiconurl); 5519 $this->assertEquals($group->name, $customdata->conversationname); 5520 $userpicture = new \user_picture($user1); 5521 $userpicture->size = 1; // Use f1 size. 5522 $this->assertEquals($userpicture->get_url($PAGE)->out(false), $customdata->notificationsendericonurl); 5523 } 5524 5525 /** 5526 * Test verifying that messages cannot be sent to conversations that don't exist. 5527 */ 5528 public function test_send_message_to_conversation_non_existent_conversation() { 5529 // Get a bunch of conversations, some group, some individual and in different states. 5530 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5531 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5532 5533 $this->expectException(\moodle_exception::class); 5534 api::send_message_to_conversation($user1->id, 0, 'test', FORMAT_MOODLE); 5535 } 5536 5537 /** 5538 * Test verifying that messages cannot be sent to conversations by users who are not members. 5539 */ 5540 public function test_send_message_to_conversation_non_member() { 5541 // Get a bunch of conversations, some group, some individual and in different states. 5542 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5543 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5544 5545 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5546 $course = $this->getDataGenerator()->create_course(); 5547 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5548 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5549 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5550 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5551 5552 $this->expectException(\moodle_exception::class); 5553 api::send_message_to_conversation($user3->id, $ic1->id, 'test', FORMAT_MOODLE); 5554 } 5555 5556 /** 5557 * Test verifying that messages cannot be sent to conversations by users who are not members. 5558 */ 5559 public function test_send_message_to_conversation_blocked_user() { 5560 // Get a bunch of conversations, some group, some individual and in different states. 5561 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5562 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5563 5564 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5565 $course = $this->getDataGenerator()->create_course(); 5566 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5567 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5568 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5569 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5570 5571 // User 1 blocks user 2. 5572 api::block_user($user1->id, $user2->id); 5573 5574 // Verify that a message can be sent to any group conversation in which user1 and user2 are members. 5575 $this->assertNotEmpty(api::send_message_to_conversation($user1->id, $gc2->id, 'Hey guys', FORMAT_PLAIN)); 5576 5577 // User 2 cannot send a message to the conversation with user 1. 5578 $this->expectException(\moodle_exception::class); 5579 api::send_message_to_conversation($user2->id, $ic1->id, 'test', FORMAT_MOODLE); 5580 } 5581 5582 /** 5583 * Test the get_conversation() function with a muted conversation. 5584 */ 5585 public function test_get_conversation_with_muted_conversation() { 5586 $this->resetAfterTest(); 5587 5588 $user1 = self::getDataGenerator()->create_user(); 5589 $user2 = self::getDataGenerator()->create_user(); 5590 5591 $this->setUser($user1); 5592 5593 $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5594 [$user1->id, $user2->id]); 5595 5596 $conversation = api::get_conversation($user1->id, $conversation->id); 5597 5598 $this->assertFalse($conversation->ismuted); 5599 5600 // Now, mute the conversation. 5601 api::mute_conversation($user1->id, $conversation->id); 5602 5603 $conversation = api::get_conversation($user1->id, $conversation->id); 5604 5605 $this->assertTrue($conversation->ismuted); 5606 } 5607 5608 /** 5609 * Data provider for test_get_conversation_counts(). 5610 */ 5611 public function get_conversation_counts_test_cases() { 5612 $typeindividual = api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 5613 $typegroup = api::MESSAGE_CONVERSATION_TYPE_GROUP; 5614 $typeself = api::MESSAGE_CONVERSATION_TYPE_SELF; 5615 list($user1, $user2, $user3, $user4, $user5, $user6, $user7, $user8) = [0, 1, 2, 3, 4, 5, 6, 7]; 5616 $conversations = [ 5617 [ 5618 'type' => $typeindividual, 5619 'users' => [$user1, $user2], 5620 'messages' => [$user1, $user2, $user2], 5621 'favourites' => [$user1], 5622 'enabled' => null // Individual conversations cannot be disabled. 5623 ], 5624 [ 5625 'type' => $typeindividual, 5626 'users' => [$user1, $user3], 5627 'messages' => [$user1, $user3, $user1], 5628 'favourites' => [], 5629 'enabled' => null // Individual conversations cannot be disabled. 5630 ], 5631 [ 5632 'type' => $typegroup, 5633 'users' => [$user1, $user2, $user3, $user4], 5634 'messages' => [$user1, $user2, $user3, $user4], 5635 'favourites' => [], 5636 'enabled' => true 5637 ], 5638 [ 5639 'type' => $typegroup, 5640 'users' => [$user2, $user3, $user4], 5641 'messages' => [$user2, $user3, $user4], 5642 'favourites' => [], 5643 'enabled' => true 5644 ], 5645 [ 5646 'type' => $typegroup, 5647 'users' => [$user6, $user7], 5648 'messages' => [$user6, $user7, $user7], 5649 'favourites' => [$user6], 5650 'enabled' => false 5651 ], 5652 [ 5653 'type' => $typeself, 5654 'users' => [$user8], 5655 'messages' => [$user8], 5656 'favourites' => [], 5657 'enabled' => null // Self-conversations cannot be disabled. 5658 ], 5659 ]; 5660 5661 return [ 5662 'No conversations' => [ 5663 'conversationConfigs' => $conversations, 5664 'deletemessagesuser' => null, 5665 'deletemessages' => [], 5666 'arguments' => [$user5], 5667 'expectedcounts' => ['favourites' => 1, 'types' => [ 5668 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5669 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5670 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5671 ]], 5672 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5673 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5674 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5675 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5676 ]], 5677 'deletedusers' => [] 5678 ], 5679 'No individual conversations, 2 group conversations' => [ 5680 'conversationConfigs' => $conversations, 5681 'deletemessagesuser' => null, 5682 'deletemessages' => [], 5683 'arguments' => [$user4], 5684 'expectedcounts' => ['favourites' => 1, 'types' => [ 5685 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5686 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5687 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5688 ]], 5689 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5690 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5691 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5692 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5693 ]], 5694 'deletedusers' => [] 5695 ], 5696 '2 individual conversations (one favourited), 1 group conversation' => [ 5697 'conversationConfigs' => $conversations, 5698 'deletemessagesuser' => null, 5699 'deletemessages' => [], 5700 'arguments' => [$user1], 5701 'expectedcounts' => ['favourites' => 2, 'types' => [ 5702 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5703 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5704 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5705 ]], 5706 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5707 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5708 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5709 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5710 ]], 5711 'deletedusers' => [] 5712 ], 5713 '1 individual conversation, 2 group conversations' => [ 5714 'conversationConfigs' => $conversations, 5715 'deletemessagesuser' => null, 5716 'deletemessages' => [], 5717 'arguments' => [$user2], 5718 'expectedcounts' => ['favourites' => 1, 'types' => [ 5719 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5720 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5721 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5722 ]], 5723 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5724 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5725 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5726 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5727 ]], 5728 'deletedusers' => [] 5729 ], 5730 '2 group conversations only' => [ 5731 'conversationConfigs' => $conversations, 5732 'deletemessagesuser' => null, 5733 'deletemessages' => [], 5734 'arguments' => [$user4], 5735 'expectedcounts' => ['favourites' => 1, 'types' => [ 5736 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5737 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5738 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5739 ]], 5740 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5741 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5742 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5743 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5744 ]], 5745 'deletedusers' => [] 5746 ], 5747 'All conversation types, delete a message from individual favourited, messages remaining' => [ 5748 'conversationConfigs' => $conversations, 5749 'deletemessagesuser' => $user1, 5750 'deletemessages' => [0], 5751 'arguments' => [$user1], 5752 'expectedcounts' => ['favourites' => 2, 'types' => [ 5753 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5754 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5755 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5756 ]], 5757 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5758 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5759 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5760 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5761 ]], 5762 'deletedusers' => [] 5763 ], 5764 'All conversation types, delete a message from individual non-favourited, messages remaining' => [ 5765 'conversationConfigs' => $conversations, 5766 'deletemessagesuser' => $user1, 5767 'deletemessages' => [3], 5768 'arguments' => [$user1], 5769 'expectedcounts' => ['favourites' => 2, 'types' => [ 5770 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5771 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5772 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5773 ]], 5774 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5775 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5776 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5777 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5778 ]], 5779 'deletedusers' => [] 5780 ], 5781 'All conversation types, delete all messages from individual favourited, no messages remaining' => [ 5782 'conversationConfigs' => $conversations, 5783 'deletemessagesuser' => $user1, 5784 'deletemessages' => [0, 1, 2], 5785 'arguments' => [$user1], 5786 'expectedcounts' => ['favourites' => 1, 'types' => [ 5787 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5788 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5789 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5790 ]], 5791 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5792 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5793 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5794 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5795 ]], 5796 'deletedusers' => [] 5797 ], 5798 'All conversation types, delete all messages from individual non-favourited, no messages remaining' => [ 5799 'conversationConfigs' => $conversations, 5800 'deletemessagesuser' => $user1, 5801 'deletemessages' => [3, 4, 5], 5802 'arguments' => [$user1], 5803 'expectedcounts' => ['favourites' => 2, 'types' => [ 5804 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5805 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5806 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5807 ]], 5808 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5809 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5810 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5811 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5812 ]], 5813 'deletedusers' => [] 5814 ], 5815 'All conversation types, delete all messages from individual favourited, no messages remaining, different user' => [ 5816 'conversationConfigs' => $conversations, 5817 'deletemessagesuser' => $user1, 5818 'deletemessages' => [0, 1, 2], 5819 'arguments' => [$user2], 5820 'expectedcounts' => ['favourites' => 1, 'types' => [ 5821 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5822 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5823 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5824 ]], 5825 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5826 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5827 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5828 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5829 ]], 5830 'deletedusers' => [] 5831 ], 5832 'All conversation types, delete all messages from individual non-favourited, no messages remaining, different user' => [ 5833 'conversationConfigs' => $conversations, 5834 'deletemessagesuser' => $user1, 5835 'deletemessages' => [3, 4, 5], 5836 'arguments' => [$user3], 5837 'expectedcounts' => ['favourites' => 1, 'types' => [ 5838 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5839 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5840 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5841 ]], 5842 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5843 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5844 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5845 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5846 ]], 5847 'deletedusers' => [] 5848 ], 5849 'All conversation types, delete some messages from group non-favourited, messages remaining,' => [ 5850 'conversationConfigs' => $conversations, 5851 'deletemessagesuser' => $user1, 5852 'deletemessages' => [6, 7], 5853 'arguments' => [$user1], 5854 'expectedcounts' => ['favourites' => 2, 'types' => [ 5855 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5856 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5857 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5858 ]], 5859 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5860 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5861 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5862 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5863 ]], 5864 'deletedusers' => [] 5865 ], 5866 'All conversation types, delete all messages from group non-favourited, no messages remaining,' => [ 5867 'conversationConfigs' => $conversations, 5868 'deletemessagesuser' => $user1, 5869 'deletemessages' => [6, 7, 8, 9], 5870 'arguments' => [$user1], 5871 'expectedcounts' => ['favourites' => 2, 'types' => [ 5872 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5873 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5874 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5875 ]], 5876 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5877 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5878 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5879 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5880 ]], 5881 'deletedusers' => [] 5882 ], 5883 'All conversation types, another user soft deleted' => [ 5884 'conversationConfigs' => $conversations, 5885 'deletemessagesuser' => null, 5886 'deletemessages' => [], 5887 'arguments' => [$user1], 5888 'expectedcounts' => ['favourites' => 2, 'types' => [ 5889 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5890 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5891 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5892 ]], 5893 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5894 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5895 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5896 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5897 ]], 5898 'deletedusers' => [$user2] 5899 ], 5900 'All conversation types, all group users soft deleted' => [ 5901 'conversationConfigs' => $conversations, 5902 'deletemessagesuser' => null, 5903 'deletemessages' => [], 5904 'arguments' => [$user1], 5905 'expectedcounts' => ['favourites' => 2, 'types' => [ 5906 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5907 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5908 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5909 ]], 5910 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5911 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5912 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5913 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5914 ]], 5915 'deletedusers' => [$user2, $user3, $user4] 5916 ], 5917 'Group conversation which is disabled, favourited' => [ 5918 'conversationConfigs' => $conversations, 5919 'deletemessagesuser' => null, 5920 'deletemessages' => [], 5921 'arguments' => [$user6], 5922 'expectedcounts' => ['favourites' => 1, 'types' => [ 5923 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5924 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5925 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5926 ]], 5927 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5928 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5929 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5930 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5931 ]], 5932 'deletedusers' => [] 5933 ], 5934 'Group conversation which is disabled, non-favourited' => [ 5935 'conversationConfigs' => $conversations, 5936 'deletemessagesuser' => null, 5937 'deletemessages' => [], 5938 'arguments' => [$user7], 5939 'expectedcounts' => ['favourites' => 1, 'types' => [ 5940 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5941 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5942 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5943 ]], 5944 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5945 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5946 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5947 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5948 ]], 5949 'deletedusers' => [] 5950 ], 5951 'Conversation with self' => [ 5952 'conversationConfigs' => $conversations, 5953 'deletemessagesuser' => null, 5954 'deletemessages' => [], 5955 'arguments' => [$user8], 5956 'expectedcounts' => ['favourites' => 0, 'types' => [ 5957 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5958 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5959 api::MESSAGE_CONVERSATION_TYPE_SELF => 1 5960 ]], 5961 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5962 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5963 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5964 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5965 ]], 5966 'deletedusers' => [] 5967 ], 5968 ]; 5969 } 5970 5971 /** 5972 * Test the get_conversation_counts() function. 5973 * 5974 * @dataProvider get_conversation_counts_test_cases 5975 * @param array $conversationconfigs Conversations to create 5976 * @param int $deletemessagesuser The user who is deleting the messages 5977 * @param array $deletemessages The list of messages to delete (by index) 5978 * @param array $arguments Arguments for the count conversations function 5979 * @param array $expectedcounts the expected conversation counts 5980 * @param array $expectedunreadcounts the expected unread conversation counts 5981 * @param array $deletedusers the array of users to soft delete. 5982 */ 5983 public function test_get_conversation_counts( 5984 $conversationconfigs, 5985 $deletemessagesuser, 5986 $deletemessages, 5987 $arguments, 5988 $expectedcounts, 5989 $expectedunreadcounts, 5990 $deletedusers 5991 ) { 5992 $generator = $this->getDataGenerator(); 5993 $users = [ 5994 $generator->create_user(), 5995 $generator->create_user(), 5996 $generator->create_user(), 5997 $generator->create_user(), 5998 $generator->create_user(), 5999 $generator->create_user(), 6000 $generator->create_user(), 6001 $generator->create_user() 6002 ]; 6003 6004 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 6005 $arguments[0] = $users[$arguments[0]]->id; 6006 $systemcontext = \context_system::instance(); 6007 $conversations = []; 6008 $messageids = []; 6009 6010 foreach ($conversationconfigs as $config) { 6011 $conversation = api::create_conversation( 6012 $config['type'], 6013 array_map(function($userindex) use ($users) { 6014 return $users[$userindex]->id; 6015 }, $config['users']), 6016 null, 6017 ($config['enabled'] ?? true) 6018 ); 6019 6020 foreach ($config['messages'] as $userfromindex) { 6021 $userfrom = $users[$userfromindex]; 6022 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 6023 } 6024 6025 // Remove the self conversations created by the generator, 6026 // so we can choose to set that ourself and honour the original intention of the test. 6027 $userids = array_map(function($userindex) use ($users) { 6028 return $users[$userindex]->id; 6029 }, $config['users']); 6030 foreach ($userids as $userid) { 6031 if ($conversation->type == api::MESSAGE_CONVERSATION_TYPE_SELF) { 6032 api::unset_favourite_conversation($conversation->id, $userid); 6033 } 6034 } 6035 6036 foreach ($config['favourites'] as $userfromindex) { 6037 $userfrom = $users[$userfromindex]; 6038 $usercontext = \context_user::instance($userfrom->id); 6039 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 6040 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 6041 } 6042 6043 $conversations[] = $conversation; 6044 } 6045 6046 foreach ($deletemessages as $messageindex) { 6047 api::delete_message($deleteuser->id, $messageids[$messageindex]); 6048 } 6049 6050 foreach ($deletedusers as $deleteduser) { 6051 delete_user($users[$deleteduser]); 6052 } 6053 6054 $counts = api::get_conversation_counts(...$arguments); 6055 6056 $this->assertEquals($expectedcounts['favourites'], $counts['favourites']); 6057 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 6058 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 6059 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP], 6060 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]); 6061 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF], 6062 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]); 6063 } 6064 6065 /** 6066 * Test the count_contacts() function. 6067 */ 6068 public function test_count_contacts() { 6069 $user1 = self::getDataGenerator()->create_user(); 6070 $user2 = self::getDataGenerator()->create_user(); 6071 $user3 = self::getDataGenerator()->create_user(); 6072 6073 $this->assertEquals(0, api::count_contacts($user1->id)); 6074 6075 api::create_contact_request($user1->id, $user2->id); 6076 6077 // Still zero until the request is confirmed. 6078 $this->assertEquals(0, api::count_contacts($user1->id)); 6079 6080 api::confirm_contact_request($user1->id, $user2->id); 6081 6082 $this->assertEquals(1, api::count_contacts($user1->id)); 6083 6084 api::create_contact_request($user3->id, $user1->id); 6085 6086 // Still one until the request is confirmed. 6087 $this->assertEquals(1, api::count_contacts($user1->id)); 6088 6089 api::confirm_contact_request($user3->id, $user1->id); 6090 6091 $this->assertEquals(2, api::count_contacts($user1->id)); 6092 } 6093 6094 /** 6095 * Test the get_unread_conversation_counts() function. 6096 * 6097 * @dataProvider get_conversation_counts_test_cases 6098 * @param array $conversationconfigs Conversations to create 6099 * @param int $deletemessagesuser The user who is deleting the messages 6100 * @param array $deletemessages The list of messages to delete (by index) 6101 * @param array $arguments Arguments for the count conversations function 6102 * @param array $expectedcounts the expected conversation counts 6103 * @param array $expectedunreadcounts the expected unread conversation counts 6104 * @param array $deletedusers the list of users to soft-delete. 6105 */ 6106 public function test_get_unread_conversation_counts( 6107 $conversationconfigs, 6108 $deletemessagesuser, 6109 $deletemessages, 6110 $arguments, 6111 $expectedcounts, 6112 $expectedunreadcounts, 6113 $deletedusers 6114 ) { 6115 $this->resetAfterTest(); 6116 $generator = $this->getDataGenerator(); 6117 $users = [ 6118 $generator->create_user(), 6119 $generator->create_user(), 6120 $generator->create_user(), 6121 $generator->create_user(), 6122 $generator->create_user(), 6123 $generator->create_user(), 6124 $generator->create_user(), 6125 $generator->create_user() 6126 ]; 6127 6128 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 6129 $this->setUser($users[$arguments[0]]); 6130 $arguments[0] = $users[$arguments[0]]->id; 6131 $systemcontext = \context_system::instance(); 6132 $conversations = []; 6133 $messageids = []; 6134 6135 foreach ($conversationconfigs as $config) { 6136 $conversation = api::create_conversation( 6137 $config['type'], 6138 array_map(function($userindex) use ($users) { 6139 return $users[$userindex]->id; 6140 }, $config['users']), 6141 null, 6142 ($config['enabled'] ?? true) 6143 ); 6144 6145 foreach ($config['messages'] as $userfromindex) { 6146 $userfrom = $users[$userfromindex]; 6147 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 6148 } 6149 6150 foreach ($config['favourites'] as $userfromindex) { 6151 $userfrom = $users[$userfromindex]; 6152 $usercontext = \context_user::instance($userfrom->id); 6153 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 6154 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 6155 } 6156 6157 $conversations[] = $conversation; 6158 } 6159 6160 foreach ($deletemessages as $messageindex) { 6161 api::delete_message($deleteuser->id, $messageids[$messageindex]); 6162 } 6163 6164 foreach ($deletedusers as $deleteduser) { 6165 delete_user($users[$deleteduser]); 6166 } 6167 6168 $counts = api::get_unread_conversation_counts(...$arguments); 6169 6170 $this->assertEquals($expectedunreadcounts['favourites'], $counts['favourites']); 6171 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 6172 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 6173 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP], 6174 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]); 6175 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF], 6176 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]); 6177 } 6178 6179 public function test_delete_all_conversation_data() { 6180 global $DB; 6181 6182 $this->resetAfterTest(); 6183 6184 $this->setAdminUser(); 6185 6186 $course1 = $this->getDataGenerator()->create_course(); 6187 $coursecontext1 = \context_course::instance($course1->id); 6188 6189 $user1 = $this->getDataGenerator()->create_user(); 6190 $user2 = $this->getDataGenerator()->create_user(); 6191 6192 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6193 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6194 6195 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); 6196 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); 6197 6198 // Add users to both groups. 6199 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 6200 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 6201 6202 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)); 6203 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)); 6204 6205 $groupconversation1 = api::get_conversation_by_area( 6206 'core_group', 6207 'groups', 6208 $group1->id, 6209 $coursecontext1->id 6210 ); 6211 6212 $groupconversation2 = api::get_conversation_by_area( 6213 'core_group', 6214 'groups', 6215 $group2->id, 6216 $coursecontext1->id 6217 ); 6218 6219 // Send a few messages. 6220 $g1m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id); 6221 $g1m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id); 6222 $g1m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id); 6223 $g1m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id); 6224 6225 $g2m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id); 6226 $g2m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id); 6227 $g2m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id); 6228 $g2m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id); 6229 6230 // Favourite the conversation for several of the users. 6231 api::set_favourite_conversation($groupconversation1->id, $user1->id); 6232 api::set_favourite_conversation($groupconversation1->id, $user2->id); 6233 6234 // Delete a few messages. 6235 api::delete_message($user1->id, $g1m1); 6236 api::delete_message($user1->id, $g1m2); 6237 api::delete_message($user1->id, $g2m1); 6238 api::delete_message($user1->id, $g2m2); 6239 6240 // Mute the conversations. 6241 api::mute_conversation($user1->id, $groupconversation1->id); 6242 api::mute_conversation($user1->id, $groupconversation2->id); 6243 6244 // Now, delete all the data for the group 1 conversation. 6245 api::delete_all_conversation_data($groupconversation1->id); 6246 6247 // Confirm group conversation was deleted just for the group 1 conversation. 6248 $this->assertEquals(0, $DB->count_records('message_conversations', ['id' => $groupconversation1->id])); 6249 $this->assertEquals(1, $DB->count_records('message_conversations', ['id' => $groupconversation2->id])); 6250 6251 // Confirm conversation members were deleted just for the group 1 conversation. 6252 $this->assertEquals(0, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation1->id])); 6253 $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation2->id])); 6254 6255 // Confirm message conversation actions were deleted just for the group 1 conversation. 6256 $this->assertEquals(0, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation1->id])); 6257 $this->assertEquals(1, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation2->id])); 6258 6259 // Confirm message user actions were deleted just for the group 1 conversation. 6260 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m1])); 6261 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m2])); 6262 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m3])); 6263 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m4])); 6264 $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m1])); 6265 $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m2])); 6266 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m3])); 6267 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m4])); 6268 6269 // Confirm messages were deleted just for the group 1 conversation. 6270 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m1])); 6271 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m2])); 6272 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m3])); 6273 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m4])); 6274 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m1])); 6275 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m2])); 6276 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m3])); 6277 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4])); 6278 6279 // Confirm favourites were deleted for both users. 6280 $user1service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id)); 6281 $this->assertFalse($user1service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id, 6282 $coursecontext1)); 6283 $user2service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id)); 6284 $this->assertFalse($user2service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id, 6285 $coursecontext1)); 6286 } 6287 6288 /** 6289 * Tests the user can delete message for all users as a teacher. 6290 */ 6291 public function test_can_delete_message_for_all_users_teacher() { 6292 global $DB; 6293 $this->resetAfterTest(true); 6294 6295 // Create fake data to test it. 6296 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6297 6298 // Allow Teacher can delete messages for all. 6299 $editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']); 6300 assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, \context_system::instance()); 6301 6302 // Set as the first user. 6303 $this->setUser($teacher); 6304 6305 // Send a message to private conversation and in a group conversation. 6306 $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6307 $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6308 6309 // Teacher cannot delete message for everyone in a private conversation. 6310 $this->assertFalse(api::can_delete_message_for_all_users($teacher->id, $messageidind)); 6311 6312 // Teacher can delete message for everyone in a group conversation. 6313 $this->assertTrue(api::can_delete_message_for_all_users($teacher->id, $messageidgrp)); 6314 } 6315 6316 /** 6317 * Tests the user can delete message for all users as a student. 6318 */ 6319 public function test_can_delete_message_for_all_users_student() { 6320 $this->resetAfterTest(true); 6321 6322 // Create fake data to test it. 6323 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6324 6325 // Set as the first user. 6326 $this->setUser($student1); 6327 6328 // Send a message to private conversation and in a group conversation. 6329 $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6330 $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6331 6332 // Student1 cannot delete message for everyone in a private conversation. 6333 $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidind)); 6334 6335 // Student1 cannot delete message for everyone in a group conversation. 6336 $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidgrp)); 6337 } 6338 6339 /** 6340 * Tests tdelete message for all users in group conversation. 6341 */ 6342 public function test_delete_message_for_all_users_group_conversation() { 6343 global $DB; 6344 $this->resetAfterTest(true); 6345 6346 // Create fake data to test it. 6347 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6348 6349 // Send 3 messages to a group conversation. 6350 $mgid1 = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6351 $mgid2 = testhelper::send_fake_message_to_conversation($student1, $convgroup->id); 6352 $mgid3 = testhelper::send_fake_message_to_conversation($student2, $convgroup->id); 6353 6354 // Delete message 1 for all users. 6355 api::delete_message_for_all_users($mgid1); 6356 6357 // Get the messages to check if the message 1 was deleted for teacher. 6358 $convmessages1 = api::get_conversation_messages($teacher->id, $convgroup->id); 6359 // Only has to remains 2 messages. 6360 $this->assertCount(2, $convmessages1['messages']); 6361 // Check if no one of the two messages is message 1. 6362 foreach ($convmessages1['messages'] as $message) { 6363 $this->assertNotEquals($mgid1, $message->id); 6364 } 6365 6366 // Get the messages to check if the message 1 was deleted for student1. 6367 $convmessages2 = api::get_conversation_messages($student1->id, $convgroup->id); 6368 // Only has to remains 2 messages. 6369 $this->assertCount(2, $convmessages2['messages']); 6370 // Check if no one of the two messages is message 1. 6371 foreach ($convmessages2['messages'] as $message) { 6372 $this->assertNotEquals($mgid1, $message->id); 6373 } 6374 6375 // Get the messages to check if the message 1 was deleted for student2. 6376 $convmessages3 = api::get_conversation_messages($student2->id, $convgroup->id); 6377 // Only has to remains 2 messages. 6378 $this->assertCount(2, $convmessages3['messages']); 6379 // Check if no one of the two messages is message 1. 6380 foreach ($convmessages3['messages'] as $message) { 6381 $this->assertNotEquals($mgid1, $message->id); 6382 } 6383 } 6384 6385 /** 6386 * Tests delete message for all users in private conversation. 6387 */ 6388 public function test_delete_message_for_all_users_individual_conversation() { 6389 global $DB; 6390 $this->resetAfterTest(true); 6391 6392 // Create fake data to test it. 6393 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6394 6395 // Send 2 messages in a individual conversation. 6396 $mid1 = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6397 $mid2 = testhelper::send_fake_message_to_conversation($student1, $convindividual->id); 6398 6399 // Delete the first message for all users. 6400 api::delete_message_for_all_users($mid1); 6401 6402 // Get the messages to check if the message 1 was deleted for teacher. 6403 $convmessages1 = api::get_conversation_messages($teacher->id, $convindividual->id); 6404 // Only has to remains 1 messages for teacher. 6405 $this->assertCount(1, $convmessages1['messages']); 6406 // Check the one messages remains not is the first message. 6407 $this->assertNotEquals($mid1, $convmessages1['messages'][0]->id); 6408 6409 // Get the messages to check if the message 1 was deleted for student1. 6410 $convmessages2 = api::get_conversation_messages($student1->id, $convindividual->id); 6411 // Only has to remains 1 messages for student1. 6412 $this->assertCount(1, $convmessages2['messages']); 6413 // Check the one messages remains not is the first message. 6414 $this->assertNotEquals($mid1, $convmessages2['messages'][0]->id); 6415 } 6416 6417 /** 6418 * Test retrieving conversation messages by providing a timefrom higher than last message timecreated. It should return no 6419 * messages but keep the return structure to not break when called from the ws. 6420 */ 6421 public function test_get_conversation_messages_timefrom_higher_than_last_timecreated() { 6422 // Create some users. 6423 $user1 = self::getDataGenerator()->create_user(); 6424 $user2 = self::getDataGenerator()->create_user(); 6425 $user3 = self::getDataGenerator()->create_user(); 6426 $user4 = self::getDataGenerator()->create_user(); 6427 6428 // Create group conversation. 6429 $conversation = api::create_conversation( 6430 api::MESSAGE_CONVERSATION_TYPE_GROUP, 6431 [$user1->id, $user2->id, $user3->id, $user4->id] 6432 ); 6433 6434 // The person doing the search. 6435 $this->setUser($user1); 6436 6437 // Send some messages back and forth. 6438 $time = 1; 6439 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 6440 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 6441 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 6442 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 6443 6444 // Retrieve the messages from $time + 5, which should return no messages. 6445 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, '', $time + 5); 6446 6447 // Confirm the conversation id is correct. 6448 $this->assertEquals($conversation->id, $convmessages['id']); 6449 6450 // Confirm the message data is correct. 6451 $messages = $convmessages['messages']; 6452 $this->assertEquals(0, count($messages)); 6453 6454 // Confirm that members key is present. 6455 $this->assertArrayHasKey('members', $convmessages); 6456 } 6457 6458 /** 6459 * Helper to seed the database with initial state with data. 6460 */ 6461 protected function create_delete_message_test_data() { 6462 // Create some users. 6463 $teacher = self::getDataGenerator()->create_user(); 6464 $student1 = self::getDataGenerator()->create_user(); 6465 $student2 = self::getDataGenerator()->create_user(); 6466 6467 // Create a course and enrol the users. 6468 $course = $this->getDataGenerator()->create_course(); 6469 $coursecontext = \context_course::instance($course->id); 6470 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher'); 6471 $this->getDataGenerator()->enrol_user($student1->id, $course->id, 'student'); 6472 $this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student'); 6473 6474 // Create a group and added the users into. 6475 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 6476 groups_add_member($group1->id, $teacher->id); 6477 groups_add_member($group1->id, $student1->id); 6478 groups_add_member($group1->id, $student2->id); 6479 6480 // Create a group conversation linked with the course. 6481 $convgroup = api::create_conversation( 6482 api::MESSAGE_CONVERSATION_TYPE_GROUP, 6483 [$teacher->id, $student1->id, $student2->id], 6484 'Group test delete for everyone', api::MESSAGE_CONVERSATION_ENABLED, 6485 'core_group', 6486 'groups', 6487 $group1->id, 6488 \context_course::instance($course->id)->id 6489 ); 6490 6491 // Create and individual conversation. 6492 $convindividual = api::create_conversation( 6493 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6494 [$teacher->id, $student1->id] 6495 ); 6496 6497 return [$teacher, $student1, $student2, $convgroup, $convindividual]; 6498 } 6499 6500 /** 6501 * Comparison function for sorting contacts. 6502 * 6503 * @param \stdClass $a 6504 * @param \stdClass $b 6505 * @return bool 6506 */ 6507 protected static function sort_contacts($a, $b) { 6508 return $a->userid > $b->userid; 6509 } 6510 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body