Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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_loggedin', 'popup', $user); 2964 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', '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_loggedin['popup']); 2971 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['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 * Test that calling to can_post_message() now shows debugging. MDL-65093. 3263 * 3264 * @deprecated since 3.8 3265 * @todo Final deprecation in MDL-66266 3266 */ 3267 public function test_can_post_emits_debugging() { 3268 // Create some users. 3269 $user1 = self::getDataGenerator()->create_user(); 3270 $user2 = self::getDataGenerator()->create_user(); 3271 3272 // Set as the first user. 3273 $this->setUser($user1); 3274 3275 // With the default privacy setting, users can't message them. 3276 $this->assertFalse(\core_message\api::can_post_message($user2)); 3277 $this->assertDebuggingCalled('\core_message\api::can_post_message is deprecated, please use ' . 3278 '\core_message\api::can_send_message instead.', DEBUG_DEVELOPER); 3279 } 3280 3281 /** 3282 * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings. 3283 */ 3284 public function test_can_send_message_to_conversation_basic() { 3285 // Create some users. 3286 $user1 = self::getDataGenerator()->create_user(); 3287 $user2 = self::getDataGenerator()->create_user(); 3288 $user3 = self::getDataGenerator()->create_user(); 3289 3290 // Create an individual conversation between user1 and user2. 3291 $ic1 = api::create_conversation( 3292 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3293 [ 3294 $user1->id, 3295 $user2->id 3296 ] 3297 ); 3298 3299 // Create a group conversation between and users 1, 2 and 3. 3300 $gc1 = api::create_conversation( 3301 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3302 [ 3303 $user1->id, 3304 $user2->id, 3305 $user3->id 3306 ] 3307 ); 3308 3309 // Get a self-conversation for user1. 3310 $sc1 = api::get_self_conversation($user1->id); 3311 3312 // For group conversations, there are no user privacy checks, so only membership in the conversation is needed. 3313 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3314 3315 // For self conversations, there are no user privacy checks, so only membership in the conversation is needed. 3316 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $sc1->id)); 3317 3318 // For individual conversations, the default privacy setting of 'only contacts and course members' applies. 3319 // Users are not in the same course, nor are they contacts, so messages cannot be sent. 3320 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3321 3322 // Enrol the users into the same course. 3323 $course = $this->getDataGenerator()->create_course(); 3324 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3325 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3326 3327 // After enrolling users to the course, they should be able to message them with the default privacy setting. 3328 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3329 } 3330 3331 /** 3332 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability. 3333 */ 3334 public function test_can_send_message_to_conversation_sendmessage_cap() { 3335 global $DB; 3336 3337 $user1 = self::getDataGenerator()->create_user(); 3338 $user2 = self::getDataGenerator()->create_user(); 3339 $user3 = self::getDataGenerator()->create_user(); 3340 3341 // Enrol the users into the same course. 3342 $course = $this->getDataGenerator()->create_course(); 3343 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3344 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3345 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3346 3347 // Create an individual conversation between user1 and user2. 3348 $ic1 = api::create_conversation( 3349 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3350 [ 3351 $user1->id, 3352 $user2->id 3353 ] 3354 ); 3355 3356 // Group conversation between and users 1, 2 and 3. 3357 $gc1 = api::create_conversation( 3358 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3359 [ 3360 $user1->id, 3361 $user2->id, 3362 $user3->id 3363 ] 3364 ); 3365 3366 // Default settings - user1 can send a message to both conversations. 3367 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3368 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3369 3370 // Remove the capability to send a message. 3371 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); 3372 unassign_capability('moodle/site:sendmessage', $roleids['user'], \context_system::instance()); 3373 3374 // Verify that a user cannot send a message to either an individual or a group conversation. 3375 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3376 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3377 } 3378 3379 /** 3380 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the messageanyuser capability. 3381 */ 3382 public function test_can_send_message_to_conversation_messageanyuser_cap() { 3383 global $DB; 3384 3385 $user1 = self::getDataGenerator()->create_user(); 3386 $user2 = self::getDataGenerator()->create_user(); 3387 $user3 = self::getDataGenerator()->create_user(); 3388 3389 // Enrol the users into the same course. 3390 $course = $this->getDataGenerator()->create_course(); 3391 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3392 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3393 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3394 3395 // Create an individual conversation between user1 and user2. 3396 $ic1 = api::create_conversation( 3397 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3398 [ 3399 $user1->id, 3400 $user2->id 3401 ] 3402 ); 3403 3404 // Group conversation between and users 1, 2 and 3. 3405 $gc1 = api::create_conversation( 3406 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3407 [ 3408 $user1->id, 3409 $user2->id, 3410 $user3->id 3411 ] 3412 ); 3413 3414 // Update the message preference for user2, so they can only be messaged by contacts. 3415 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3416 3417 // Verify that the user cannot be contacted in the individual conversation and that groups are unaffected. 3418 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3419 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3420 3421 // Assign the 'messageanyuser' capability to user1 at system context. 3422 $systemcontext = \context_system::instance(); 3423 $authenticateduser = $DB->get_record('role', ['shortname' => 'user']); 3424 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, $systemcontext->id); 3425 3426 // Check that user1 can now message user2 due to the capability, and that group conversations is again unaffected. 3427 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3428 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3429 } 3430 3431 /** 3432 * Test verifying that users cannot send messages to conversations they are not a part of. 3433 */ 3434 public function test_can_send_message_to_conversation_non_member() { 3435 // Create some users. 3436 $user1 = self::getDataGenerator()->create_user(); 3437 $user2 = self::getDataGenerator()->create_user(); 3438 $user3 = self::getDataGenerator()->create_user(); 3439 $user4 = self::getDataGenerator()->create_user(); 3440 3441 // Enrol the users into the same course. 3442 $course = $this->getDataGenerator()->create_course(); 3443 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3444 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3445 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3446 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 3447 3448 // Create an individual conversation between user1 and user2. 3449 $ic1 = api::create_conversation( 3450 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3451 [ 3452 $user1->id, 3453 $user2->id 3454 ] 3455 ); 3456 3457 // Create a group conversation between and users 1, 2 and 3. 3458 $gc1 = api::create_conversation( 3459 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3460 [ 3461 $user1->id, 3462 $user2->id, 3463 $user3->id 3464 ] 3465 ); 3466 3467 // Get a self-conversation for user1. 3468 $sc1 = api::get_self_conversation($user1->id); 3469 3470 // Verify, non members cannot send a message. 3471 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $gc1->id)); 3472 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $ic1->id)); 3473 $this->assertFalse(api::can_send_message_to_conversation($user4->id, $sc1->id)); 3474 } 3475 3476 /** 3477 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts only. 3478 */ 3479 public function test_can_send_message_to_conversation_privacy_contacts_only() { 3480 // Create some users. 3481 $user1 = self::getDataGenerator()->create_user(); 3482 $user2 = self::getDataGenerator()->create_user(); 3483 $user3 = self::getDataGenerator()->create_user(); 3484 3485 // Create an individual conversation between user1 and user2. 3486 $ic1 = api::create_conversation( 3487 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3488 [ 3489 $user1->id, 3490 $user2->id 3491 ] 3492 ); 3493 3494 // Create a group conversation between and users 1, 2 and 3. 3495 $gc1 = api::create_conversation( 3496 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3497 [ 3498 $user1->id, 3499 $user2->id, 3500 $user3->id 3501 ] 3502 ); 3503 3504 // Set the message privacy preference to 'contacts only' for user 2. 3505 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3506 3507 // Verify that user1 cannot send a message to the individual conversation, but that the group conversation is unaffected. 3508 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3509 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3510 3511 // Now, simulate a contact request (and approval) between user1 and user2. 3512 api::create_contact_request($user1->id, $user2->id); 3513 api::confirm_contact_request($user1->id, $user2->id); 3514 3515 // Verify user1 can now message user2 again via their individual conversation. 3516 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3517 } 3518 3519 /** 3520 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts / course members. 3521 */ 3522 public function test_can_send_message_to_conversation_privacy_contacts_course() { 3523 // Create some users. 3524 $user1 = self::getDataGenerator()->create_user(); 3525 $user2 = self::getDataGenerator()->create_user(); 3526 $user3 = self::getDataGenerator()->create_user(); 3527 3528 // Set the message privacy preference to 'contacts + course members' for user 2. 3529 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id); 3530 3531 // Create an individual conversation between user1 and user2. 3532 $ic1 = api::create_conversation( 3533 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3534 [ 3535 $user1->id, 3536 $user2->id 3537 ] 3538 ); 3539 3540 // Create a group conversation between and users 1, 2 and 3. 3541 $gc1 = api::create_conversation( 3542 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3543 [ 3544 $user1->id, 3545 $user2->id, 3546 $user3->id 3547 ] 3548 ); 3549 3550 // Verify that users in a group conversation can message one another (i.e. privacy controls ignored). 3551 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3552 3553 // Verify that user1 can not message user2 unless they are either contacts, or share a course. 3554 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3555 3556 // Enrol the users into the same course. 3557 $course = $this->getDataGenerator()->create_course(); 3558 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3559 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3560 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3561 3562 // Verify that user1 can send a message to user2, based on the shared course, without being a contact. 3563 $this->assertFalse(api::is_contact($user1->id, $user2->id)); 3564 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3565 } 3566 3567 /** 3568 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to any user. 3569 */ 3570 public function test_can_send_message_to_conversation_privacy_sitewide() { 3571 // Create some users. 3572 $user1 = self::getDataGenerator()->create_user(); 3573 $user2 = self::getDataGenerator()->create_user(); 3574 $user3 = self::getDataGenerator()->create_user(); 3575 3576 // Create an individual conversation between user1 and user2. 3577 $ic1 = api::create_conversation( 3578 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3579 [ 3580 $user1->id, 3581 $user2->id 3582 ] 3583 ); 3584 3585 // Create a group conversation between and users 1, 2 and 3. 3586 $gc1 = api::create_conversation( 3587 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3588 [ 3589 $user1->id, 3590 $user2->id, 3591 $user3->id 3592 ] 3593 ); 3594 3595 // By default, the messaging privacy dictates that users can only be contacted by contacts, and members of their courses. 3596 // Verify also, that groups are not restricted in this way. 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 // Enable site-wide messagging privacy setting. 3601 // This enables a privacy option for users, allowing them to choose to be contactable by anybody on the site. 3602 set_config('messagingallusers', true); 3603 3604 // Set the second user's preference to receive messages from everybody. 3605 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user2->id); 3606 3607 // Check that user1 can send user2 a message, and that the group conversation is unaffected. 3608 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3609 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3610 3611 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts 3612 // and members sharing a course with her. 3613 set_config('messagingallusers', false); 3614 3615 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER. 3616 // Verify also that the group conversation is unaffected. 3617 $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id)); 3618 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3619 } 3620 3621 /** 3622 * Test verifying the behaviour of the can_send_message_to_conversation method when a user is blocked. 3623 */ 3624 public function test_can_send_message_to_conversation_when_blocked() { 3625 $user1 = self::getDataGenerator()->create_user(); 3626 $user2 = self::getDataGenerator()->create_user(); 3627 $user3 = self::getDataGenerator()->create_user(); 3628 3629 // Create an individual conversation between user1 and user2. 3630 $ic1 = api::create_conversation( 3631 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 3632 [ 3633 $user1->id, 3634 $user2->id 3635 ] 3636 ); 3637 3638 // Create a group conversation between and users 1, 2 and 3. 3639 $gc1 = api::create_conversation( 3640 api::MESSAGE_CONVERSATION_TYPE_GROUP, 3641 [ 3642 $user1->id, 3643 $user2->id, 3644 $user3->id 3645 ] 3646 ); 3647 3648 // Enrol the users into the same course. 3649 $course = $this->getDataGenerator()->create_course(); 3650 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 3651 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 3652 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 3653 3654 // Block the second user. 3655 api::block_user($user1->id, $user2->id); 3656 3657 // Check that user2 can not send user1 a message in their individual conversation. 3658 $this->assertFalse(api::can_send_message_to_conversation($user2->id, $ic1->id)); 3659 3660 // Verify that group conversations are unaffected. 3661 $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id)); 3662 $this->assertTrue(api::can_send_message_to_conversation($user2->id, $gc1->id)); 3663 } 3664 3665 /** 3666 * Tests get_user_privacy_messaging_preference method. 3667 */ 3668 public function test_get_user_privacy_messaging_preference() { 3669 // Create some users. 3670 $user1 = self::getDataGenerator()->create_user(); 3671 $user2 = self::getDataGenerator()->create_user(); 3672 $user3 = self::getDataGenerator()->create_user(); 3673 3674 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody. 3675 set_config('messagingallusers', true); 3676 3677 // Set some user preferences. 3678 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user1->id); 3679 set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id); 3680 3681 // Check the returned value for each user. 3682 $this->assertEquals( 3683 api::MESSAGE_PRIVACY_SITE, 3684 api::get_user_privacy_messaging_preference($user1->id) 3685 ); 3686 $this->assertEquals( 3687 api::MESSAGE_PRIVACY_ONLYCONTACTS, 3688 api::get_user_privacy_messaging_preference($user2->id) 3689 ); 3690 $this->assertEquals( 3691 api::MESSAGE_PRIVACY_SITE, 3692 api::get_user_privacy_messaging_preference($user3->id) 3693 ); 3694 3695 // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course. 3696 set_config('messagingallusers', false); 3697 3698 // Check the returned value for each user. 3699 $this->assertEquals( 3700 api::MESSAGE_PRIVACY_COURSEMEMBER, 3701 api::get_user_privacy_messaging_preference($user1->id) 3702 ); 3703 $this->assertEquals( 3704 api::MESSAGE_PRIVACY_ONLYCONTACTS, 3705 api::get_user_privacy_messaging_preference($user2->id) 3706 ); 3707 $this->assertEquals( 3708 api::MESSAGE_PRIVACY_COURSEMEMBER, 3709 api::get_user_privacy_messaging_preference($user3->id) 3710 ); 3711 } 3712 3713 /* 3714 * Tes get_message_processor api. 3715 */ 3716 public function test_get_message_processor() { 3717 $processors = get_message_processors(true); 3718 if (empty($processors)) { 3719 $this->markTestSkipped("No message processors found"); 3720 } 3721 3722 $name = key($processors); 3723 $processor = current($processors); 3724 $testprocessor = api::get_message_processor($name); 3725 $this->assertEquals($processor->name, $testprocessor->name); 3726 $this->assertEquals($processor->enabled, $testprocessor->enabled); 3727 $this->assertEquals($processor->available, $testprocessor->available); 3728 $this->assertEquals($processor->configured, $testprocessor->configured); 3729 3730 // Disable processor and test. 3731 api::update_processor_status($testprocessor, 0); 3732 $testprocessor = api::get_message_processor($name, true); 3733 $this->assertEmpty($testprocessor); 3734 $testprocessor = api::get_message_processor($name); 3735 $this->assertEquals($processor->name, $testprocessor->name); 3736 $this->assertEquals(0, $testprocessor->enabled); 3737 3738 // Enable again and test. 3739 api::update_processor_status($testprocessor, 1); 3740 $testprocessor = api::get_message_processor($name, true); 3741 $this->assertEquals($processor->name, $testprocessor->name); 3742 $this->assertEquals(1, $testprocessor->enabled); 3743 $testprocessor = api::get_message_processor($name); 3744 $this->assertEquals($processor->name, $testprocessor->name); 3745 $this->assertEquals(1, $testprocessor->enabled); 3746 } 3747 3748 /** 3749 * Test method update_processor_status. 3750 */ 3751 public function test_update_processor_status() { 3752 $processors = get_message_processors(); 3753 if (empty($processors)) { 3754 $this->markTestSkipped("No message processors found"); 3755 } 3756 $name = key($processors); 3757 $testprocessor = current($processors); 3758 3759 // Enable. 3760 api::update_processor_status($testprocessor, 1); 3761 $testprocessor = api::get_message_processor($name); 3762 $this->assertEquals(1, $testprocessor->enabled); 3763 3764 // Disable. 3765 api::update_processor_status($testprocessor, 0); 3766 $testprocessor = api::get_message_processor($name); 3767 $this->assertEquals(0, $testprocessor->enabled); 3768 3769 // Enable again. 3770 api::update_processor_status($testprocessor, 1); 3771 $testprocessor = api::get_message_processor($name); 3772 $this->assertEquals(1, $testprocessor->enabled); 3773 } 3774 3775 /** 3776 * Test method is_user_enabled. 3777 */ 3778 public function is_user_enabled() { 3779 $processors = get_message_processors(); 3780 if (empty($processors)) { 3781 $this->markTestSkipped("No message processors found"); 3782 } 3783 $name = key($processors); 3784 $testprocessor = current($processors); 3785 3786 // Enable. 3787 api::update_processor_status($testprocessor, 1); 3788 $status = api::is_processor_enabled($name); 3789 $this->assertEquals(1, $status); 3790 3791 // Disable. 3792 api::update_processor_status($testprocessor, 0); 3793 $status = api::is_processor_enabled($name); 3794 $this->assertEquals(0, $status); 3795 3796 // Enable again. 3797 api::update_processor_status($testprocessor, 1); 3798 $status = api::is_processor_enabled($name); 3799 $this->assertEquals(1, $status); 3800 } 3801 3802 /** 3803 * Test returning blocked users. 3804 */ 3805 public function test_get_blocked_users() { 3806 global $USER; 3807 3808 // Set this user as the admin. 3809 $this->setAdminUser(); 3810 3811 // Create a user to add to the admin's contact list. 3812 $user1 = $this->getDataGenerator()->create_user(); 3813 $user2 = $this->getDataGenerator()->create_user(); 3814 3815 // Add users to the admin's contact list. 3816 api::block_user($USER->id, $user2->id); 3817 3818 $this->assertCount(1, api::get_blocked_users($USER->id)); 3819 3820 // Block other user. 3821 api::block_user($USER->id, $user1->id); 3822 $this->assertCount(2, api::get_blocked_users($USER->id)); 3823 3824 // Test deleting users. 3825 delete_user($user1); 3826 $this->assertCount(1, api::get_blocked_users($USER->id)); 3827 } 3828 3829 /** 3830 * Test returning contacts with unread message count. 3831 * MDL-69643 3832 */ 3833 public function test_get_contacts_with_unread_message_count() { 3834 global $DB; 3835 3836 $user1 = self::getDataGenerator()->create_user(); 3837 $user2 = self::getDataGenerator()->create_user(); 3838 $user3 = self::getDataGenerator()->create_user(); 3839 $user4 = self::getDataGenerator()->create_user(); 3840 3841 // Add the users to each of their contacts. 3842 api::add_contact($user1->id, $user2->id); 3843 api::add_contact($user2->id, $user3->id); 3844 3845 $this->send_fake_message($user1, $user2); 3846 $this->send_fake_message($user1, $user2); 3847 $this->send_fake_message($user1, $user2); 3848 $message4id = $this->send_fake_message($user1, $user2); 3849 3850 $this->send_fake_message($user3, $user2); 3851 $message6id = $this->send_fake_message($user3, $user2); 3852 $this->send_fake_message($user3, $user2); 3853 $this->send_fake_message($user3, $user2); 3854 $this->send_fake_message($user3, $user2); 3855 3856 // Send a message that should never be included as the user is not a contact. 3857 $this->send_fake_message($user4, $user2); 3858 3859 // Get the contacts and the unread message count. 3860 $messages = api::get_contacts_with_unread_message_count($user2->id); 3861 $this->assertDebuggingCalled(); 3862 3863 // Confirm the size is correct. 3864 $this->assertCount(2, $messages); 3865 ksort($messages); 3866 3867 $messageinfo1 = array_shift($messages); 3868 $messageinfo2 = array_shift($messages); 3869 3870 $this->assertEquals($user1->id, $messageinfo1->id); 3871 $this->assertEquals(4, $messageinfo1->messagecount); 3872 $this->assertEquals($user3->id, $messageinfo2->id); 3873 $this->assertEquals(5, $messageinfo2->messagecount); 3874 3875 // Mark some of the messages as read. 3876 $m4 = $DB->get_record('messages', ['id' => $message4id]); 3877 $m6 = $DB->get_record('messages', ['id' => $message6id]); 3878 api::mark_message_as_read($user2->id, $m4); 3879 api::mark_message_as_read($user2->id, $m6); 3880 3881 // Get the contacts and the unread message count. 3882 $messages = api::get_contacts_with_unread_message_count($user2->id); 3883 $this->assertDebuggingCalled(); 3884 3885 // Confirm the size is correct. 3886 $this->assertCount(2, $messages); 3887 ksort($messages); 3888 3889 // Confirm read messages are not included. 3890 $messageinfo1 = array_shift($messages); 3891 $messageinfo2 = array_shift($messages); 3892 $this->assertEquals($user1->id, $messageinfo1->id); 3893 $this->assertEquals(3, $messageinfo1->messagecount); 3894 $this->assertEquals($user3->id, $messageinfo2->id); 3895 $this->assertEquals(4, $messageinfo2->messagecount); 3896 3897 // Now, let's populate the database with messages from user2 to user 1. 3898 $this->send_fake_message($user2, $user1); 3899 $this->send_fake_message($user2, $user1); 3900 $messageid = $this->send_fake_message($user2, $user1); 3901 3902 // Send a message that should never be included as the user is not a contact. 3903 $this->send_fake_message($user4, $user1); 3904 3905 // Get the contacts and the unread message count. 3906 $messages = api::get_contacts_with_unread_message_count($user1->id); 3907 $this->assertDebuggingCalled(); 3908 3909 // Confirm the size is correct. 3910 $this->assertCount(1, $messages); 3911 $messageinfo1 = array_shift($messages); 3912 $this->assertEquals($user2->id, $messageinfo1->id); 3913 $this->assertEquals(3, $messageinfo1->messagecount); 3914 3915 // Mark the last message as read. 3916 $m = $DB->get_record('messages', ['id' => $messageid]); 3917 api::mark_message_as_read($user1->id, $m); 3918 3919 $messages = api::get_contacts_with_unread_message_count($user1->id); 3920 $this->assertDebuggingCalled(); 3921 3922 // Confirm the size is correct. 3923 $this->assertCount(1, $messages); 3924 3925 // Confirm read messages are not included. 3926 $messageinfo1 = array_shift($messages); 3927 $this->assertEquals($user2->id, $messageinfo1->id); 3928 $this->assertEquals(2, $messageinfo1->messagecount); 3929 } 3930 3931 /** 3932 * Test returning contacts with unread message count when there are no messages. 3933 */ 3934 public function test_get_contacts_with_unread_message_count_no_messages() { 3935 $user1 = self::getDataGenerator()->create_user(); 3936 $user2 = self::getDataGenerator()->create_user(); 3937 3938 // Add the users to each of their contacts. 3939 api::add_contact($user2->id, $user1->id); 3940 3941 // Check we get the correct message count. 3942 $messages = api::get_contacts_with_unread_message_count($user2->id); 3943 $this->assertDebuggingCalled(); 3944 3945 // Confirm the size is correct. 3946 $this->assertCount(1, $messages); 3947 3948 $messageinfo = array_shift($messages); 3949 3950 $this->assertEquals($user1->id, $messageinfo->id); 3951 $this->assertEquals(0, $messageinfo->messagecount); 3952 } 3953 3954 /** 3955 * Test returning non-contacts with unread message count. 3956 * MDL-69643 3957 */ 3958 public function test_get_non_contacts_with_unread_message_count() { 3959 global $DB; 3960 3961 $user1 = self::getDataGenerator()->create_user(); 3962 $user2 = self::getDataGenerator()->create_user(); 3963 $user3 = self::getDataGenerator()->create_user(); 3964 $user4 = self::getDataGenerator()->create_user(); 3965 3966 // Add a user to the contact list of the users we are testing this function with. 3967 api::add_contact($user1->id, $user4->id); 3968 api::add_contact($user2->id, $user4->id); 3969 3970 $this->send_fake_message($user1, $user2); 3971 $this->send_fake_message($user1, $user2); 3972 $this->send_fake_message($user1, $user2); 3973 $message4id = $this->send_fake_message($user1, $user2); 3974 3975 $this->send_fake_message($user3, $user2); 3976 $message6id = $this->send_fake_message($user3, $user2); 3977 $this->send_fake_message($user3, $user2); 3978 $this->send_fake_message($user3, $user2); 3979 $this->send_fake_message($user3, $user2); 3980 3981 // Send a message that should never be included as the user is a contact. 3982 $this->send_fake_message($user4, $user2); 3983 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 we get the correct 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(4, $messageinfo1->messagecount); 3996 $this->assertEquals($user3->id, $messageinfo2->id); 3997 $this->assertEquals(5, $messageinfo2->messagecount); 3998 3999 // Mark some of the messages as read. 4000 $m4 = $DB->get_record('messages', ['id' => $message4id]); 4001 $m6 = $DB->get_record('messages', ['id' => $message6id]); 4002 api::mark_message_as_read($user2->id, $m4); 4003 api::mark_message_as_read($user2->id, $m6); 4004 4005 // Get the non-contacts and the unread message count. 4006 $messages = api::get_non_contacts_with_unread_message_count($user2->id); 4007 $this->assertDebuggingCalled(); 4008 4009 // Check the marked message is not returned in the message count. 4010 ksort($messages); 4011 $this->assertCount(2, $messages); 4012 $messageinfo1 = array_shift($messages); 4013 $messageinfo2 = array_shift($messages); 4014 $this->assertEquals($user1->id, $messageinfo1->id); 4015 $this->assertEquals(3, $messageinfo1->messagecount); 4016 $this->assertEquals($user3->id, $messageinfo2->id); 4017 $this->assertEquals(4, $messageinfo2->messagecount); 4018 4019 // Now, let's populate the database with messages from user2 to user 1. 4020 $this->send_fake_message($user2, $user1); 4021 $this->send_fake_message($user2, $user1); 4022 $messageid = $this->send_fake_message($user2, $user1); 4023 4024 // Send a message that should never be included as the user is a contact. 4025 $this->send_fake_message($user4, $user1); 4026 4027 // Get the non-contacts and the unread message count. 4028 $messages = api::get_non_contacts_with_unread_message_count($user1->id); 4029 $this->assertDebuggingCalled(); 4030 4031 // Confirm the size is correct. 4032 $this->assertCount(1, $messages); 4033 $messageinfo1 = array_shift($messages); 4034 $this->assertEquals($user2->id, $messageinfo1->id); 4035 $this->assertEquals(3, $messageinfo1->messagecount); 4036 4037 // Mark the last message as read. 4038 $m = $DB->get_record('messages', ['id' => $messageid]); 4039 api::mark_message_as_read($user1->id, $m); 4040 4041 // Get the non-contacts and the unread message count. 4042 $messages = api::get_non_contacts_with_unread_message_count($user1->id); 4043 $this->assertDebuggingCalled(); 4044 4045 // Check the marked message is not returned in the message count. 4046 $this->assertCount(1, $messages); 4047 $messageinfo1 = array_shift($messages); 4048 $this->assertEquals($user2->id, $messageinfo1->id); 4049 $this->assertEquals(2, $messageinfo1->messagecount); 4050 } 4051 4052 /** 4053 * Test marking a message as read. 4054 */ 4055 public function test_mark_message_as_read() { 4056 global $DB; 4057 4058 $user1 = self::getDataGenerator()->create_user(); 4059 $user2 = self::getDataGenerator()->create_user(); 4060 4061 $this->send_fake_message($user1, $user2); 4062 $m2id = $this->send_fake_message($user1, $user2); 4063 $this->send_fake_message($user2, $user1); 4064 $m4id = $this->send_fake_message($user2, $user1); 4065 4066 $m2 = $DB->get_record('messages', ['id' => $m2id]); 4067 $m4 = $DB->get_record('messages', ['id' => $m4id]); 4068 api::mark_message_as_read($user2->id, $m2, 11); 4069 api::mark_message_as_read($user1->id, $m4, 12); 4070 4071 // Confirm there are two user actions. 4072 $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC'); 4073 $this->assertEquals(2, count($muas)); 4074 4075 // Confirm they are correct. 4076 $mua1 = array_shift($muas); 4077 $mua2 = array_shift($muas); 4078 4079 // Confirm first action. 4080 $this->assertEquals($user2->id, $mua1->userid); 4081 $this->assertEquals($m2id, $mua1->messageid); 4082 $this->assertEquals(api::MESSAGE_ACTION_READ, $mua1->action); 4083 $this->assertEquals(11, $mua1->timecreated); 4084 4085 // Confirm second action. 4086 $this->assertEquals($user1->id, $mua2->userid); 4087 $this->assertEquals($m4id, $mua2->messageid); 4088 $this->assertEquals(api::MESSAGE_ACTION_READ, $mua2->action); 4089 $this->assertEquals(12, $mua2->timecreated); 4090 } 4091 4092 /** 4093 * Test marking a notification as read. 4094 */ 4095 public function test_mark_notification_as_read() { 4096 global $DB; 4097 4098 $user1 = self::getDataGenerator()->create_user(); 4099 $user2 = self::getDataGenerator()->create_user(); 4100 4101 $this->send_fake_message($user1, $user2, 'Notification 1', 1); 4102 $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1); 4103 $this->send_fake_message($user2, $user1, 'Notification 3', 1); 4104 $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1); 4105 4106 $n2 = $DB->get_record('notifications', ['id' => $n2id]); 4107 $n4 = $DB->get_record('notifications', ['id' => $n4id]); 4108 4109 api::mark_notification_as_read($n2, 11); 4110 api::mark_notification_as_read($n4, 12); 4111 4112 // Retrieve the notifications. 4113 $n2 = $DB->get_record('notifications', ['id' => $n2id]); 4114 $n4 = $DB->get_record('notifications', ['id' => $n4id]); 4115 4116 // Confirm they have been marked as read. 4117 $this->assertEquals(11, $n2->timeread); 4118 $this->assertEquals(12, $n4->timeread); 4119 } 4120 4121 /** 4122 * Test a conversation is not returned if there is none. 4123 */ 4124 public function test_get_conversation_between_users_no_conversation() { 4125 $user1 = self::getDataGenerator()->create_user(); 4126 $user2 = self::getDataGenerator()->create_user(); 4127 4128 $this->assertFalse(api::get_conversation_between_users([$user1->id, $user2->id])); 4129 } 4130 4131 /** 4132 * Test count_conversation_members for non existing conversation. 4133 */ 4134 public function test_count_conversation_members_no_existing_conversation() { 4135 $this->assertEquals(0, 4136 api::count_conversation_members(0)); 4137 } 4138 4139 /** 4140 * Test count_conversation_members for existing conversation. 4141 */ 4142 public function test_count_conversation_members_existing_conversation() { 4143 $user1 = self::getDataGenerator()->create_user(); 4144 $user2 = self::getDataGenerator()->create_user(); 4145 4146 $conversation = api::create_conversation( 4147 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4148 [ 4149 $user1->id, 4150 $user2->id 4151 ] 4152 ); 4153 $conversationid = $conversation->id; 4154 4155 $this->assertEquals(2, 4156 api::count_conversation_members($conversationid)); 4157 } 4158 4159 /** 4160 * Test add_members_to_conversation for an individual conversation. 4161 */ 4162 public function test_add_members_to_individual_conversation() { 4163 $user1 = self::getDataGenerator()->create_user(); 4164 $user2 = self::getDataGenerator()->create_user(); 4165 $user3 = self::getDataGenerator()->create_user(); 4166 4167 $conversation = api::create_conversation( 4168 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4169 [ 4170 $user1->id, 4171 $user2->id 4172 ] 4173 ); 4174 $conversationid = $conversation->id; 4175 4176 $this->expectException('moodle_exception'); 4177 api::add_members_to_conversation([$user3->id], $conversationid); 4178 } 4179 4180 /** 4181 * Test add_members_to_conversation for existing conversation. 4182 */ 4183 public function test_add_members_to_existing_conversation() { 4184 $user1 = self::getDataGenerator()->create_user(); 4185 $user2 = self::getDataGenerator()->create_user(); 4186 $user3 = self::getDataGenerator()->create_user(); 4187 4188 $conversation = api::create_conversation( 4189 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4190 [ 4191 $user1->id, 4192 $user2->id 4193 ] 4194 ); 4195 $conversationid = $conversation->id; 4196 4197 $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid)); 4198 $this->assertEquals(3, 4199 api::count_conversation_members($conversationid)); 4200 } 4201 4202 /** 4203 * Test add_members_to_conversation for non existing conversation. 4204 */ 4205 public function test_add_members_to_no_existing_conversation() { 4206 $user1 = self::getDataGenerator()->create_user(); 4207 4208 // Throw dml_missing_record_exception for non existing conversation. 4209 $this->expectException('dml_missing_record_exception'); 4210 api::add_members_to_conversation([$user1->id], 0); 4211 } 4212 4213 /** 4214 * Test add_member_to_conversation for non existing user. 4215 */ 4216 public function test_add_members_to_no_existing_user() { 4217 $user1 = self::getDataGenerator()->create_user(); 4218 $user2 = self::getDataGenerator()->create_user(); 4219 4220 $conversation = api::create_conversation( 4221 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4222 [ 4223 $user1->id, 4224 $user2->id 4225 ] 4226 ); 4227 $conversationid = $conversation->id; 4228 4229 // Don't throw an error for non existing user, but don't add it as a member. 4230 $this->assertNull(api::add_members_to_conversation([0], $conversationid)); 4231 $this->assertEquals(2, 4232 api::count_conversation_members($conversationid)); 4233 } 4234 4235 /** 4236 * Test add_members_to_conversation for current conversation member. 4237 */ 4238 public function test_add_members_to_current_conversation_member() { 4239 $user1 = self::getDataGenerator()->create_user(); 4240 $user2 = self::getDataGenerator()->create_user(); 4241 4242 $conversation = api::create_conversation( 4243 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4244 [ 4245 $user1->id, 4246 $user2->id 4247 ] 4248 ); 4249 $conversationid = $conversation->id; 4250 4251 // Don't add as a member a user that is already conversation member. 4252 $this->assertNull(api::add_members_to_conversation([$user1->id], $conversationid)); 4253 $this->assertEquals(2, 4254 api::count_conversation_members($conversationid)); 4255 } 4256 4257 /** 4258 * Test add_members_to_conversation for multiple users. 4259 */ 4260 public function test_add_members_for_multiple_users() { 4261 $user1 = self::getDataGenerator()->create_user(); 4262 $user2 = self::getDataGenerator()->create_user(); 4263 $user3 = self::getDataGenerator()->create_user(); 4264 $user4 = self::getDataGenerator()->create_user(); 4265 4266 $conversation = api::create_conversation( 4267 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4268 [ 4269 $user1->id, 4270 $user2->id 4271 ] 4272 ); 4273 $conversationid = $conversation->id; 4274 4275 $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid)); 4276 $this->assertEquals(4, 4277 api::count_conversation_members($conversationid)); 4278 } 4279 4280 /** 4281 * Test add_members_to_conversation for multiple users, included non existing and current conversation members 4282 */ 4283 public function test_add_members_for_multiple_not_valid_users() { 4284 $user1 = self::getDataGenerator()->create_user(); 4285 $user2 = self::getDataGenerator()->create_user(); 4286 $user3 = self::getDataGenerator()->create_user(); 4287 4288 $conversation = api::create_conversation( 4289 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4290 [ 4291 $user1->id, 4292 $user2->id 4293 ] 4294 ); 4295 $conversationid = $conversation->id; 4296 4297 // Don't throw errors, but don't add as members users don't exist or are already conversation members. 4298 $this->assertNull(api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid)); 4299 $this->assertEquals(3, 4300 api::count_conversation_members($conversationid)); 4301 } 4302 4303 /** 4304 * Test remove_members_from_conversation for individual conversation. 4305 */ 4306 public function test_remove_members_from_individual_conversation() { 4307 $user1 = self::getDataGenerator()->create_user(); 4308 $user2 = self::getDataGenerator()->create_user(); 4309 4310 $conversation = api::create_conversation( 4311 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4312 [ 4313 $user1->id, 4314 $user2->id 4315 ] 4316 ); 4317 $conversationid = $conversation->id; 4318 4319 $this->expectException('moodle_exception'); 4320 api::remove_members_from_conversation([$user1->id], $conversationid); 4321 } 4322 4323 /** 4324 * Test remove_members_from_conversation for existing conversation. 4325 */ 4326 public function test_remove_members_from_existing_conversation() { 4327 $user1 = self::getDataGenerator()->create_user(); 4328 $user2 = self::getDataGenerator()->create_user(); 4329 4330 $conversation = api::create_conversation( 4331 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4332 [ 4333 $user1->id, 4334 $user2->id 4335 ] 4336 ); 4337 $conversationid = $conversation->id; 4338 4339 $this->assertNull(api::remove_members_from_conversation([$user1->id], $conversationid)); 4340 $this->assertEquals(1, 4341 api::count_conversation_members($conversationid)); 4342 } 4343 4344 /** 4345 * Test remove_members_from_conversation for non existing conversation. 4346 */ 4347 public function test_remove_members_from_no_existing_conversation() { 4348 $user1 = self::getDataGenerator()->create_user(); 4349 4350 // Throw dml_missing_record_exception for non existing conversation. 4351 $this->expectException('dml_missing_record_exception'); 4352 api::remove_members_from_conversation([$user1->id], 0); 4353 } 4354 4355 /** 4356 * Test remove_members_from_conversation for non existing user. 4357 */ 4358 public function test_remove_members_for_no_existing_user() { 4359 $user1 = self::getDataGenerator()->create_user(); 4360 $user2 = self::getDataGenerator()->create_user(); 4361 4362 $conversation = api::create_conversation( 4363 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4364 [ 4365 $user1->id, 4366 $user2->id 4367 ] 4368 ); 4369 $conversationid = $conversation->id; 4370 4371 $this->assertNull(api::remove_members_from_conversation([0], $conversationid)); 4372 $this->assertEquals(2, 4373 api::count_conversation_members($conversationid)); 4374 } 4375 4376 /** 4377 * Test remove_members_from_conversation for multiple users. 4378 */ 4379 public function test_remove_members_for_multiple_users() { 4380 $user1 = self::getDataGenerator()->create_user(); 4381 $user2 = self::getDataGenerator()->create_user(); 4382 $user3 = self::getDataGenerator()->create_user(); 4383 $user4 = self::getDataGenerator()->create_user(); 4384 4385 $conversation = api::create_conversation( 4386 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4387 [ 4388 $user1->id, 4389 $user2->id 4390 ] 4391 ); 4392 $conversationid = $conversation->id; 4393 4394 $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid)); 4395 $this->assertNull(api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid)); 4396 $this->assertEquals(2, 4397 api::count_conversation_members($conversationid)); 4398 } 4399 4400 /** 4401 * Test remove_members_from_conversation for multiple non valid users. 4402 */ 4403 public function test_remove_members_for_multiple_no_valid_users() { 4404 $user1 = self::getDataGenerator()->create_user(); 4405 $user2 = self::getDataGenerator()->create_user(); 4406 $user3 = self::getDataGenerator()->create_user(); 4407 $user4 = self::getDataGenerator()->create_user(); 4408 4409 $conversation = api::create_conversation( 4410 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4411 [ 4412 $user1->id, 4413 $user2->id 4414 ] 4415 ); 4416 $conversationid = $conversation->id; 4417 4418 $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid)); 4419 $this->assertNull( 4420 api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid) 4421 ); 4422 $this->assertEquals(1, 4423 api::count_conversation_members($conversationid)); 4424 } 4425 4426 /** 4427 * Test count_conversation_members for empty conversation. 4428 */ 4429 public function test_count_conversation_members_empty_conversation() { 4430 $user1 = self::getDataGenerator()->create_user(); 4431 $user2 = self::getDataGenerator()->create_user(); 4432 4433 $conversation = api::create_conversation( 4434 api::MESSAGE_CONVERSATION_TYPE_GROUP, 4435 [ 4436 $user1->id, 4437 $user2->id 4438 ] 4439 ); 4440 $conversationid = $conversation->id; 4441 4442 $this->assertNull(api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid)); 4443 4444 $this->assertEquals(0, 4445 api::count_conversation_members($conversationid)); 4446 } 4447 4448 /** 4449 * Test can create a contact request. 4450 */ 4451 public function test_can_create_contact_request() { 4452 global $CFG; 4453 4454 $user1 = self::getDataGenerator()->create_user(); 4455 $user2 = self::getDataGenerator()->create_user(); 4456 4457 // Disable messaging. 4458 $CFG->messaging = 0; 4459 $this->assertFalse(api::can_create_contact($user1->id, $user2->id)); 4460 4461 // Re-enable messaging. 4462 $CFG->messaging = 1; 4463 4464 // Allow users to message anyone site-wide. 4465 $CFG->messagingallusers = 1; 4466 $this->assertTrue(api::can_create_contact($user1->id, $user2->id)); 4467 4468 // Disallow users from messaging anyone site-wide. 4469 $CFG->messagingallusers = 0; 4470 $this->assertFalse(api::can_create_contact($user1->id, $user2->id)); 4471 4472 // Put the users in the same course so a contact request should be possible. 4473 $course = self::getDataGenerator()->create_course(); 4474 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 4475 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 4476 $this->assertTrue(api::can_create_contact($user1->id, $user2->id)); 4477 } 4478 4479 /** 4480 * Test creating a contact request. 4481 */ 4482 public function test_create_contact_request() { 4483 global $DB; 4484 4485 $user1 = self::getDataGenerator()->create_user(); 4486 $user2 = self::getDataGenerator()->create_user(); 4487 4488 $sink = $this->redirectMessages(); 4489 $request = api::create_contact_request($user1->id, $user2->id); 4490 $messages = $sink->get_messages(); 4491 $sink->close(); 4492 // Test customdata. 4493 $customdata = json_decode($messages[0]->customdata); 4494 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 4495 $this->assertObjectHasAttribute('actionbuttons', $customdata); 4496 $this->assertCount(2, (array) $customdata->actionbuttons); 4497 4498 $this->assertEquals($user1->id, $request->userid); 4499 $this->assertEquals($user2->id, $request->requesteduserid); 4500 } 4501 4502 /** 4503 * Test confirming a contact request. 4504 */ 4505 public function test_confirm_contact_request() { 4506 global $DB; 4507 4508 $user1 = self::getDataGenerator()->create_user(); 4509 $user2 = self::getDataGenerator()->create_user(); 4510 4511 api::create_contact_request($user1->id, $user2->id); 4512 4513 api::confirm_contact_request($user1->id, $user2->id); 4514 4515 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 4516 4517 $contact = $DB->get_records('message_contacts'); 4518 4519 $this->assertCount(1, $contact); 4520 4521 $contact = reset($contact); 4522 4523 $this->assertEquals($user1->id, $contact->userid); 4524 $this->assertEquals($user2->id, $contact->contactid); 4525 } 4526 4527 /** 4528 * Test declining a contact request. 4529 */ 4530 public function test_decline_contact_request() { 4531 global $DB; 4532 4533 $user1 = self::getDataGenerator()->create_user(); 4534 $user2 = self::getDataGenerator()->create_user(); 4535 4536 api::create_contact_request($user1->id, $user2->id); 4537 4538 api::decline_contact_request($user1->id, $user2->id); 4539 4540 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 4541 $this->assertEquals(0, $DB->count_records('message_contacts')); 4542 } 4543 4544 /** 4545 * Test retrieving contact requests. 4546 */ 4547 public function test_get_contact_requests() { 4548 global $PAGE; 4549 4550 $user1 = self::getDataGenerator()->create_user(); 4551 $user2 = self::getDataGenerator()->create_user(); 4552 $user3 = self::getDataGenerator()->create_user(); 4553 4554 // Block one user, their request should not show up. 4555 api::block_user($user1->id, $user3->id); 4556 4557 api::create_contact_request($user2->id, $user1->id); 4558 api::create_contact_request($user3->id, $user1->id); 4559 4560 $requests = api::get_contact_requests($user1->id); 4561 4562 $this->assertCount(1, $requests); 4563 4564 $request = reset($requests); 4565 $userpicture = new \user_picture($user2); 4566 $profileimageurl = $userpicture->get_url($PAGE)->out(false); 4567 4568 $this->assertEquals($user2->id, $request->id); 4569 $this->assertEquals(fullname($user2), $request->fullname); 4570 $this->assertObjectHasAttribute('profileimageurl', $request); 4571 $this->assertObjectHasAttribute('profileimageurlsmall', $request); 4572 $this->assertObjectHasAttribute('isonline', $request); 4573 $this->assertObjectHasAttribute('showonlinestatus', $request); 4574 $this->assertObjectHasAttribute('isblocked', $request); 4575 $this->assertObjectHasAttribute('iscontact', $request); 4576 } 4577 4578 /** 4579 * Test the get_contact_requests() function when the user has blocked the sender of the request. 4580 */ 4581 public function test_get_contact_requests_blocked_sender() { 4582 $user1 = self::getDataGenerator()->create_user(); 4583 $user2 = self::getDataGenerator()->create_user(); 4584 4585 // User1 blocks User2. 4586 api::block_user($user1->id, $user2->id); 4587 4588 // User2 tries to add User1 as a contact. 4589 api::create_contact_request($user2->id, $user1->id); 4590 4591 // Verify we don't see the contact request from the blocked user User2 in the requests for User1. 4592 $requests = api::get_contact_requests($user1->id); 4593 $this->assertEmpty($requests); 4594 } 4595 4596 /** 4597 * Test getting contact requests when there are none. 4598 */ 4599 public function test_get_contact_requests_no_requests() { 4600 $this->resetAfterTest(); 4601 4602 $user1 = self::getDataGenerator()->create_user(); 4603 4604 $requests = api::get_contact_requests($user1->id); 4605 4606 $this->assertEmpty($requests); 4607 } 4608 4609 /** 4610 * Test getting contact requests with limits. 4611 */ 4612 public function test_get_contact_requests_with_limits() { 4613 $this->resetAfterTest(); 4614 4615 $user1 = self::getDataGenerator()->create_user(); 4616 $user2 = self::getDataGenerator()->create_user(); 4617 $user3 = self::getDataGenerator()->create_user(); 4618 4619 api::create_contact_request($user2->id, $user1->id); 4620 api::create_contact_request($user3->id, $user1->id); 4621 4622 $requests = api::get_contact_requests($user1->id, 0, 1); 4623 4624 $this->assertCount(1, $requests); 4625 } 4626 4627 /** 4628 * Test adding contacts. 4629 */ 4630 public function test_add_contact() { 4631 global $DB; 4632 4633 $user1 = self::getDataGenerator()->create_user(); 4634 $user2 = self::getDataGenerator()->create_user(); 4635 4636 api::add_contact($user1->id, $user2->id); 4637 4638 $contact = $DB->get_records('message_contacts'); 4639 4640 $this->assertCount(1, $contact); 4641 4642 $contact = reset($contact); 4643 4644 $this->assertEquals($user1->id, $contact->userid); 4645 $this->assertEquals($user2->id, $contact->contactid); 4646 } 4647 4648 /** 4649 * Test removing contacts. 4650 */ 4651 public function test_remove_contact() { 4652 global $DB; 4653 4654 $user1 = self::getDataGenerator()->create_user(); 4655 $user2 = self::getDataGenerator()->create_user(); 4656 4657 api::add_contact($user1->id, $user2->id); 4658 api::remove_contact($user1->id, $user2->id); 4659 4660 $this->assertEquals(0, $DB->count_records('message_contacts')); 4661 } 4662 4663 /** 4664 * Test blocking users. 4665 */ 4666 public function test_block_user() { 4667 global $DB; 4668 4669 $user1 = self::getDataGenerator()->create_user(); 4670 $user2 = self::getDataGenerator()->create_user(); 4671 4672 api::block_user($user1->id, $user2->id); 4673 4674 $blockedusers = $DB->get_records('message_users_blocked'); 4675 4676 $this->assertCount(1, $blockedusers); 4677 4678 $blockeduser = reset($blockedusers); 4679 4680 $this->assertEquals($user1->id, $blockeduser->userid); 4681 $this->assertEquals($user2->id, $blockeduser->blockeduserid); 4682 } 4683 4684 /** 4685 * Test unblocking users. 4686 */ 4687 public function test_unblock_user() { 4688 global $DB; 4689 4690 $user1 = self::getDataGenerator()->create_user(); 4691 $user2 = self::getDataGenerator()->create_user(); 4692 4693 api::block_user($user1->id, $user2->id); 4694 api::unblock_user($user1->id, $user2->id); 4695 4696 $this->assertEquals(0, $DB->count_records('message_users_blocked')); 4697 } 4698 4699 /** 4700 * Test muting a conversation. 4701 */ 4702 public function test_mute_conversation() { 4703 global $DB; 4704 4705 $user1 = self::getDataGenerator()->create_user(); 4706 $user2 = self::getDataGenerator()->create_user(); 4707 4708 $conversation = api::create_conversation( 4709 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4710 [ 4711 $user1->id, 4712 $user2->id 4713 ] 4714 ); 4715 $conversationid = $conversation->id; 4716 4717 api::mute_conversation($user1->id, $conversationid); 4718 4719 $mutedconversation = $DB->get_records('message_conversation_actions'); 4720 4721 $this->assertCount(1, $mutedconversation); 4722 4723 $mutedconversation = reset($mutedconversation); 4724 4725 $this->assertEquals($user1->id, $mutedconversation->userid); 4726 $this->assertEquals($conversationid, $mutedconversation->conversationid); 4727 $this->assertEquals(api::CONVERSATION_ACTION_MUTED, $mutedconversation->action); 4728 } 4729 4730 /** 4731 * Test unmuting a conversation. 4732 */ 4733 public function test_unmute_conversation() { 4734 global $DB; 4735 4736 $user1 = self::getDataGenerator()->create_user(); 4737 $user2 = self::getDataGenerator()->create_user(); 4738 4739 $conversation = api::create_conversation( 4740 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4741 [ 4742 $user1->id, 4743 $user2->id 4744 ] 4745 ); 4746 $conversationid = $conversation->id; 4747 4748 api::mute_conversation($user1->id, $conversationid); 4749 api::unmute_conversation($user1->id, $conversationid); 4750 4751 $this->assertEquals(0, $DB->count_records('message_conversation_actions')); 4752 } 4753 4754 /** 4755 * Test if a conversation is muted. 4756 */ 4757 public function test_is_conversation_muted() { 4758 $user1 = self::getDataGenerator()->create_user(); 4759 $user2 = self::getDataGenerator()->create_user(); 4760 4761 $conversation = api::create_conversation( 4762 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4763 [ 4764 $user1->id, 4765 $user2->id 4766 ] 4767 ); 4768 $conversationid = $conversation->id; 4769 4770 $this->assertFalse(api::is_conversation_muted($user1->id, $conversationid)); 4771 4772 api::mute_conversation($user1->id, $conversationid); 4773 4774 $this->assertTrue(api::is_conversation_muted($user1->id, $conversationid)); 4775 } 4776 4777 /** 4778 * Test is contact check. 4779 */ 4780 public function test_is_contact() { 4781 $user1 = self::getDataGenerator()->create_user(); 4782 $user2 = self::getDataGenerator()->create_user(); 4783 $user3 = self::getDataGenerator()->create_user(); 4784 4785 api::add_contact($user1->id, $user2->id); 4786 4787 $this->assertTrue(api::is_contact($user1->id, $user2->id)); 4788 $this->assertTrue(api::is_contact($user2->id, $user1->id)); 4789 $this->assertFalse(api::is_contact($user2->id, $user3->id)); 4790 } 4791 4792 /** 4793 * Test get contact. 4794 */ 4795 public function test_get_contact() { 4796 $user1 = self::getDataGenerator()->create_user(); 4797 $user2 = self::getDataGenerator()->create_user(); 4798 4799 api::add_contact($user1->id, $user2->id); 4800 4801 $contact = api::get_contact($user1->id, $user2->id); 4802 4803 $this->assertEquals($user1->id, $contact->userid); 4804 $this->assertEquals($user2->id, $contact->contactid); 4805 } 4806 4807 /** 4808 * Test is blocked checked. 4809 */ 4810 public function test_is_blocked() { 4811 $user1 = self::getDataGenerator()->create_user(); 4812 $user2 = self::getDataGenerator()->create_user(); 4813 4814 $this->assertFalse(api::is_blocked($user1->id, $user2->id)); 4815 $this->assertFalse(api::is_blocked($user2->id, $user1->id)); 4816 4817 api::block_user($user1->id, $user2->id); 4818 4819 $this->assertTrue(api::is_blocked($user1->id, $user2->id)); 4820 $this->assertFalse(api::is_blocked($user2->id, $user1->id)); 4821 } 4822 4823 /** 4824 * Test the contact request exist check. 4825 */ 4826 public function test_does_contact_request_exist() { 4827 $user1 = self::getDataGenerator()->create_user(); 4828 $user2 = self::getDataGenerator()->create_user(); 4829 4830 $this->assertFalse(api::does_contact_request_exist($user1->id, $user2->id)); 4831 $this->assertFalse(api::does_contact_request_exist($user2->id, $user1->id)); 4832 4833 api::create_contact_request($user1->id, $user2->id); 4834 4835 $this->assertTrue(api::does_contact_request_exist($user1->id, $user2->id)); 4836 $this->assertTrue(api::does_contact_request_exist($user2->id, $user1->id)); 4837 } 4838 4839 /** 4840 * Test the get_received_contact_requests_count() function. 4841 */ 4842 public function test_get_received_contact_requests_count() { 4843 $user1 = self::getDataGenerator()->create_user(); 4844 $user2 = self::getDataGenerator()->create_user(); 4845 $user3 = self::getDataGenerator()->create_user(); 4846 $user4 = self::getDataGenerator()->create_user(); 4847 4848 $this->assertEquals(0, api::get_received_contact_requests_count($user1->id)); 4849 4850 api::create_contact_request($user2->id, $user1->id); 4851 4852 $this->assertEquals(1, api::get_received_contact_requests_count($user1->id)); 4853 4854 api::create_contact_request($user3->id, $user1->id); 4855 4856 $this->assertEquals(2, api::get_received_contact_requests_count($user1->id)); 4857 4858 api::create_contact_request($user1->id, $user4->id); 4859 // Function should ignore sent requests. 4860 $this->assertEquals(2, api::get_received_contact_requests_count($user1->id)); 4861 } 4862 4863 /** 4864 * Test the get_received_contact_requests_count() function when the user has blocked the sender of the request. 4865 */ 4866 public function test_get_received_contact_requests_count_blocked_sender() { 4867 $user1 = self::getDataGenerator()->create_user(); 4868 $user2 = self::getDataGenerator()->create_user(); 4869 4870 // User1 blocks User2. 4871 api::block_user($user1->id, $user2->id); 4872 4873 // User2 tries to add User1 as a contact. 4874 api::create_contact_request($user2->id, $user1->id); 4875 4876 // Verify we don't see the contact request from the blocked user User2 in the count for User1. 4877 $this->assertEquals(0, api::get_received_contact_requests_count($user1->id)); 4878 } 4879 4880 /** 4881 * Test the get_contact_requests_between_users() function. 4882 */ 4883 public function test_get_contact_requests_between_users() { 4884 $user1 = self::getDataGenerator()->create_user(); 4885 $user2 = self::getDataGenerator()->create_user(); 4886 $user3 = self::getDataGenerator()->create_user(); 4887 $user4 = self::getDataGenerator()->create_user(); 4888 4889 $this->assertEquals([], api::get_contact_requests_between_users($user1->id, $user2->id)); 4890 4891 $request1 = api::create_contact_request($user2->id, $user1->id); 4892 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4893 $results = array_values($results); 4894 4895 $this->assertCount(1, $results); 4896 $result = $results[0]; 4897 $this->assertEquals($request1->id, $result->id); 4898 4899 $request2 = api::create_contact_request($user1->id, $user2->id); 4900 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4901 $results = array_values($results); 4902 4903 $this->assertCount(2, $results); 4904 $actual = [(int) $results[0]->id, (int) $results[1]->id]; 4905 $expected = [(int) $request1->id, (int) $request2->id]; 4906 4907 sort($actual); 4908 sort($expected); 4909 4910 $this->assertEquals($expected, $actual); 4911 4912 // Request from a different user. 4913 api::create_contact_request($user3->id, $user1->id); 4914 4915 $results = api::get_contact_requests_between_users($user1->id, $user2->id); 4916 $results = array_values($results); 4917 4918 $this->assertCount(2, $results); 4919 $actual = [(int) $results[0]->id, (int) $results[1]->id]; 4920 $expected = [(int) $request1->id, (int) $request2->id]; 4921 4922 sort($actual); 4923 sort($expected); 4924 4925 $this->assertEquals($expected, $actual); 4926 } 4927 4928 /** 4929 * Test the user in conversation check. 4930 */ 4931 public function test_is_user_in_conversation() { 4932 $user1 = self::getDataGenerator()->create_user(); 4933 $user2 = 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->assertTrue(api::is_user_in_conversation($user1->id, $conversationid)); 4945 } 4946 4947 /** 4948 * Test the user in conversation check when they are not. 4949 */ 4950 public function test_is_user_in_conversation_when_not() { 4951 $user1 = self::getDataGenerator()->create_user(); 4952 $user2 = self::getDataGenerator()->create_user(); 4953 $user3 = self::getDataGenerator()->create_user(); 4954 4955 $conversation = api::create_conversation( 4956 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 4957 [ 4958 $user1->id, 4959 $user2->id 4960 ] 4961 ); 4962 $conversationid = $conversation->id; 4963 4964 $this->assertFalse(api::is_user_in_conversation($user3->id, $conversationid)); 4965 } 4966 4967 /** 4968 * Test can create a group conversation. 4969 */ 4970 public function test_can_create_group_conversation() { 4971 global $CFG; 4972 4973 $student = self::getDataGenerator()->create_user(); 4974 $teacher = self::getDataGenerator()->create_user(); 4975 $course = self::getDataGenerator()->create_course(); 4976 4977 $coursecontext = \context_course::instance($course->id); 4978 4979 $this->getDataGenerator()->enrol_user($student->id, $course->id); 4980 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher'); 4981 4982 // Disable messaging. 4983 $CFG->messaging = 0; 4984 $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext)); 4985 4986 // Re-enable messaging. 4987 $CFG->messaging = 1; 4988 4989 // Student shouldn't be able to. 4990 $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext)); 4991 4992 // Teacher should. 4993 $this->assertTrue(api::can_create_group_conversation($teacher->id, $coursecontext)); 4994 } 4995 4996 /** 4997 * Test creating an individual conversation. 4998 */ 4999 public function test_create_conversation_individual() { 5000 $user1 = self::getDataGenerator()->create_user(); 5001 $user2 = self::getDataGenerator()->create_user(); 5002 5003 $conversation = api::create_conversation( 5004 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5005 [ 5006 $user1->id, 5007 $user2->id 5008 ], 5009 'A conversation name' 5010 ); 5011 5012 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type); 5013 $this->assertEquals('A conversation name', $conversation->name); 5014 $this->assertEquals(helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash); 5015 5016 $this->assertCount(2, $conversation->members); 5017 5018 $member1 = array_shift($conversation->members); 5019 $member2 = array_shift($conversation->members); 5020 5021 $this->assertEquals($user1->id, $member1->userid); 5022 $this->assertEquals($conversation->id, $member1->conversationid); 5023 5024 $this->assertEquals($user2->id, $member2->userid); 5025 $this->assertEquals($conversation->id, $member2->conversationid); 5026 } 5027 5028 /** 5029 * Test creating a group conversation. 5030 */ 5031 public function test_create_conversation_group() { 5032 $user1 = self::getDataGenerator()->create_user(); 5033 $user2 = self::getDataGenerator()->create_user(); 5034 $user3 = self::getDataGenerator()->create_user(); 5035 5036 $conversation = api::create_conversation( 5037 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5038 [ 5039 $user1->id, 5040 $user2->id, 5041 $user3->id 5042 ], 5043 'A conversation name' 5044 ); 5045 5046 $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type); 5047 $this->assertEquals('A conversation name', $conversation->name); 5048 $this->assertNull($conversation->convhash); 5049 5050 $this->assertCount(3, $conversation->members); 5051 5052 $member1 = array_shift($conversation->members); 5053 $member2 = array_shift($conversation->members); 5054 $member3 = array_shift($conversation->members); 5055 5056 $this->assertEquals($user1->id, $member1->userid); 5057 $this->assertEquals($conversation->id, $member1->conversationid); 5058 5059 $this->assertEquals($user2->id, $member2->userid); 5060 $this->assertEquals($conversation->id, $member2->conversationid); 5061 5062 $this->assertEquals($user3->id, $member3->userid); 5063 $this->assertEquals($conversation->id, $member3->conversationid); 5064 } 5065 5066 /** 5067 * Test creating an invalid conversation. 5068 */ 5069 public function test_create_conversation_invalid() { 5070 $this->expectException('moodle_exception'); 5071 api::create_conversation(3, [1, 2, 3]); 5072 } 5073 5074 /** 5075 * Test creating an individual conversation with too many members. 5076 */ 5077 public function test_create_conversation_individual_too_many_members() { 5078 $this->expectException('moodle_exception'); 5079 api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]); 5080 } 5081 5082 /** 5083 * Test create message conversation with area. 5084 */ 5085 public function test_create_conversation_with_area() { 5086 $contextid = 111; 5087 $itemid = 222; 5088 $name = 'Name of conversation'; 5089 $conversation = api::create_conversation( 5090 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5091 [], 5092 $name, 5093 api::MESSAGE_CONVERSATION_DISABLED, 5094 'core_group', 5095 'groups', 5096 $itemid, 5097 $contextid 5098 ); 5099 5100 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5101 $this->assertEquals('core_group', $conversation->component); 5102 $this->assertEquals('groups', $conversation->itemtype); 5103 $this->assertEquals($itemid, $conversation->itemid); 5104 $this->assertEquals($contextid, $conversation->contextid); 5105 } 5106 5107 /** 5108 * Test get_conversation_by_area. 5109 */ 5110 public function test_get_conversation_by_area() { 5111 $contextid = 111; 5112 $itemid = 222; 5113 $name = 'Name of conversation'; 5114 $createconversation = api::create_conversation( 5115 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5116 [], 5117 $name, 5118 api::MESSAGE_CONVERSATION_DISABLED, 5119 'core_group', 5120 'groups', 5121 $itemid, 5122 $contextid 5123 ); 5124 $conversation = api::get_conversation_by_area('core_group', 'groups', $itemid, $contextid); 5125 5126 $this->assertEquals($createconversation->id, $conversation->id); 5127 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5128 $this->assertEquals('core_group', $conversation->component); 5129 $this->assertEquals('groups', $conversation->itemtype); 5130 $this->assertEquals($itemid, $conversation->itemid); 5131 $this->assertEquals($contextid, $conversation->contextid); 5132 } 5133 5134 /** 5135 * Test enable_conversation. 5136 */ 5137 public function test_enable_conversation() { 5138 global $DB; 5139 5140 $name = 'Name of conversation'; 5141 5142 $conversation = api::create_conversation( 5143 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5144 [], 5145 $name, 5146 api::MESSAGE_CONVERSATION_DISABLED 5147 ); 5148 5149 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled); 5150 api::enable_conversation($conversation->id); 5151 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]); 5152 $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversationenabled); 5153 } 5154 5155 /** 5156 * Test disable_conversation. 5157 */ 5158 public function test_disable_conversation() { 5159 global $DB; 5160 5161 $name = 'Name of conversation'; 5162 5163 $conversation = api::create_conversation( 5164 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5165 [], 5166 $name, 5167 api::MESSAGE_CONVERSATION_ENABLED 5168 ); 5169 5170 $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversation->enabled); 5171 api::disable_conversation($conversation->id); 5172 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]); 5173 $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversationenabled); 5174 } 5175 5176 /** 5177 * Test update_conversation_name. 5178 */ 5179 public function test_update_conversation_name() { 5180 global $DB; 5181 5182 $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, []); 5183 5184 $newname = 'New name of conversation'; 5185 api::update_conversation_name($conversation->id, $newname); 5186 5187 $this->assertEquals( 5188 $newname, 5189 $DB->get_field('message_conversations', 'name', ['id' => $conversation->id]) 5190 ); 5191 } 5192 5193 5194 /** 5195 * Test an empty array returned when no args given. 5196 */ 5197 public function test_get_individual_conversations_between_users_no_user_sets() { 5198 $this->assertEmpty(\core_message\api::get_individual_conversations_between_users([])); 5199 $this->assertDebuggingCalled(); 5200 } 5201 5202 /** 5203 * Test a conversation is not returned if there is none. 5204 */ 5205 public function test_get_individual_conversations_between_users_no_conversation() { 5206 $generator = $this->getDataGenerator(); 5207 $user1 = $generator->create_user(); 5208 $user2 = $generator->create_user(); 5209 5210 $this->assertEquals( 5211 [null], 5212 \core_message\api::get_individual_conversations_between_users([[$user1->id, $user2->id]]) 5213 ); 5214 $this->assertDebuggingCalled(); 5215 } 5216 5217 /** 5218 * Test the result set includes null if there is no conversation between users. 5219 */ 5220 public function test_get_individual_conversations_between_users_partial_conversations() { 5221 $generator = $this->getDataGenerator(); 5222 $user1 = $generator->create_user(); 5223 $user2 = $generator->create_user(); 5224 $user3 = $generator->create_user(); 5225 $type = \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 5226 5227 $conversation1 = \core_message\api::create_conversation($type, [$user1->id, $user2->id]); 5228 $conversation2 = \core_message\api::create_conversation($type, [$user1->id, $user3->id]); 5229 5230 $results = \core_message\api::get_individual_conversations_between_users([ 5231 [$user1->id, $user2->id], 5232 [$user2->id, $user3->id], 5233 [$user1->id, $user3->id] 5234 ]); 5235 $this->assertDebuggingCalled(); 5236 5237 $result = array_map(function($result) { 5238 if ($result) { 5239 return $result->id; 5240 } else { 5241 return $result; 5242 } 5243 }, $results); 5244 5245 $this->assertEquals( 5246 [$conversation1->id, null, $conversation2->id], 5247 $result 5248 ); 5249 } 5250 5251 /** 5252 * Test all conversations are returned if each set has a conversation. 5253 */ 5254 public function test_get_individual_conversations_between_users_all_conversations() { 5255 $generator = $this->getDataGenerator(); 5256 $user1 = $generator->create_user(); 5257 $user2 = $generator->create_user(); 5258 $user3 = $generator->create_user(); 5259 $type = \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 5260 5261 $conversation1 = \core_message\api::create_conversation($type, [$user1->id, $user2->id]); 5262 $conversation2 = \core_message\api::create_conversation($type, [$user2->id, $user3->id]); 5263 $conversation3 = \core_message\api::create_conversation($type, [$user1->id, $user3->id]); 5264 5265 $results = \core_message\api::get_individual_conversations_between_users([ 5266 [$user1->id, $user2->id], 5267 [$user2->id, $user3->id], 5268 [$user1->id, $user3->id] 5269 ]); 5270 $this->assertDebuggingCalled(); 5271 5272 $result = array_map(function($result) { 5273 if ($result) { 5274 return $result->id; 5275 } else { 5276 return $result; 5277 } 5278 }, $results); 5279 5280 $this->assertEquals( 5281 [$conversation1->id, $conversation2->id, $conversation3->id], 5282 $result 5283 ); 5284 } 5285 5286 /** 5287 * Test that the results are ordered to match the order of the parameters. 5288 */ 5289 public function test_get_individual_conversations_between_users_ordering() { 5290 $generator = $this->getDataGenerator(); 5291 $user1 = $generator->create_user(); 5292 $user2 = $generator->create_user(); 5293 $user3 = $generator->create_user(); 5294 $type = \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 5295 5296 $conversation1 = \core_message\api::create_conversation($type, [$user1->id, $user2->id]); 5297 $conversation2 = \core_message\api::create_conversation($type, [$user2->id, $user3->id]); 5298 $conversation3 = \core_message\api::create_conversation($type, [$user1->id, $user3->id]); 5299 5300 $results = \core_message\api::get_individual_conversations_between_users([ 5301 [$user1->id, $user2->id], 5302 [$user2->id, $user3->id], 5303 [$user1->id, $user3->id] 5304 ]); 5305 $this->assertDebuggingCalled(); 5306 5307 $result = array_map(function($result) { 5308 if ($result) { 5309 return $result->id; 5310 } else { 5311 return $result; 5312 } 5313 }, $results); 5314 5315 $this->assertEquals( 5316 [$conversation1->id, $conversation2->id, $conversation3->id], 5317 $result 5318 ); 5319 5320 $results = \core_message\api::get_individual_conversations_between_users([ 5321 [$user2->id, $user3->id], 5322 [$user1->id, $user2->id], 5323 [$user1->id, $user3->id] 5324 ]); 5325 $this->assertDebuggingCalled(); 5326 5327 $result = array_map(function($result) { 5328 if ($result) { 5329 return $result->id; 5330 } else { 5331 return $result; 5332 } 5333 }, $results); 5334 5335 $this->assertEquals( 5336 [$conversation2->id, $conversation1->id, $conversation3->id], 5337 $result 5338 ); 5339 } 5340 5341 /** 5342 * Test returning members in a conversation with no contact requests. 5343 */ 5344 public function test_get_conversation_members() { 5345 $lastaccess = new \stdClass(); 5346 $lastaccess->lastaccess = time(); 5347 5348 $user1 = self::getDataGenerator()->create_user($lastaccess); 5349 $user2 = self::getDataGenerator()->create_user(); 5350 $user3 = self::getDataGenerator()->create_user(); 5351 5352 // This user will not be in the conversation, but a contact request will exist for them. 5353 $user4 = self::getDataGenerator()->create_user(); 5354 5355 // Add some contact requests. 5356 api::create_contact_request($user1->id, $user3->id); 5357 api::create_contact_request($user1->id, $user4->id); 5358 api::create_contact_request($user2->id, $user3->id); 5359 5360 // User 1 and 2 are already contacts. 5361 api::add_contact($user1->id, $user2->id); 5362 5363 // User 1 has blocked user 3. 5364 api::block_user($user1->id, $user3->id); 5365 $conversation = api::create_conversation( 5366 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5367 [ 5368 $user1->id, 5369 $user2->id, 5370 $user3->id 5371 ] 5372 ); 5373 $conversationid = $conversation->id; 5374 $members = api::get_conversation_members($user1->id, $conversationid, false); 5375 5376 // Sort them by id. 5377 ksort($members); 5378 $this->assertCount(3, $members); 5379 $member1 = array_shift($members); 5380 $member2 = array_shift($members); 5381 $member3 = array_shift($members); 5382 5383 // Confirm the standard fields are OK. 5384 $this->assertEquals($user1->id, $member1->id); 5385 $this->assertEquals(fullname($user1), $member1->fullname); 5386 $this->assertEquals(true, $member1->isonline); 5387 $this->assertEquals(true, $member1->showonlinestatus); 5388 $this->assertEquals(false, $member1->iscontact); 5389 $this->assertEquals(false, $member1->isblocked); 5390 $this->assertObjectHasAttribute('contactrequests', $member1); 5391 $this->assertEmpty($member1->contactrequests); 5392 5393 $this->assertEquals($user2->id, $member2->id); 5394 $this->assertEquals(fullname($user2), $member2->fullname); 5395 $this->assertEquals(false, $member2->isonline); 5396 $this->assertEquals(true, $member2->showonlinestatus); 5397 $this->assertEquals(true, $member2->iscontact); 5398 $this->assertEquals(false, $member2->isblocked); 5399 $this->assertObjectHasAttribute('contactrequests', $member2); 5400 $this->assertEmpty($member2->contactrequests); 5401 5402 $this->assertEquals($user3->id, $member3->id); 5403 $this->assertEquals(fullname($user3), $member3->fullname); 5404 $this->assertEquals(false, $member3->isonline); 5405 $this->assertEquals(true, $member3->showonlinestatus); 5406 $this->assertEquals(false, $member3->iscontact); 5407 $this->assertEquals(true, $member3->isblocked); 5408 $this->assertObjectHasAttribute('contactrequests', $member3); 5409 $this->assertEmpty($member3->contactrequests); 5410 } 5411 5412 /** 5413 * Test returning members in a conversation with contact requests. 5414 */ 5415 public function test_get_conversation_members_with_contact_requests() { 5416 $lastaccess = new \stdClass(); 5417 $lastaccess->lastaccess = time(); 5418 5419 $user1 = self::getDataGenerator()->create_user($lastaccess); 5420 $user2 = self::getDataGenerator()->create_user(); 5421 $user3 = self::getDataGenerator()->create_user(); 5422 5423 // This user will not be in the conversation, but a contact request will exist for them. 5424 $user4 = self::getDataGenerator()->create_user(); 5425 // Add some contact requests. 5426 api::create_contact_request($user1->id, $user2->id); 5427 api::create_contact_request($user1->id, $user3->id); 5428 api::create_contact_request($user1->id, $user4->id); 5429 api::create_contact_request($user2->id, $user3->id); 5430 5431 // User 1 and 2 are already contacts. 5432 api::add_contact($user1->id, $user2->id); 5433 // User 1 has blocked user 3. 5434 api::block_user($user1->id, $user3->id); 5435 5436 $conversation = api::create_conversation( 5437 api::MESSAGE_CONVERSATION_TYPE_GROUP, 5438 [ 5439 $user1->id, 5440 $user2->id, 5441 $user3->id 5442 ] 5443 ); 5444 $conversationid = $conversation->id; 5445 5446 $members = api::get_conversation_members($user1->id, $conversationid, true); 5447 5448 // Sort them by id. 5449 ksort($members); 5450 5451 $this->assertCount(3, $members); 5452 5453 $member1 = array_shift($members); 5454 $member2 = array_shift($members); 5455 $member3 = array_shift($members); 5456 5457 // Confirm the standard fields are OK. 5458 $this->assertEquals($user1->id, $member1->id); 5459 $this->assertEquals(fullname($user1), $member1->fullname); 5460 $this->assertEquals(true, $member1->isonline); 5461 $this->assertEquals(true, $member1->showonlinestatus); 5462 $this->assertEquals(false, $member1->iscontact); 5463 $this->assertEquals(false, $member1->isblocked); 5464 $this->assertCount(2, $member1->contactrequests); 5465 5466 $this->assertEquals($user2->id, $member2->id); 5467 $this->assertEquals(fullname($user2), $member2->fullname); 5468 $this->assertEquals(false, $member2->isonline); 5469 $this->assertEquals(true, $member2->showonlinestatus); 5470 $this->assertEquals(true, $member2->iscontact); 5471 $this->assertEquals(false, $member2->isblocked); 5472 $this->assertCount(1, $member2->contactrequests); 5473 5474 $this->assertEquals($user3->id, $member3->id); 5475 $this->assertEquals(fullname($user3), $member3->fullname); 5476 $this->assertEquals(false, $member3->isonline); 5477 $this->assertEquals(true, $member3->showonlinestatus); 5478 $this->assertEquals(false, $member3->iscontact); 5479 $this->assertEquals(true, $member3->isblocked); 5480 $this->assertCount(1, $member3->contactrequests); 5481 5482 // Confirm the contact requests are OK. 5483 $request1 = array_shift($member1->contactrequests); 5484 $request2 = array_shift($member1->contactrequests); 5485 5486 $this->assertEquals($user1->id, $request1->userid); 5487 $this->assertEquals($user2->id, $request1->requesteduserid); 5488 5489 $this->assertEquals($user1->id, $request2->userid); 5490 $this->assertEquals($user3->id, $request2->requesteduserid); 5491 5492 $request1 = array_shift($member2->contactrequests); 5493 5494 $this->assertEquals($user1->id, $request1->userid); 5495 $this->assertEquals($user2->id, $request1->requesteduserid); 5496 5497 $request1 = array_shift($member3->contactrequests); 5498 5499 $this->assertEquals($user1->id, $request1->userid); 5500 $this->assertEquals($user3->id, $request1->requesteduserid); 5501 } 5502 5503 /** 5504 * Test returning members of a self conversation. 5505 */ 5506 public function test_get_conversation_members_with_self_conversation() { 5507 $lastaccess = new \stdClass(); 5508 $lastaccess->lastaccess = time(); 5509 5510 $user1 = self::getDataGenerator()->create_user($lastaccess); 5511 5512 $selfconversation = api::get_self_conversation($user1->id); 5513 testhelper::send_fake_message_to_conversation($user1, $selfconversation->id, 'This is a self-message!'); 5514 5515 // Get the members for the self-conversation. 5516 $members = api::get_conversation_members($user1->id, $selfconversation->id); 5517 $this->assertCount(1, $members); 5518 5519 $member1 = array_shift($members); 5520 5521 // Confirm the standard fields are OK. 5522 $this->assertEquals($user1->id, $member1->id); 5523 $this->assertEquals(fullname($user1), $member1->fullname); 5524 $this->assertEquals(true, $member1->isonline); 5525 $this->assertEquals(true, $member1->showonlinestatus); 5526 $this->assertEquals(false, $member1->iscontact); 5527 $this->assertEquals(false, $member1->isblocked); 5528 } 5529 5530 /** 5531 * Test verifying that messages can be sent to existing individual conversations. 5532 */ 5533 public function test_send_message_to_conversation_individual_conversation() { 5534 // Get a bunch of conversations, some group, some individual and in different states. 5535 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5536 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5537 5538 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5539 $course = $this->getDataGenerator()->create_course(); 5540 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5541 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5542 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5543 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5544 5545 // Redirect messages. 5546 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5547 // based on the message_viewed events generated as part of marking the message as read for each user. 5548 $this->preventResetByRollback(); 5549 $sink = $this->redirectMessages(); 5550 5551 // Send a message to an individual conversation. 5552 $sink = $this->redirectEvents(); 5553 $messagessink = $this->redirectMessages(); 5554 $message1 = api::send_message_to_conversation($user1->id, $ic1->id, 'this is a message', FORMAT_MOODLE); 5555 $events = $sink->get_events(); 5556 $messages = $messagessink->get_messages(); 5557 // Test customdata. 5558 $customdata = json_decode($messages[0]->customdata); 5559 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 5560 $this->assertObjectHasAttribute('actionbuttons', $customdata); 5561 $this->assertCount(1, (array) $customdata->actionbuttons); 5562 $this->assertObjectHasAttribute('placeholders', $customdata); 5563 $this->assertCount(1, (array) $customdata->placeholders); 5564 5565 // Verify the message returned. 5566 $this->assertInstanceOf(\stdClass::class, $message1); 5567 $this->assertObjectHasAttribute('id', $message1); 5568 $this->assertEquals($user1->id, $message1->useridfrom); 5569 $this->assertEquals('this is a message', $message1->text); 5570 $this->assertObjectHasAttribute('timecreated', $message1); 5571 5572 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(), 5573 // however, we can still determine the number and ids of any recipients this way. 5574 $this->assertCount(1, $events); 5575 $userids = array_column($events, 'userid'); 5576 $this->assertNotContainsEquals($user1->id, $userids); 5577 $this->assertContainsEquals($user2->id, $userids); 5578 } 5579 5580 /** 5581 * Test verifying that messages can be sent to existing group conversations. 5582 */ 5583 public function test_send_message_to_conversation_group_conversation() { 5584 // Get a bunch of conversations, some group, some individual and in different states. 5585 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5586 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5587 5588 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5589 $course = $this->getDataGenerator()->create_course(); 5590 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5591 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5592 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5593 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5594 5595 // Redirect messages. 5596 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5597 // based on the message_viewed events generated as part of marking the message as read for each user. 5598 $this->preventResetByRollback(); 5599 $sink = $this->redirectMessages(); 5600 5601 // Send a message to a group conversation. 5602 $sink = $this->redirectEvents(); 5603 $messagessink = $this->redirectMessages(); 5604 $message1 = api::send_message_to_conversation($user1->id, $gc2->id, 'message to the group', FORMAT_MOODLE); 5605 $events = $sink->get_events(); 5606 $messages = $messagessink->get_messages(); 5607 // Verify the message returned. 5608 $this->assertInstanceOf(\stdClass::class, $message1); 5609 $this->assertObjectHasAttribute('id', $message1); 5610 $this->assertEquals($user1->id, $message1->useridfrom); 5611 $this->assertEquals('message to the group', $message1->text); 5612 $this->assertObjectHasAttribute('timecreated', $message1); 5613 // Test customdata. 5614 $customdata = json_decode($messages[0]->customdata); 5615 $this->assertObjectHasAttribute('actionbuttons', $customdata); 5616 $this->assertCount(1, (array) $customdata->actionbuttons); 5617 $this->assertObjectHasAttribute('placeholders', $customdata); 5618 $this->assertCount(1, (array) $customdata->placeholders); 5619 $this->assertObjectNotHasAttribute('notificationiconurl', $customdata); // No group image means no image. 5620 5621 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(), 5622 // however, we can still determine the number and ids of any recipients this way. 5623 $this->assertCount(2, $events); 5624 $userids = array_column($events, 'userid'); 5625 $this->assertNotContainsEquals($user1->id, $userids); 5626 $this->assertContainsEquals($user3->id, $userids); 5627 $this->assertContainsEquals($user4->id, $userids); 5628 } 5629 5630 /** 5631 * Test verifying that messages can be sent to existing linked group conversations. 5632 */ 5633 public function test_send_message_to_conversation_linked_group_conversation() { 5634 global $CFG, $PAGE; 5635 5636 // Create some users. 5637 $user1 = self::getDataGenerator()->create_user(); 5638 $user2 = self::getDataGenerator()->create_user(); 5639 $user3 = self::getDataGenerator()->create_user(); 5640 5641 $course = $this->getDataGenerator()->create_course(); 5642 5643 // Create a group with a linked conversation and a valid image. 5644 $this->setAdminUser(); 5645 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5646 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5647 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5648 $group = $this->getDataGenerator()->create_group([ 5649 'courseid' => $course->id, 5650 'enablemessaging' => 1, 5651 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' 5652 ]); 5653 5654 // Add users to group. 5655 $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user1->id)); 5656 $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user2->id)); 5657 5658 // Verify the group with the image works as expected. 5659 $conversations = api::get_conversations($user1->id); 5660 $this->assertEquals(2, $conversations[0]->membercount); 5661 $this->assertEquals($course->shortname, $conversations[0]->subname); 5662 $groupimageurl = get_group_picture_url($group, $group->courseid, true); 5663 $this->assertEquals($groupimageurl, $conversations[0]->imageurl); 5664 5665 // Redirect messages. 5666 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 5667 // based on the message_viewed events generated as part of marking the message as read for each user. 5668 $this->preventResetByRollback(); 5669 $sink = $this->redirectMessages(); 5670 5671 // Send a message to a group conversation. 5672 $messagessink = $this->redirectMessages(); 5673 $message1 = api::send_message_to_conversation($user1->id, $conversations[0]->id, 5674 'message to the group', FORMAT_MOODLE); 5675 $messages = $messagessink->get_messages(); 5676 // Verify the message returned. 5677 $this->assertInstanceOf(\stdClass::class, $message1); 5678 $this->assertObjectHasAttribute('id', $message1); 5679 $this->assertEquals($user1->id, $message1->useridfrom); 5680 $this->assertEquals('message to the group', $message1->text); 5681 $this->assertObjectHasAttribute('timecreated', $message1); 5682 // Test customdata. 5683 $customdata = json_decode($messages[0]->customdata); 5684 $this->assertObjectHasAttribute('notificationiconurl', $customdata); 5685 $this->assertObjectHasAttribute('notificationsendericonurl', $customdata); 5686 $this->assertEquals($groupimageurl, $customdata->notificationiconurl); 5687 $this->assertEquals($group->name, $customdata->conversationname); 5688 $userpicture = new \user_picture($user1); 5689 $userpicture->size = 1; // Use f1 size. 5690 $this->assertEquals($userpicture->get_url($PAGE)->out(false), $customdata->notificationsendericonurl); 5691 } 5692 5693 /** 5694 * Test verifying that messages cannot be sent to conversations that don't exist. 5695 */ 5696 public function test_send_message_to_conversation_non_existent_conversation() { 5697 // Get a bunch of conversations, some group, some individual and in different states. 5698 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5699 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5700 5701 $this->expectException(\moodle_exception::class); 5702 api::send_message_to_conversation($user1->id, 0, 'test', FORMAT_MOODLE); 5703 } 5704 5705 /** 5706 * Test verifying that messages cannot be sent to conversations by users who are not members. 5707 */ 5708 public function test_send_message_to_conversation_non_member() { 5709 // Get a bunch of conversations, some group, some individual and in different states. 5710 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5711 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5712 5713 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5714 $course = $this->getDataGenerator()->create_course(); 5715 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5716 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5717 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5718 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5719 5720 $this->expectException(\moodle_exception::class); 5721 api::send_message_to_conversation($user3->id, $ic1->id, 'test', FORMAT_MOODLE); 5722 } 5723 5724 /** 5725 * Test verifying that messages cannot be sent to conversations by users who are not members. 5726 */ 5727 public function test_send_message_to_conversation_blocked_user() { 5728 // Get a bunch of conversations, some group, some individual and in different states. 5729 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5730 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5731 5732 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting. 5733 $course = $this->getDataGenerator()->create_course(); 5734 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 5735 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 5736 $this->getDataGenerator()->enrol_user($user3->id, $course->id); 5737 $this->getDataGenerator()->enrol_user($user4->id, $course->id); 5738 5739 // User 1 blocks user 2. 5740 api::block_user($user1->id, $user2->id); 5741 5742 // Verify that a message can be sent to any group conversation in which user1 and user2 are members. 5743 $this->assertNotEmpty(api::send_message_to_conversation($user1->id, $gc2->id, 'Hey guys', FORMAT_PLAIN)); 5744 5745 // User 2 cannot send a message to the conversation with user 1. 5746 $this->expectException(\moodle_exception::class); 5747 api::send_message_to_conversation($user2->id, $ic1->id, 'test', FORMAT_MOODLE); 5748 } 5749 5750 /** 5751 * Test the get_conversation() function with a muted conversation. 5752 */ 5753 public function test_get_conversation_with_muted_conversation() { 5754 $this->resetAfterTest(); 5755 5756 $user1 = self::getDataGenerator()->create_user(); 5757 $user2 = self::getDataGenerator()->create_user(); 5758 5759 $this->setUser($user1); 5760 5761 $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5762 [$user1->id, $user2->id]); 5763 5764 $conversation = api::get_conversation($user1->id, $conversation->id); 5765 5766 $this->assertFalse($conversation->ismuted); 5767 5768 // Now, mute the conversation. 5769 api::mute_conversation($user1->id, $conversation->id); 5770 5771 $conversation = api::get_conversation($user1->id, $conversation->id); 5772 5773 $this->assertTrue($conversation->ismuted); 5774 } 5775 5776 /** 5777 * Data provider for test_get_conversation_counts(). 5778 */ 5779 public function get_conversation_counts_test_cases() { 5780 $typeindividual = api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 5781 $typegroup = api::MESSAGE_CONVERSATION_TYPE_GROUP; 5782 $typeself = api::MESSAGE_CONVERSATION_TYPE_SELF; 5783 list($user1, $user2, $user3, $user4, $user5, $user6, $user7, $user8) = [0, 1, 2, 3, 4, 5, 6, 7]; 5784 $conversations = [ 5785 [ 5786 'type' => $typeindividual, 5787 'users' => [$user1, $user2], 5788 'messages' => [$user1, $user2, $user2], 5789 'favourites' => [$user1], 5790 'enabled' => null // Individual conversations cannot be disabled. 5791 ], 5792 [ 5793 'type' => $typeindividual, 5794 'users' => [$user1, $user3], 5795 'messages' => [$user1, $user3, $user1], 5796 'favourites' => [], 5797 'enabled' => null // Individual conversations cannot be disabled. 5798 ], 5799 [ 5800 'type' => $typegroup, 5801 'users' => [$user1, $user2, $user3, $user4], 5802 'messages' => [$user1, $user2, $user3, $user4], 5803 'favourites' => [], 5804 'enabled' => true 5805 ], 5806 [ 5807 'type' => $typegroup, 5808 'users' => [$user2, $user3, $user4], 5809 'messages' => [$user2, $user3, $user4], 5810 'favourites' => [], 5811 'enabled' => true 5812 ], 5813 [ 5814 'type' => $typegroup, 5815 'users' => [$user6, $user7], 5816 'messages' => [$user6, $user7, $user7], 5817 'favourites' => [$user6], 5818 'enabled' => false 5819 ], 5820 [ 5821 'type' => $typeself, 5822 'users' => [$user8], 5823 'messages' => [$user8], 5824 'favourites' => [], 5825 'enabled' => null // Self-conversations cannot be disabled. 5826 ], 5827 ]; 5828 5829 return [ 5830 'No conversations' => [ 5831 'conversationConfigs' => $conversations, 5832 'deletemessagesuser' => null, 5833 'deletemessages' => [], 5834 'arguments' => [$user5], 5835 'expectedcounts' => ['favourites' => 1, 'types' => [ 5836 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5837 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5838 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5839 ]], 5840 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5841 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5842 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 5843 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5844 ]], 5845 'deletedusers' => [] 5846 ], 5847 'No individual conversations, 2 group conversations' => [ 5848 'conversationConfigs' => $conversations, 5849 'deletemessagesuser' => null, 5850 'deletemessages' => [], 5851 'arguments' => [$user4], 5852 'expectedcounts' => ['favourites' => 1, 'types' => [ 5853 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5854 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5855 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5856 ]], 5857 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5858 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5859 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5860 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5861 ]], 5862 'deletedusers' => [] 5863 ], 5864 '2 individual conversations (one favourited), 1 group conversation' => [ 5865 'conversationConfigs' => $conversations, 5866 'deletemessagesuser' => null, 5867 'deletemessages' => [], 5868 'arguments' => [$user1], 5869 'expectedcounts' => ['favourites' => 2, 'types' => [ 5870 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5871 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5872 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5873 ]], 5874 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5875 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5876 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5877 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5878 ]], 5879 'deletedusers' => [] 5880 ], 5881 '1 individual conversation, 2 group conversations' => [ 5882 'conversationConfigs' => $conversations, 5883 'deletemessagesuser' => null, 5884 'deletemessages' => [], 5885 'arguments' => [$user2], 5886 'expectedcounts' => ['favourites' => 1, 'types' => [ 5887 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5888 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5889 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5890 ]], 5891 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5892 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5893 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5894 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5895 ]], 5896 'deletedusers' => [] 5897 ], 5898 '2 group conversations only' => [ 5899 'conversationConfigs' => $conversations, 5900 'deletemessagesuser' => null, 5901 'deletemessages' => [], 5902 'arguments' => [$user4], 5903 'expectedcounts' => ['favourites' => 1, 'types' => [ 5904 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5905 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5906 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5907 ]], 5908 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5909 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5910 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5911 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5912 ]], 5913 'deletedusers' => [] 5914 ], 5915 'All conversation types, delete a message from individual favourited, messages remaining' => [ 5916 'conversationConfigs' => $conversations, 5917 'deletemessagesuser' => $user1, 5918 'deletemessages' => [0], 5919 'arguments' => [$user1], 5920 'expectedcounts' => ['favourites' => 2, 'types' => [ 5921 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5922 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5923 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5924 ]], 5925 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5926 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5927 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5928 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5929 ]], 5930 'deletedusers' => [] 5931 ], 5932 'All conversation types, delete a message from individual non-favourited, messages remaining' => [ 5933 'conversationConfigs' => $conversations, 5934 'deletemessagesuser' => $user1, 5935 'deletemessages' => [3], 5936 'arguments' => [$user1], 5937 'expectedcounts' => ['favourites' => 2, 'types' => [ 5938 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5939 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5940 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5941 ]], 5942 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5943 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5944 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5945 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5946 ]], 5947 'deletedusers' => [] 5948 ], 5949 'All conversation types, delete all messages from individual favourited, no messages remaining' => [ 5950 'conversationConfigs' => $conversations, 5951 'deletemessagesuser' => $user1, 5952 'deletemessages' => [0, 1, 2], 5953 'arguments' => [$user1], 5954 'expectedcounts' => ['favourites' => 1, 'types' => [ 5955 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5956 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5957 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5958 ]], 5959 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5960 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5961 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5962 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5963 ]], 5964 'deletedusers' => [] 5965 ], 5966 'All conversation types, delete all messages from individual non-favourited, no messages remaining' => [ 5967 'conversationConfigs' => $conversations, 5968 'deletemessagesuser' => $user1, 5969 'deletemessages' => [3, 4, 5], 5970 'arguments' => [$user1], 5971 'expectedcounts' => ['favourites' => 2, 'types' => [ 5972 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5973 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5974 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5975 ]], 5976 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 5977 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 5978 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 5979 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5980 ]], 5981 'deletedusers' => [] 5982 ], 5983 'All conversation types, delete all messages from individual favourited, no messages remaining, different user' => [ 5984 'conversationConfigs' => $conversations, 5985 'deletemessagesuser' => $user1, 5986 'deletemessages' => [0, 1, 2], 5987 'arguments' => [$user2], 5988 'expectedcounts' => ['favourites' => 1, 'types' => [ 5989 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5990 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5991 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5992 ]], 5993 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 5994 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 5995 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 5996 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 5997 ]], 5998 'deletedusers' => [] 5999 ], 6000 'All conversation types, delete all messages from individual non-favourited, no messages remaining, different user' => [ 6001 'conversationConfigs' => $conversations, 6002 'deletemessagesuser' => $user1, 6003 'deletemessages' => [3, 4, 5], 6004 'arguments' => [$user3], 6005 'expectedcounts' => ['favourites' => 1, 'types' => [ 6006 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6007 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6008 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6009 ]], 6010 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6011 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6012 api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6013 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6014 ]], 6015 'deletedusers' => [] 6016 ], 6017 'All conversation types, delete some messages from group non-favourited, messages remaining,' => [ 6018 'conversationConfigs' => $conversations, 6019 'deletemessagesuser' => $user1, 6020 'deletemessages' => [6, 7], 6021 'arguments' => [$user1], 6022 'expectedcounts' => ['favourites' => 2, 'types' => [ 6023 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6024 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6025 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6026 ]], 6027 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6028 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6029 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6030 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6031 ]], 6032 'deletedusers' => [] 6033 ], 6034 'All conversation types, delete all messages from group non-favourited, no messages remaining,' => [ 6035 'conversationConfigs' => $conversations, 6036 'deletemessagesuser' => $user1, 6037 'deletemessages' => [6, 7, 8, 9], 6038 'arguments' => [$user1], 6039 'expectedcounts' => ['favourites' => 2, 'types' => [ 6040 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6041 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6042 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6043 ]], 6044 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6045 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6046 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6047 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6048 ]], 6049 'deletedusers' => [] 6050 ], 6051 'All conversation types, another user soft deleted' => [ 6052 'conversationConfigs' => $conversations, 6053 'deletemessagesuser' => null, 6054 'deletemessages' => [], 6055 'arguments' => [$user1], 6056 'expectedcounts' => ['favourites' => 2, 'types' => [ 6057 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6058 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6059 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6060 ]], 6061 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6062 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6063 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6064 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6065 ]], 6066 'deletedusers' => [$user2] 6067 ], 6068 'All conversation types, all group users soft deleted' => [ 6069 'conversationConfigs' => $conversations, 6070 'deletemessagesuser' => null, 6071 'deletemessages' => [], 6072 'arguments' => [$user1], 6073 'expectedcounts' => ['favourites' => 2, 'types' => [ 6074 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6075 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6076 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6077 ]], 6078 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6079 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6080 api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6081 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6082 ]], 6083 'deletedusers' => [$user2, $user3, $user4] 6084 ], 6085 'Group conversation which is disabled, favourited' => [ 6086 'conversationConfigs' => $conversations, 6087 'deletemessagesuser' => null, 6088 'deletemessages' => [], 6089 'arguments' => [$user6], 6090 'expectedcounts' => ['favourites' => 1, 'types' => [ 6091 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6092 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6093 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6094 ]], 6095 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6096 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6097 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6098 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6099 ]], 6100 'deletedusers' => [] 6101 ], 6102 'Group conversation which is disabled, non-favourited' => [ 6103 'conversationConfigs' => $conversations, 6104 'deletemessagesuser' => null, 6105 'deletemessages' => [], 6106 'arguments' => [$user7], 6107 'expectedcounts' => ['favourites' => 1, 'types' => [ 6108 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6109 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6110 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6111 ]], 6112 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6113 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6114 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6115 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6116 ]], 6117 'deletedusers' => [] 6118 ], 6119 'Conversation with self' => [ 6120 'conversationConfigs' => $conversations, 6121 'deletemessagesuser' => null, 6122 'deletemessages' => [], 6123 'arguments' => [$user8], 6124 'expectedcounts' => ['favourites' => 0, 'types' => [ 6125 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6126 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6127 api::MESSAGE_CONVERSATION_TYPE_SELF => 1 6128 ]], 6129 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6130 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6131 api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6132 api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6133 ]], 6134 'deletedusers' => [] 6135 ], 6136 ]; 6137 } 6138 6139 /** 6140 * Test the get_conversation_counts() function. 6141 * 6142 * @dataProvider get_conversation_counts_test_cases 6143 * @param array $conversationconfigs Conversations to create 6144 * @param int $deletemessagesuser The user who is deleting the messages 6145 * @param array $deletemessages The list of messages to delete (by index) 6146 * @param array $arguments Arguments for the count conversations function 6147 * @param array $expectedcounts the expected conversation counts 6148 * @param array $expectedunreadcounts the expected unread conversation counts 6149 * @param array $deletedusers the array of users to soft delete. 6150 */ 6151 public function test_get_conversation_counts( 6152 $conversationconfigs, 6153 $deletemessagesuser, 6154 $deletemessages, 6155 $arguments, 6156 $expectedcounts, 6157 $expectedunreadcounts, 6158 $deletedusers 6159 ) { 6160 $generator = $this->getDataGenerator(); 6161 $users = [ 6162 $generator->create_user(), 6163 $generator->create_user(), 6164 $generator->create_user(), 6165 $generator->create_user(), 6166 $generator->create_user(), 6167 $generator->create_user(), 6168 $generator->create_user(), 6169 $generator->create_user() 6170 ]; 6171 6172 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 6173 $arguments[0] = $users[$arguments[0]]->id; 6174 $systemcontext = \context_system::instance(); 6175 $conversations = []; 6176 $messageids = []; 6177 6178 foreach ($conversationconfigs as $config) { 6179 $conversation = api::create_conversation( 6180 $config['type'], 6181 array_map(function($userindex) use ($users) { 6182 return $users[$userindex]->id; 6183 }, $config['users']), 6184 null, 6185 ($config['enabled'] ?? true) 6186 ); 6187 6188 foreach ($config['messages'] as $userfromindex) { 6189 $userfrom = $users[$userfromindex]; 6190 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 6191 } 6192 6193 // Remove the self conversations created by the generator, 6194 // so we can choose to set that ourself and honour the original intention of the test. 6195 $userids = array_map(function($userindex) use ($users) { 6196 return $users[$userindex]->id; 6197 }, $config['users']); 6198 foreach ($userids as $userid) { 6199 if ($conversation->type == api::MESSAGE_CONVERSATION_TYPE_SELF) { 6200 api::unset_favourite_conversation($conversation->id, $userid); 6201 } 6202 } 6203 6204 foreach ($config['favourites'] as $userfromindex) { 6205 $userfrom = $users[$userfromindex]; 6206 $usercontext = \context_user::instance($userfrom->id); 6207 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 6208 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 6209 } 6210 6211 $conversations[] = $conversation; 6212 } 6213 6214 foreach ($deletemessages as $messageindex) { 6215 api::delete_message($deleteuser->id, $messageids[$messageindex]); 6216 } 6217 6218 foreach ($deletedusers as $deleteduser) { 6219 delete_user($users[$deleteduser]); 6220 } 6221 6222 $counts = api::get_conversation_counts(...$arguments); 6223 6224 $this->assertEquals($expectedcounts['favourites'], $counts['favourites']); 6225 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 6226 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 6227 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP], 6228 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]); 6229 $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF], 6230 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]); 6231 } 6232 6233 /** 6234 * Test the count_contacts() function. 6235 */ 6236 public function test_count_contacts() { 6237 $user1 = self::getDataGenerator()->create_user(); 6238 $user2 = self::getDataGenerator()->create_user(); 6239 $user3 = self::getDataGenerator()->create_user(); 6240 6241 $this->assertEquals(0, api::count_contacts($user1->id)); 6242 6243 api::create_contact_request($user1->id, $user2->id); 6244 6245 // Still zero until the request is confirmed. 6246 $this->assertEquals(0, api::count_contacts($user1->id)); 6247 6248 api::confirm_contact_request($user1->id, $user2->id); 6249 6250 $this->assertEquals(1, api::count_contacts($user1->id)); 6251 6252 api::create_contact_request($user3->id, $user1->id); 6253 6254 // Still one until the request is confirmed. 6255 $this->assertEquals(1, api::count_contacts($user1->id)); 6256 6257 api::confirm_contact_request($user3->id, $user1->id); 6258 6259 $this->assertEquals(2, api::count_contacts($user1->id)); 6260 } 6261 6262 /** 6263 * Test the get_unread_conversation_counts() function. 6264 * 6265 * @dataProvider get_conversation_counts_test_cases 6266 * @param array $conversationconfigs Conversations to create 6267 * @param int $deletemessagesuser The user who is deleting the messages 6268 * @param array $deletemessages The list of messages to delete (by index) 6269 * @param array $arguments Arguments for the count conversations function 6270 * @param array $expectedcounts the expected conversation counts 6271 * @param array $expectedunreadcounts the expected unread conversation counts 6272 * @param array $deletedusers the list of users to soft-delete. 6273 */ 6274 public function test_get_unread_conversation_counts( 6275 $conversationconfigs, 6276 $deletemessagesuser, 6277 $deletemessages, 6278 $arguments, 6279 $expectedcounts, 6280 $expectedunreadcounts, 6281 $deletedusers 6282 ) { 6283 $this->resetAfterTest(); 6284 $generator = $this->getDataGenerator(); 6285 $users = [ 6286 $generator->create_user(), 6287 $generator->create_user(), 6288 $generator->create_user(), 6289 $generator->create_user(), 6290 $generator->create_user(), 6291 $generator->create_user(), 6292 $generator->create_user(), 6293 $generator->create_user() 6294 ]; 6295 6296 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 6297 $this->setUser($users[$arguments[0]]); 6298 $arguments[0] = $users[$arguments[0]]->id; 6299 $systemcontext = \context_system::instance(); 6300 $conversations = []; 6301 $messageids = []; 6302 6303 foreach ($conversationconfigs as $config) { 6304 $conversation = api::create_conversation( 6305 $config['type'], 6306 array_map(function($userindex) use ($users) { 6307 return $users[$userindex]->id; 6308 }, $config['users']), 6309 null, 6310 ($config['enabled'] ?? true) 6311 ); 6312 6313 foreach ($config['messages'] as $userfromindex) { 6314 $userfrom = $users[$userfromindex]; 6315 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 6316 } 6317 6318 foreach ($config['favourites'] as $userfromindex) { 6319 $userfrom = $users[$userfromindex]; 6320 $usercontext = \context_user::instance($userfrom->id); 6321 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 6322 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 6323 } 6324 6325 $conversations[] = $conversation; 6326 } 6327 6328 foreach ($deletemessages as $messageindex) { 6329 api::delete_message($deleteuser->id, $messageids[$messageindex]); 6330 } 6331 6332 foreach ($deletedusers as $deleteduser) { 6333 delete_user($users[$deleteduser]); 6334 } 6335 6336 $counts = api::get_unread_conversation_counts(...$arguments); 6337 6338 $this->assertEquals($expectedunreadcounts['favourites'], $counts['favourites']); 6339 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 6340 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 6341 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP], 6342 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]); 6343 $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF], 6344 $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]); 6345 } 6346 6347 public function test_delete_all_conversation_data() { 6348 global $DB; 6349 6350 $this->resetAfterTest(); 6351 6352 $this->setAdminUser(); 6353 6354 $course1 = $this->getDataGenerator()->create_course(); 6355 $coursecontext1 = \context_course::instance($course1->id); 6356 6357 $user1 = $this->getDataGenerator()->create_user(); 6358 $user2 = $this->getDataGenerator()->create_user(); 6359 6360 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6361 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6362 6363 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); 6364 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); 6365 6366 // Add users to both groups. 6367 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 6368 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 6369 6370 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)); 6371 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)); 6372 6373 $groupconversation1 = api::get_conversation_by_area( 6374 'core_group', 6375 'groups', 6376 $group1->id, 6377 $coursecontext1->id 6378 ); 6379 6380 $groupconversation2 = api::get_conversation_by_area( 6381 'core_group', 6382 'groups', 6383 $group2->id, 6384 $coursecontext1->id 6385 ); 6386 6387 // Send a few messages. 6388 $g1m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id); 6389 $g1m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id); 6390 $g1m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id); 6391 $g1m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id); 6392 6393 $g2m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id); 6394 $g2m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id); 6395 $g2m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id); 6396 $g2m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id); 6397 6398 // Favourite the conversation for several of the users. 6399 api::set_favourite_conversation($groupconversation1->id, $user1->id); 6400 api::set_favourite_conversation($groupconversation1->id, $user2->id); 6401 6402 // Delete a few messages. 6403 api::delete_message($user1->id, $g1m1); 6404 api::delete_message($user1->id, $g1m2); 6405 api::delete_message($user1->id, $g2m1); 6406 api::delete_message($user1->id, $g2m2); 6407 6408 // Mute the conversations. 6409 api::mute_conversation($user1->id, $groupconversation1->id); 6410 api::mute_conversation($user1->id, $groupconversation2->id); 6411 6412 // Now, delete all the data for the group 1 conversation. 6413 api::delete_all_conversation_data($groupconversation1->id); 6414 6415 // Confirm group conversation was deleted just for the group 1 conversation. 6416 $this->assertEquals(0, $DB->count_records('message_conversations', ['id' => $groupconversation1->id])); 6417 $this->assertEquals(1, $DB->count_records('message_conversations', ['id' => $groupconversation2->id])); 6418 6419 // Confirm conversation members were deleted just for the group 1 conversation. 6420 $this->assertEquals(0, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation1->id])); 6421 $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation2->id])); 6422 6423 // Confirm message conversation actions were deleted just for the group 1 conversation. 6424 $this->assertEquals(0, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation1->id])); 6425 $this->assertEquals(1, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation2->id])); 6426 6427 // Confirm message user actions were deleted just for the group 1 conversation. 6428 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m1])); 6429 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m2])); 6430 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m3])); 6431 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m4])); 6432 $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m1])); 6433 $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m2])); 6434 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m3])); 6435 $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m4])); 6436 6437 // Confirm messages were deleted just for the group 1 conversation. 6438 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m1])); 6439 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m2])); 6440 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m3])); 6441 $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m4])); 6442 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m1])); 6443 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m2])); 6444 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m3])); 6445 $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4])); 6446 6447 // Confirm favourites were deleted for both users. 6448 $user1service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id)); 6449 $this->assertFalse($user1service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id, 6450 $coursecontext1)); 6451 $user2service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id)); 6452 $this->assertFalse($user2service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id, 6453 $coursecontext1)); 6454 } 6455 6456 /** 6457 * Tests the user can delete message for all users as a teacher. 6458 */ 6459 public function test_can_delete_message_for_all_users_teacher() { 6460 global $DB; 6461 $this->resetAfterTest(true); 6462 6463 // Create fake data to test it. 6464 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6465 6466 // Allow Teacher can delete messages for all. 6467 $editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']); 6468 assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, \context_system::instance()); 6469 6470 // Set as the first user. 6471 $this->setUser($teacher); 6472 6473 // Send a message to private conversation and in a group conversation. 6474 $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6475 $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6476 6477 // Teacher cannot delete message for everyone in a private conversation. 6478 $this->assertFalse(api::can_delete_message_for_all_users($teacher->id, $messageidind)); 6479 6480 // Teacher can delete message for everyone in a group conversation. 6481 $this->assertTrue(api::can_delete_message_for_all_users($teacher->id, $messageidgrp)); 6482 } 6483 6484 /** 6485 * Tests the user can delete message for all users as a student. 6486 */ 6487 public function test_can_delete_message_for_all_users_student() { 6488 $this->resetAfterTest(true); 6489 6490 // Create fake data to test it. 6491 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6492 6493 // Set as the first user. 6494 $this->setUser($student1); 6495 6496 // Send a message to private conversation and in a group conversation. 6497 $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6498 $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6499 6500 // Student1 cannot delete message for everyone in a private conversation. 6501 $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidind)); 6502 6503 // Student1 cannot delete message for everyone in a group conversation. 6504 $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidgrp)); 6505 } 6506 6507 /** 6508 * Tests tdelete message for all users in group conversation. 6509 */ 6510 public function test_delete_message_for_all_users_group_conversation() { 6511 global $DB; 6512 $this->resetAfterTest(true); 6513 6514 // Create fake data to test it. 6515 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6516 6517 // Send 3 messages to a group conversation. 6518 $mgid1 = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id); 6519 $mgid2 = testhelper::send_fake_message_to_conversation($student1, $convgroup->id); 6520 $mgid3 = testhelper::send_fake_message_to_conversation($student2, $convgroup->id); 6521 6522 // Delete message 1 for all users. 6523 api::delete_message_for_all_users($mgid1); 6524 6525 // Get the messages to check if the message 1 was deleted for teacher. 6526 $convmessages1 = api::get_conversation_messages($teacher->id, $convgroup->id); 6527 // Only has to remains 2 messages. 6528 $this->assertCount(2, $convmessages1['messages']); 6529 // Check if no one of the two messages is message 1. 6530 foreach ($convmessages1['messages'] as $message) { 6531 $this->assertNotEquals($mgid1, $message->id); 6532 } 6533 6534 // Get the messages to check if the message 1 was deleted for student1. 6535 $convmessages2 = api::get_conversation_messages($student1->id, $convgroup->id); 6536 // Only has to remains 2 messages. 6537 $this->assertCount(2, $convmessages2['messages']); 6538 // Check if no one of the two messages is message 1. 6539 foreach ($convmessages2['messages'] as $message) { 6540 $this->assertNotEquals($mgid1, $message->id); 6541 } 6542 6543 // Get the messages to check if the message 1 was deleted for student2. 6544 $convmessages3 = api::get_conversation_messages($student2->id, $convgroup->id); 6545 // Only has to remains 2 messages. 6546 $this->assertCount(2, $convmessages3['messages']); 6547 // Check if no one of the two messages is message 1. 6548 foreach ($convmessages3['messages'] as $message) { 6549 $this->assertNotEquals($mgid1, $message->id); 6550 } 6551 } 6552 6553 /** 6554 * Tests delete message for all users in private conversation. 6555 */ 6556 public function test_delete_message_for_all_users_individual_conversation() { 6557 global $DB; 6558 $this->resetAfterTest(true); 6559 6560 // Create fake data to test it. 6561 list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 6562 6563 // Send 2 messages in a individual conversation. 6564 $mid1 = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id); 6565 $mid2 = testhelper::send_fake_message_to_conversation($student1, $convindividual->id); 6566 6567 // Delete the first message for all users. 6568 api::delete_message_for_all_users($mid1); 6569 6570 // Get the messages to check if the message 1 was deleted for teacher. 6571 $convmessages1 = api::get_conversation_messages($teacher->id, $convindividual->id); 6572 // Only has to remains 1 messages for teacher. 6573 $this->assertCount(1, $convmessages1['messages']); 6574 // Check the one messages remains not is the first message. 6575 $this->assertNotEquals($mid1, $convmessages1['messages'][0]->id); 6576 6577 // Get the messages to check if the message 1 was deleted for student1. 6578 $convmessages2 = api::get_conversation_messages($student1->id, $convindividual->id); 6579 // Only has to remains 1 messages for student1. 6580 $this->assertCount(1, $convmessages2['messages']); 6581 // Check the one messages remains not is the first message. 6582 $this->assertNotEquals($mid1, $convmessages2['messages'][0]->id); 6583 } 6584 6585 /** 6586 * Test retrieving conversation messages by providing a timefrom higher than last message timecreated. It should return no 6587 * messages but keep the return structure to not break when called from the ws. 6588 */ 6589 public function test_get_conversation_messages_timefrom_higher_than_last_timecreated() { 6590 // Create some users. 6591 $user1 = self::getDataGenerator()->create_user(); 6592 $user2 = self::getDataGenerator()->create_user(); 6593 $user3 = self::getDataGenerator()->create_user(); 6594 $user4 = self::getDataGenerator()->create_user(); 6595 6596 // Create group conversation. 6597 $conversation = api::create_conversation( 6598 api::MESSAGE_CONVERSATION_TYPE_GROUP, 6599 [$user1->id, $user2->id, $user3->id, $user4->id] 6600 ); 6601 6602 // The person doing the search. 6603 $this->setUser($user1); 6604 6605 // Send some messages back and forth. 6606 $time = 1; 6607 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 6608 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 6609 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 6610 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 6611 6612 // Retrieve the messages from $time + 5, which should return no messages. 6613 $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, '', $time + 5); 6614 6615 // Confirm the conversation id is correct. 6616 $this->assertEquals($conversation->id, $convmessages['id']); 6617 6618 // Confirm the message data is correct. 6619 $messages = $convmessages['messages']; 6620 $this->assertEquals(0, count($messages)); 6621 6622 // Confirm that members key is present. 6623 $this->assertArrayHasKey('members', $convmessages); 6624 } 6625 6626 /** 6627 * Helper to seed the database with initial state with data. 6628 */ 6629 protected function create_delete_message_test_data() { 6630 // Create some users. 6631 $teacher = self::getDataGenerator()->create_user(); 6632 $student1 = self::getDataGenerator()->create_user(); 6633 $student2 = self::getDataGenerator()->create_user(); 6634 6635 // Create a course and enrol the users. 6636 $course = $this->getDataGenerator()->create_course(); 6637 $coursecontext = \context_course::instance($course->id); 6638 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher'); 6639 $this->getDataGenerator()->enrol_user($student1->id, $course->id, 'student'); 6640 $this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student'); 6641 6642 // Create a group and added the users into. 6643 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 6644 groups_add_member($group1->id, $teacher->id); 6645 groups_add_member($group1->id, $student1->id); 6646 groups_add_member($group1->id, $student2->id); 6647 6648 // Create a group conversation linked with the course. 6649 $convgroup = api::create_conversation( 6650 api::MESSAGE_CONVERSATION_TYPE_GROUP, 6651 [$teacher->id, $student1->id, $student2->id], 6652 'Group test delete for everyone', api::MESSAGE_CONVERSATION_ENABLED, 6653 'core_group', 6654 'groups', 6655 $group1->id, 6656 \context_course::instance($course->id)->id 6657 ); 6658 6659 // Create and individual conversation. 6660 $convindividual = api::create_conversation( 6661 api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6662 [$teacher->id, $student1->id] 6663 ); 6664 6665 return [$teacher, $student1, $student2, $convgroup, $convindividual]; 6666 } 6667 6668 /** 6669 * Comparison function for sorting contacts. 6670 * 6671 * @param \stdClass $a 6672 * @param \stdClass $b 6673 * @return bool 6674 */ 6675 protected static function sort_contacts($a, $b) { 6676 return $a->userid > $b->userid; 6677 } 6678 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body