Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [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