See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * External message functions unit tests 19 * 20 * @package core_message 21 * @category external 22 * @copyright 2012 Jerome Mouneyrac 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 30 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 31 require_once($CFG->dirroot . '/message/externallib.php'); 32 33 use \core_message\tests\helper as testhelper; 34 35 class core_message_externallib_testcase extends externallib_advanced_testcase { 36 37 /** 38 * Tests set up 39 */ 40 protected function setUp() { 41 global $CFG; 42 43 require_once($CFG->dirroot . '/message/lib.php'); 44 } 45 46 /** 47 * Send a fake message. 48 * 49 * {@link message_send()} does not support transaction, this function will simulate a message 50 * sent from a user to another. We should stop using it once {@link message_send()} will support 51 * transactions. This is not clean at all, this is just used to add rows to the table. 52 * 53 * @param stdClass $userfrom user object of the one sending the message. 54 * @param stdClass $userto user object of the one receiving the message. 55 * @param string $message message to send. 56 * @param int $notification is the message a notification. 57 * @param int $time the time the message was sent 58 */ 59 protected function send_message($userfrom, $userto, $message = 'Hello world!', $notification = 0, $time = 0) { 60 global $DB; 61 62 if (empty($time)) { 63 $time = time(); 64 } 65 66 if ($notification) { 67 $record = new stdClass(); 68 $record->useridfrom = $userfrom->id; 69 $record->useridto = $userto->id; 70 $record->subject = 'No subject'; 71 $record->fullmessage = $message; 72 $record->smallmessage = $message; 73 $record->timecreated = $time; 74 75 return $DB->insert_record('notifications', $record); 76 } 77 78 if (!$conversationid = \core_message\api::get_conversation_between_users([$userfrom->id, $userto->id])) { 79 $conversation = \core_message\api::create_conversation( 80 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 81 [ 82 $userfrom->id, 83 $userto->id 84 ] 85 ); 86 $conversationid = $conversation->id; 87 } 88 89 // Ok, send the message. 90 $record = new stdClass(); 91 $record->useridfrom = $userfrom->id; 92 $record->conversationid = $conversationid; 93 $record->subject = 'No subject'; 94 $record->fullmessage = $message; 95 $record->smallmessage = $message; 96 $record->timecreated = $time; 97 98 return $DB->insert_record('messages', $record); 99 } 100 101 /** 102 * Test send_instant_messages. 103 */ 104 public function test_send_instant_messages() { 105 global $DB, $USER; 106 107 $this->resetAfterTest(); 108 109 // Transactions used in tests, tell phpunit use alternative reset method. 110 $this->preventResetByRollback(); 111 112 $user1 = self::getDataGenerator()->create_user(); 113 $user2 = self::getDataGenerator()->create_user(); 114 115 $this->setUser($user1); 116 117 // Create test message data. 118 $message1 = array(); 119 $message1['touserid'] = $user2->id; 120 $message1['text'] = 'the message.'; 121 $message1['clientmsgid'] = 4; 122 $messages = array($message1); 123 124 $sentmessages = core_message_external::send_instant_messages($messages); 125 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 126 $this->assertEquals( 127 get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message1['touserid']))), 128 array_pop($sentmessages)['errormessage'] 129 ); 130 131 // Add the user1 as a contact. 132 \core_message\api::add_contact($user1->id, $user2->id); 133 134 // Send message again. Now it should work properly. 135 $sentmessages = core_message_external::send_instant_messages($messages); 136 // We need to execute the return values cleaning process to simulate the web service server. 137 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 138 139 $sentmessage = reset($sentmessages); 140 141 $sql = "SELECT m.*, mcm.userid as useridto 142 FROM {messages} m 143 INNER JOIN {message_conversations} mc 144 ON m.conversationid = mc.id 145 INNER JOIN {message_conversation_members} mcm 146 ON mcm.conversationid = mc.id 147 WHERE mcm.userid != ? 148 AND m.id = ?"; 149 $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]); 150 151 // Confirm that the message was inserted correctly. 152 $this->assertEquals($themessage->useridfrom, $user1->id); 153 $this->assertEquals($themessage->useridto, $message1['touserid']); 154 $this->assertEquals($themessage->smallmessage, $message1['text']); 155 $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']); 156 } 157 158 /** 159 * Test send_instant_messages with a message text longer than permitted. 160 */ 161 public function test_send_instant_messages_long_text() { 162 global $CFG; 163 164 $this->resetAfterTest(true); 165 166 // Transactions used in tests, tell phpunit use alternative reset method. 167 $this->preventResetByRollback(); 168 169 $user1 = self::getDataGenerator()->create_user(); 170 $user2 = self::getDataGenerator()->create_user(); 171 172 $this->setUser($user1); 173 174 // Create test message data. 175 $message1 = [ 176 'touserid' => $user2->id, 177 'text' => str_repeat("M", \core_message\api::MESSAGE_MAX_LENGTH + 100), 178 'clientmsgid' => 4, 179 ]; 180 $messages = [$message1]; 181 182 // Add the user1 as a contact. 183 \core_message\api::add_contact($user1->id, $user2->id); 184 185 $sentmessages = core_message_external::send_instant_messages($messages); 186 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 187 $this->assertEquals( 188 get_string('errormessagetoolong', 'message'), 189 array_pop($sentmessages)['errormessage'] 190 ); 191 } 192 193 /** 194 * Test send_instant_messages to a user who has blocked you. 195 */ 196 public function test_send_instant_messages_blocked_user() { 197 global $DB; 198 199 $this->resetAfterTest(); 200 201 // Transactions used in tests, tell phpunit use alternative reset method. 202 $this->preventResetByRollback(); 203 204 $user1 = self::getDataGenerator()->create_user(); 205 $user2 = self::getDataGenerator()->create_user(); 206 207 $this->setUser($user1); 208 209 \core_message\api::block_user($user2->id, $user1->id); 210 211 // Create test message data. 212 $message1 = array(); 213 $message1['touserid'] = $user2->id; 214 $message1['text'] = 'the message.'; 215 $message1['clientmsgid'] = 4; 216 $messages = array($message1); 217 218 $sentmessages = core_message_external::send_instant_messages($messages); 219 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 220 221 $sentmessage = reset($sentmessages); 222 223 $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']); 224 225 $this->assertEquals(0, $DB->count_records('messages')); 226 } 227 228 /** 229 * Test send_instant_messages when sending a message to a non-contact who has blocked non-contacts. 230 */ 231 public function test_send_instant_messages_block_non_contacts() { 232 global $DB; 233 234 $this->resetAfterTest(true); 235 236 // Transactions used in tests, tell phpunit use alternative reset method. 237 $this->preventResetByRollback(); 238 239 $user1 = self::getDataGenerator()->create_user(); 240 $user2 = self::getDataGenerator()->create_user(); 241 242 $this->setUser($user1); 243 244 // Set the user preference so user 2 does not accept messages from non-contacts. 245 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2); 246 247 // Create test message data. 248 $message1 = array(); 249 $message1['touserid'] = $user2->id; 250 $message1['text'] = 'the message.'; 251 $message1['clientmsgid'] = 4; 252 $messages = array($message1); 253 254 $sentmessages = core_message_external::send_instant_messages($messages); 255 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 256 257 $sentmessage = reset($sentmessages); 258 259 $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']); 260 261 $this->assertEquals(0, $DB->count_records('messages')); 262 } 263 264 /** 265 * Test send_instant_messages when sending a message to a contact who has blocked non-contacts. 266 */ 267 public function test_send_instant_messages_block_non_contacts_but_am_contact() { 268 global $DB, $USER; 269 270 $this->resetAfterTest(true); 271 272 // Transactions used in tests, tell phpunit use alternative reset method. 273 $this->preventResetByRollback(); 274 275 $user1 = self::getDataGenerator()->create_user(); 276 $user2 = self::getDataGenerator()->create_user(); 277 278 $this->setUser($user1); 279 280 // Set the user preference so user 2 does not accept messages from non-contacts. 281 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2); 282 283 \core_message\api::add_contact($user1->id, $user2->id); 284 285 // Create test message data. 286 $message1 = array(); 287 $message1['touserid'] = $user2->id; 288 $message1['text'] = 'the message.'; 289 $message1['clientmsgid'] = 4; 290 $messages = array($message1); 291 292 $sentmessages = core_message_external::send_instant_messages($messages); 293 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages); 294 295 $sentmessage = reset($sentmessages); 296 297 $sql = "SELECT m.*, mcm.userid as useridto 298 FROM {messages} m 299 INNER JOIN {message_conversations} mc 300 ON m.conversationid = mc.id 301 INNER JOIN {message_conversation_members} mcm 302 ON mcm.conversationid = mc.id 303 WHERE mcm.userid != ? 304 AND m.id = ?"; 305 $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]); 306 307 // Confirm that the message was inserted correctly. 308 $this->assertEquals($themessage->useridfrom, $user1->id); 309 $this->assertEquals($themessage->useridto, $message1['touserid']); 310 $this->assertEquals($themessage->smallmessage, $message1['text']); 311 $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']); 312 } 313 314 /** 315 * Test send_instant_messages with no capabilities 316 */ 317 public function test_send_instant_messages_no_capability() { 318 global $DB; 319 320 $this->resetAfterTest(true); 321 322 // Transactions used in tests, tell phpunit use alternative reset method. 323 $this->preventResetByRollback(); 324 325 $user1 = self::getDataGenerator()->create_user(); 326 $user2 = self::getDataGenerator()->create_user(); 327 328 $this->setUser($user1); 329 330 // Unset the required capabilities by the external function. 331 $contextid = context_system::instance()->id; 332 $userrole = $DB->get_record('role', array('shortname' => 'user')); 333 $this->unassignUserCapability('moodle/site:sendmessage', $contextid, $userrole->id); 334 335 // Create test message data. 336 $message1 = array(); 337 $message1['touserid'] = $user2->id; 338 $message1['text'] = 'the message.'; 339 $message1['clientmsgid'] = 4; 340 $messages = array($message1); 341 342 $this->expectException('required_capability_exception'); 343 core_message_external::send_instant_messages($messages); 344 } 345 346 /** 347 * Test send_instant_messages when messaging is disabled. 348 */ 349 public function test_send_instant_messages_messaging_disabled() { 350 global $CFG; 351 352 $this->resetAfterTest(true); 353 354 // Transactions used in tests, tell phpunit use alternative reset method. 355 $this->preventResetByRollback(); 356 357 $user1 = self::getDataGenerator()->create_user(); 358 $user2 = self::getDataGenerator()->create_user(); 359 360 $this->setUser($user1); 361 362 // Disable messaging. 363 $CFG->messaging = 0; 364 365 // Create test message data. 366 $message1 = array(); 367 $message1['touserid'] = $user2->id; 368 $message1['text'] = 'the message.'; 369 $message1['clientmsgid'] = 4; 370 $messages = array($message1); 371 372 $this->expectException('moodle_exception'); 373 core_message_external::send_instant_messages($messages); 374 } 375 376 /** 377 * Test create_contacts. 378 */ 379 public function test_create_contacts() { 380 $this->resetAfterTest(true); 381 382 $user1 = self::getDataGenerator()->create_user(); 383 $user2 = self::getDataGenerator()->create_user(); 384 $user3 = self::getDataGenerator()->create_user(); 385 $user4 = self::getDataGenerator()->create_user(); 386 $user5 = self::getDataGenerator()->create_user(); 387 $this->setUser($user1); 388 389 // Adding a contact. 390 $return = core_message_external::create_contacts(array($user2->id)); 391 $this->assertDebuggingCalled(); 392 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return); 393 $this->assertEquals(array(), $return); 394 395 // Adding a contact who is already a contact. 396 $return = core_message_external::create_contacts(array($user2->id)); 397 $this->assertDebuggingCalled(); 398 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return); 399 $this->assertEquals(array(), $return); 400 401 // Adding multiple contacts. 402 $return = core_message_external::create_contacts(array($user3->id, $user4->id)); 403 $this->assertDebuggingCalledCount(2); 404 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return); 405 $this->assertEquals(array(), $return); 406 407 // Adding a non-existing user. 408 $return = core_message_external::create_contacts(array(99999)); 409 $this->assertDebuggingCalled(); 410 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return); 411 $this->assertCount(1, $return); 412 $return = array_pop($return); 413 $this->assertEquals($return['warningcode'], 'contactnotcreated'); 414 $this->assertEquals($return['itemid'], 99999); 415 416 // Adding contacts with valid and invalid parameters. 417 $return = core_message_external::create_contacts(array($user5->id, 99999)); 418 $this->assertDebuggingCalledCount(2); 419 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return); 420 $this->assertCount(1, $return); 421 $return = array_pop($return); 422 $this->assertEquals($return['warningcode'], 'contactnotcreated'); 423 $this->assertEquals($return['itemid'], 99999); 424 425 // Try to add a contact to another user, should throw an exception. 426 // All assertions must be added before this point. 427 $this->expectException('required_capability_exception'); 428 core_message_external::create_contacts(array($user2->id), $user3->id); 429 } 430 431 /** 432 * Test delete_contacts. 433 */ 434 public function test_delete_contacts() { 435 $this->resetAfterTest(true); 436 437 $user1 = self::getDataGenerator()->create_user(); 438 $user2 = self::getDataGenerator()->create_user(); 439 $user3 = self::getDataGenerator()->create_user(); 440 $user4 = self::getDataGenerator()->create_user(); 441 $user5 = self::getDataGenerator()->create_user(); 442 $user6 = self::getDataGenerator()->create_user(); 443 $this->setUser($user1); 444 445 \core_message\api::add_contact($user1->id, $user3->id); 446 \core_message\api::add_contact($user1->id, $user4->id); 447 \core_message\api::add_contact($user1->id, $user5->id); 448 \core_message\api::add_contact($user1->id, $user6->id); 449 450 // Removing a non-contact. 451 $return = core_message_external::delete_contacts(array($user2->id)); 452 $this->assertNull($return); 453 454 // Removing one contact. 455 $return = core_message_external::delete_contacts(array($user3->id)); 456 $this->assertNull($return); 457 458 // Removing multiple contacts. 459 $return = core_message_external::delete_contacts(array($user4->id, $user5->id)); 460 $this->assertNull($return); 461 462 // Removing contact from unexisting user. 463 $return = core_message_external::delete_contacts(array(99999)); 464 $this->assertNull($return); 465 466 // Removing mixed valid and invalid data. 467 $return = core_message_external::delete_contacts(array($user6->id, 99999)); 468 $this->assertNull($return); 469 470 // Try to delete a contact of another user contact list, should throw an exception. 471 // All assertions must be added before this point. 472 $this->expectException('required_capability_exception'); 473 core_message_external::delete_contacts(array($user2->id), $user3->id); 474 } 475 476 /** 477 * Test block_contacts. 478 */ 479 public function test_block_contacts() { 480 $this->resetAfterTest(true); 481 482 $user1 = self::getDataGenerator()->create_user(); 483 $user2 = self::getDataGenerator()->create_user(); 484 $user3 = self::getDataGenerator()->create_user(); 485 $user4 = self::getDataGenerator()->create_user(); 486 $user5 = self::getDataGenerator()->create_user(); 487 $this->setUser($user1); 488 489 \core_message\api::add_contact($user1->id, $user3->id); 490 \core_message\api::add_contact($user1->id, $user4->id); 491 \core_message\api::add_contact($user1->id, $user5->id); 492 493 // Blocking a contact. 494 $return = core_message_external::block_contacts(array($user2->id)); 495 $this->assertDebuggingCalled(); 496 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return); 497 $this->assertEquals(array(), $return); 498 499 // Blocking a contact who is already a contact. 500 $return = core_message_external::block_contacts(array($user2->id)); 501 $this->assertDebuggingCalled(); 502 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return); 503 $this->assertEquals(array(), $return); 504 505 // Blocking multiple contacts. 506 $return = core_message_external::block_contacts(array($user3->id, $user4->id)); 507 $this->assertDebuggingCalledCount(2); 508 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return); 509 $this->assertEquals(array(), $return); 510 511 // Blocking a non-existing user. 512 $return = core_message_external::block_contacts(array(99999)); 513 $this->assertDebuggingCalled(); 514 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return); 515 $this->assertCount(1, $return); 516 $return = array_pop($return); 517 $this->assertEquals($return['warningcode'], 'contactnotblocked'); 518 $this->assertEquals($return['itemid'], 99999); 519 520 // Blocking contacts with valid and invalid parameters. 521 $return = core_message_external::block_contacts(array($user5->id, 99999)); 522 $this->assertDebuggingCalledCount(2); 523 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return); 524 $this->assertCount(1, $return); 525 $return = array_pop($return); 526 $this->assertEquals($return['warningcode'], 'contactnotblocked'); 527 $this->assertEquals($return['itemid'], 99999); 528 529 // Try to block a contact of another user contact list, should throw an exception. 530 // All assertions must be added before this point. 531 $this->expectException('required_capability_exception'); 532 core_message_external::block_contacts(array($user2->id), $user3->id); 533 } 534 535 /** 536 * Test unblock_contacts. 537 */ 538 public function test_unblock_contacts() { 539 $this->resetAfterTest(true); 540 541 $user1 = self::getDataGenerator()->create_user(); 542 $user2 = self::getDataGenerator()->create_user(); 543 $user3 = self::getDataGenerator()->create_user(); 544 $user4 = self::getDataGenerator()->create_user(); 545 $user5 = self::getDataGenerator()->create_user(); 546 $user6 = self::getDataGenerator()->create_user(); 547 $this->setUser($user1); 548 549 \core_message\api::add_contact($user1->id, $user3->id); 550 \core_message\api::add_contact($user1->id, $user4->id); 551 \core_message\api::add_contact($user1->id, $user5->id); 552 \core_message\api::add_contact($user1->id, $user6->id); 553 554 // Removing a non-contact. 555 $return = core_message_external::unblock_contacts(array($user2->id)); 556 $this->assertDebuggingCalled(); 557 $this->assertNull($return); 558 559 // Removing one contact. 560 $return = core_message_external::unblock_contacts(array($user3->id)); 561 $this->assertDebuggingCalled(); 562 $this->assertNull($return); 563 564 // Removing multiple contacts. 565 $return = core_message_external::unblock_contacts(array($user4->id, $user5->id)); 566 $this->assertDebuggingCalledCount(2); 567 $this->assertNull($return); 568 569 // Removing contact from unexisting user. 570 $return = core_message_external::unblock_contacts(array(99999)); 571 $this->assertDebuggingCalled(); 572 $this->assertNull($return); 573 574 // Removing mixed valid and invalid data. 575 $return = core_message_external::unblock_contacts(array($user6->id, 99999)); 576 $this->assertDebuggingCalledCount(2); 577 $this->assertNull($return); 578 579 // Try to unblock a contact of another user contact list, should throw an exception. 580 // All assertions must be added before this point. 581 $this->expectException('required_capability_exception'); 582 core_message_external::unblock_contacts(array($user2->id), $user3->id); 583 $this->assertDebuggingCalled(); 584 } 585 586 /** 587 * Test getting contact requests. 588 */ 589 public function test_get_contact_requests() { 590 global $PAGE; 591 592 $this->resetAfterTest(); 593 594 $user1 = self::getDataGenerator()->create_user(); 595 $user2 = self::getDataGenerator()->create_user(); 596 $user3 = self::getDataGenerator()->create_user(); 597 598 $this->setUser($user1); 599 600 // Block one user, their request should not show up. 601 \core_message\api::block_user($user1->id, $user3->id); 602 603 \core_message\api::create_contact_request($user2->id, $user1->id); 604 \core_message\api::create_contact_request($user3->id, $user1->id); 605 606 $requests = core_message_external::get_contact_requests($user1->id); 607 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests); 608 609 $this->assertCount(1, $requests); 610 611 $request = reset($requests); 612 $userpicture = new \user_picture($user2); 613 $profileimageurl = $userpicture->get_url($PAGE)->out(false); 614 615 $this->assertEquals($user2->id, $request['id']); 616 $this->assertEquals(fullname($user2), $request['fullname']); 617 $this->assertArrayHasKey('profileimageurl', $request); 618 $this->assertArrayHasKey('profileimageurlsmall', $request); 619 $this->assertArrayHasKey('isonline', $request); 620 $this->assertArrayHasKey('showonlinestatus', $request); 621 $this->assertArrayHasKey('isblocked', $request); 622 $this->assertArrayHasKey('iscontact', $request); 623 } 624 625 /** 626 * Test the get_contact_requests() function when the user has blocked the sender of the request. 627 */ 628 public function test_get_contact_requests_blocked_sender() { 629 $this->resetAfterTest(); 630 $user1 = self::getDataGenerator()->create_user(); 631 $user2 = self::getDataGenerator()->create_user(); 632 633 // User1 blocks User2. 634 \core_message\api::block_user($user1->id, $user2->id); 635 636 // User2 tries to add User1 as a contact. 637 \core_message\api::create_contact_request($user2->id, $user1->id); 638 639 // Verify we don't see the contact request from the blocked user User2 in the requests for User1. 640 $this->setUser($user1); 641 $requests = core_message_external::get_contact_requests($user1->id); 642 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests); 643 644 $this->assertCount(0, $requests); 645 } 646 647 /** 648 * Test getting contact requests when there are none. 649 */ 650 public function test_get_contact_requests_no_requests() { 651 $this->resetAfterTest(); 652 653 $user1 = self::getDataGenerator()->create_user(); 654 655 $this->setUser($user1); 656 657 $requests = core_message_external::get_contact_requests($user1->id); 658 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests); 659 660 $this->assertEmpty($requests); 661 } 662 663 /** 664 * Test getting contact requests with limits. 665 */ 666 public function test_get_contact_requests_with_limits() { 667 $this->resetAfterTest(); 668 669 $user1 = self::getDataGenerator()->create_user(); 670 $user2 = self::getDataGenerator()->create_user(); 671 $user3 = self::getDataGenerator()->create_user(); 672 673 $this->setUser($user1); 674 675 \core_message\api::create_contact_request($user2->id, $user1->id); 676 \core_message\api::create_contact_request($user3->id, $user1->id); 677 678 $requests = core_message_external::get_contact_requests($user1->id, 0, 1); 679 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests); 680 681 $this->assertCount(1, $requests); 682 } 683 684 /** 685 * Test getting contact requests with messaging disabled. 686 */ 687 public function test_get_contact_requests_messaging_disabled() { 688 global $CFG; 689 690 $this->resetAfterTest(); 691 692 // Create some skeleton data just so we can call the WS. 693 $user1 = self::getDataGenerator()->create_user(); 694 695 $this->setUser($user1); 696 697 // Disable messaging. 698 $CFG->messaging = 0; 699 700 // Ensure an exception is thrown. 701 $this->expectException('moodle_exception'); 702 core_message_external::get_contact_requests($user1->id); 703 } 704 705 /** 706 * Test getting contact requests with no permission. 707 */ 708 public function test_get_contact_requests_no_permission() { 709 $this->resetAfterTest(); 710 711 // Create some skeleton data just so we can call the WS. 712 $user1 = self::getDataGenerator()->create_user(); 713 $user2 = self::getDataGenerator()->create_user(); 714 $user3 = self::getDataGenerator()->create_user(); 715 716 $this->setUser($user3); 717 718 // Ensure an exception is thrown. 719 $this->expectException('required_capability_exception'); 720 core_message_external::create_contact_request($user1->id, $user2->id); 721 } 722 723 /** 724 * Test getting the number of received contact requests. 725 */ 726 public function test_get_received_contact_requests_count() { 727 $this->resetAfterTest(); 728 729 $user1 = self::getDataGenerator()->create_user(); 730 $user2 = self::getDataGenerator()->create_user(); 731 $user3 = self::getDataGenerator()->create_user(); 732 $user4 = self::getDataGenerator()->create_user(); 733 734 $this->setUser($user1); 735 736 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id); 737 $contactrequestnumber = external_api::clean_returnvalue( 738 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber); 739 $this->assertEquals(0, $contactrequestnumber); 740 741 \core_message\api::create_contact_request($user2->id, $user1->id); 742 743 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id); 744 $contactrequestnumber = external_api::clean_returnvalue( 745 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber); 746 $this->assertEquals(1, $contactrequestnumber); 747 748 \core_message\api::create_contact_request($user3->id, $user1->id); 749 750 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id); 751 $contactrequestnumber = external_api::clean_returnvalue( 752 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber); 753 $this->assertEquals(2, $contactrequestnumber); 754 755 \core_message\api::create_contact_request($user1->id, $user4->id); 756 757 // Web service should ignore sent requests. 758 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id); 759 $contactrequestnumber = external_api::clean_returnvalue( 760 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber); 761 $this->assertEquals(2, $contactrequestnumber); 762 } 763 764 /** 765 * Test the get_received_contact_requests_count() function when the user has blocked the sender of the request. 766 */ 767 public function test_get_received_contact_requests_count_blocked_sender() { 768 $this->resetAfterTest(); 769 $user1 = self::getDataGenerator()->create_user(); 770 $user2 = self::getDataGenerator()->create_user(); 771 772 // User1 blocks User2. 773 \core_message\api::block_user($user1->id, $user2->id); 774 775 // User2 tries to add User1 as a contact. 776 \core_message\api::create_contact_request($user2->id, $user1->id); 777 778 // Verify we don't see the contact request from the blocked user User2 in the count for User1. 779 $this->setUser($user1); 780 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id); 781 $contactrequestnumber = external_api::clean_returnvalue( 782 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber); 783 $this->assertEquals(0, $contactrequestnumber); 784 } 785 786 /** 787 * Test getting the number of received contact requests with no permissions. 788 */ 789 public function test_get_received_contact_requests_count_no_permission() { 790 $this->resetAfterTest(); 791 792 // Create some skeleton data just so we can call the WS. 793 $user1 = self::getDataGenerator()->create_user(); 794 $user2 = self::getDataGenerator()->create_user(); 795 796 $this->setUser($user2); 797 798 // Ensure an exception is thrown. 799 $this->expectException('required_capability_exception'); 800 core_message_external::get_received_contact_requests_count($user1->id); 801 } 802 803 /** 804 * Test getting the number of received contact requests with messaging disabled. 805 */ 806 public function test_get_received_contact_requests_count_messaging_disabled() { 807 global $CFG; 808 809 $this->resetAfterTest(); 810 811 // Create some skeleton data just so we can call the WS. 812 $user1 = self::getDataGenerator()->create_user(); 813 814 $this->setUser($user1); 815 816 // Disable messaging. 817 $CFG->messaging = 0; 818 819 // Ensure an exception is thrown. 820 $this->expectException('moodle_exception'); 821 core_message_external::get_received_contact_requests_count($user1->id); 822 } 823 824 /** 825 * Test creating a contact request. 826 */ 827 public function test_create_contact_request() { 828 global $CFG, $DB; 829 830 $this->resetAfterTest(); 831 832 $user1 = self::getDataGenerator()->create_user(); 833 $user2 = self::getDataGenerator()->create_user(); 834 835 $this->setUser($user1); 836 837 // Allow users to message anyone site-wide. 838 $CFG->messagingallusers = 1; 839 840 $return = core_message_external::create_contact_request($user1->id, $user2->id); 841 $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return); 842 $this->assertEquals([], $return['warnings']); 843 844 $request = $DB->get_records('message_contact_requests'); 845 846 $this->assertCount(1, $request); 847 848 $request = reset($request); 849 850 $this->assertEquals($request->id, $return['request']['id']); 851 $this->assertEquals($request->userid, $return['request']['userid']); 852 $this->assertEquals($request->requesteduserid, $return['request']['requesteduserid']); 853 $this->assertEquals($request->timecreated, $return['request']['timecreated']); 854 } 855 856 /** 857 * Test creating a contact request when not allowed. 858 */ 859 public function test_create_contact_request_not_allowed() { 860 global $CFG; 861 862 $this->resetAfterTest(); 863 864 $user1 = self::getDataGenerator()->create_user(); 865 $user2 = self::getDataGenerator()->create_user(); 866 867 $this->setUser($user1); 868 869 $CFG->messagingallusers = 0; 870 871 $return = core_message_external::create_contact_request($user1->id, $user2->id); 872 $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return); 873 874 $warning = reset($return['warnings']); 875 876 $this->assertEquals('user', $warning['item']); 877 $this->assertEquals($user2->id, $warning['itemid']); 878 $this->assertEquals('cannotcreatecontactrequest', $warning['warningcode']); 879 $this->assertEquals('You are unable to create a contact request for this user', $warning['message']); 880 } 881 882 /** 883 * Test creating a contact request with messaging disabled. 884 */ 885 public function test_create_contact_request_messaging_disabled() { 886 global $CFG; 887 888 $this->resetAfterTest(); 889 890 // Create some skeleton data just so we can call the WS. 891 $user1 = self::getDataGenerator()->create_user(); 892 $user2 = self::getDataGenerator()->create_user(); 893 894 $this->setUser($user1); 895 896 // Disable messaging. 897 $CFG->messaging = 0; 898 899 // Ensure an exception is thrown. 900 $this->expectException('moodle_exception'); 901 core_message_external::create_contact_request($user1->id, $user2->id); 902 } 903 904 /** 905 * Test creating a contact request with no permission. 906 */ 907 public function test_create_contact_request_no_permission() { 908 $this->resetAfterTest(); 909 910 // Create some skeleton data just so we can call the WS. 911 $user1 = self::getDataGenerator()->create_user(); 912 $user2 = self::getDataGenerator()->create_user(); 913 $user3 = self::getDataGenerator()->create_user(); 914 915 $this->setUser($user3); 916 917 // Ensure an exception is thrown. 918 $this->expectException('required_capability_exception'); 919 core_message_external::create_contact_request($user1->id, $user2->id); 920 } 921 922 /** 923 * Test confirming a contact request. 924 */ 925 public function test_confirm_contact_request() { 926 global $DB; 927 928 $this->resetAfterTest(); 929 930 $user1 = self::getDataGenerator()->create_user(); 931 $user2 = self::getDataGenerator()->create_user(); 932 933 $this->setUser($user1); 934 935 \core_message\api::create_contact_request($user1->id, $user2->id); 936 937 $this->setUser($user2); 938 939 $return = core_message_external::confirm_contact_request($user1->id, $user2->id); 940 $return = external_api::clean_returnvalue(core_message_external::confirm_contact_request_returns(), $return); 941 $this->assertEquals(array(), $return); 942 943 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 944 945 $contact = $DB->get_records('message_contacts'); 946 947 $this->assertCount(1, $contact); 948 949 $contact = reset($contact); 950 951 $this->assertEquals($user1->id, $contact->userid); 952 $this->assertEquals($user2->id, $contact->contactid); 953 } 954 955 /** 956 * Test confirming a contact request with messaging disabled. 957 */ 958 public function test_confirm_contact_request_messaging_disabled() { 959 global $CFG; 960 961 $this->resetAfterTest(); 962 963 // Create some skeleton data just so we can call the WS. 964 $user1 = self::getDataGenerator()->create_user(); 965 $user2 = self::getDataGenerator()->create_user(); 966 967 $this->setUser($user1); 968 969 // Disable messaging. 970 $CFG->messaging = 0; 971 972 // Ensure an exception is thrown. 973 $this->expectException('moodle_exception'); 974 core_message_external::confirm_contact_request($user1->id, $user2->id); 975 } 976 977 /** 978 * Test confirming a contact request with no permission. 979 */ 980 public function test_confirm_contact_request_no_permission() { 981 $this->resetAfterTest(); 982 983 // Create some skeleton data just so we can call the WS. 984 $user1 = self::getDataGenerator()->create_user(); 985 $user2 = self::getDataGenerator()->create_user(); 986 $user3 = self::getDataGenerator()->create_user(); 987 988 $this->setUser($user3); 989 990 // Ensure an exception is thrown. 991 $this->expectException('required_capability_exception'); 992 core_message_external::confirm_contact_request($user1->id, $user2->id); 993 } 994 995 /** 996 * Test declining a contact request. 997 */ 998 public function test_decline_contact_request() { 999 global $DB; 1000 1001 $this->resetAfterTest(); 1002 1003 $user1 = self::getDataGenerator()->create_user(); 1004 $user2 = self::getDataGenerator()->create_user(); 1005 1006 $this->setUser($user1); 1007 1008 \core_message\api::create_contact_request($user1->id, $user2->id); 1009 1010 $this->setUser($user2); 1011 1012 $return = core_message_external::decline_contact_request($user1->id, $user2->id); 1013 $return = external_api::clean_returnvalue(core_message_external::decline_contact_request_returns(), $return); 1014 $this->assertEquals(array(), $return); 1015 1016 $this->assertEquals(0, $DB->count_records('message_contact_requests')); 1017 $this->assertEquals(0, $DB->count_records('message_contacts')); 1018 } 1019 1020 /** 1021 * Test declining a contact request with messaging disabled. 1022 */ 1023 public function test_decline_contact_request_messaging_disabled() { 1024 global $CFG; 1025 1026 $this->resetAfterTest(); 1027 1028 // Create some skeleton data just so we can call the WS. 1029 $user1 = self::getDataGenerator()->create_user(); 1030 $user2 = self::getDataGenerator()->create_user(); 1031 1032 $this->setUser($user1); 1033 1034 // Disable messaging. 1035 $CFG->messaging = 0; 1036 1037 // Ensure an exception is thrown. 1038 $this->expectException('moodle_exception'); 1039 core_message_external::decline_contact_request($user1->id, $user2->id); 1040 } 1041 1042 /** 1043 * Test declining a contact request with no permission. 1044 */ 1045 public function test_decline_contact_request_no_permission() { 1046 $this->resetAfterTest(); 1047 1048 // Create some skeleton data just so we can call the WS. 1049 $user1 = self::getDataGenerator()->create_user(); 1050 $user2 = self::getDataGenerator()->create_user(); 1051 $user3 = self::getDataGenerator()->create_user(); 1052 1053 $this->setUser($user3); 1054 1055 // Ensure an exception is thrown. 1056 $this->expectException('required_capability_exception'); 1057 core_message_external::decline_contact_request($user1->id, $user2->id); 1058 } 1059 1060 /** 1061 * Test muting conversations. 1062 */ 1063 public function test_mute_conversations() { 1064 global $DB; 1065 1066 $this->resetAfterTest(true); 1067 1068 $user1 = self::getDataGenerator()->create_user(); 1069 $user2 = self::getDataGenerator()->create_user(); 1070 1071 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1072 [$user1->id, $user2->id]); 1073 1074 $this->setUser($user1); 1075 1076 // Muting a conversation. 1077 $return = core_message_external::mute_conversations($user1->id, [$conversation->id]); 1078 $return = external_api::clean_returnvalue(core_message_external::mute_conversations_returns(), $return); 1079 $this->assertEquals(array(), $return); 1080 1081 // Get list of muted conversations. 1082 $mca = $DB->get_record('message_conversation_actions', []); 1083 1084 $this->assertEquals($user1->id, $mca->userid); 1085 $this->assertEquals($conversation->id, $mca->conversationid); 1086 $this->assertEquals(\core_message\api::CONVERSATION_ACTION_MUTED, $mca->action); 1087 1088 // Muting a conversation that is already muted. 1089 $return = core_message_external::mute_conversations($user1->id, [$conversation->id]); 1090 $return = external_api::clean_returnvalue(core_message_external::mute_conversations_returns(), $return); 1091 $this->assertEquals(array(), $return); 1092 1093 $this->assertEquals(1, $DB->count_records('message_conversation_actions')); 1094 } 1095 1096 /** 1097 * Test muting a conversation with messaging disabled. 1098 */ 1099 public function test_mute_conversations_messaging_disabled() { 1100 global $CFG; 1101 1102 $this->resetAfterTest(); 1103 1104 // Create some skeleton data just so we can call the WS. 1105 $user1 = self::getDataGenerator()->create_user(); 1106 $user2 = self::getDataGenerator()->create_user(); 1107 1108 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1109 [$user1->id, $user2->id]); 1110 1111 $this->setUser($user1); 1112 1113 // Disable messaging. 1114 $CFG->messaging = 0; 1115 1116 // Ensure an exception is thrown. 1117 $this->expectException('moodle_exception'); 1118 core_message_external::mute_conversations($user1->id, [$conversation->id]); 1119 } 1120 1121 /** 1122 * Test muting a conversation with no permission. 1123 */ 1124 public function test_mute_conversations_no_permission() { 1125 $this->resetAfterTest(); 1126 1127 // Create some skeleton data just so we can call the WS. 1128 $user1 = self::getDataGenerator()->create_user(); 1129 $user2 = self::getDataGenerator()->create_user(); 1130 $user3 = self::getDataGenerator()->create_user(); 1131 1132 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1133 [$user1->id, $user2->id]); 1134 1135 $this->setUser($user3); 1136 1137 // Ensure an exception is thrown. 1138 $this->expectException('required_capability_exception'); 1139 core_message_external::mute_conversations($user1->id, [$conversation->id]); 1140 } 1141 1142 /** 1143 * Test unmuting conversations. 1144 */ 1145 public function test_unmute_conversations() { 1146 global $DB; 1147 1148 $this->resetAfterTest(true); 1149 1150 $user1 = self::getDataGenerator()->create_user(); 1151 $user2 = self::getDataGenerator()->create_user(); 1152 1153 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1154 [$user1->id, $user2->id]); 1155 1156 $this->setUser($user1); 1157 1158 // Mute the conversation. 1159 \core_message\api::mute_conversation($user1->id, $conversation->id); 1160 1161 // Unmuting a conversation. 1162 $return = core_message_external::unmute_conversations($user1->id, [$conversation->id]); 1163 $return = external_api::clean_returnvalue(core_message_external::unmute_conversations_returns(), $return); 1164 $this->assertEquals(array(), $return); 1165 1166 $this->assertEquals(0, $DB->count_records('message_conversation_actions')); 1167 1168 // Unmuting a conversation which is already unmuted. 1169 $return = core_message_external::unmute_conversations($user1->id, [$conversation->id]); 1170 $return = external_api::clean_returnvalue(core_message_external::unmute_conversations_returns(), $return); 1171 $this->assertEquals(array(), $return); 1172 1173 $this->assertEquals(0, $DB->count_records('message_conversation_actions')); 1174 } 1175 1176 /** 1177 * Test unmuting a conversation with messaging disabled. 1178 */ 1179 public function test_unmute_conversation_messaging_disabled() { 1180 global $CFG; 1181 1182 $this->resetAfterTest(); 1183 1184 // Create some skeleton data just so we can call the WS. 1185 $user1 = self::getDataGenerator()->create_user(); 1186 $user2 = self::getDataGenerator()->create_user(); 1187 1188 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1189 [$user1->id, $user2->id]); 1190 1191 $this->setUser($user1); 1192 1193 // Disable messaging. 1194 $CFG->messaging = 0; 1195 1196 // Ensure an exception is thrown. 1197 $this->expectException('moodle_exception'); 1198 core_message_external::unmute_conversations($user1->id, [$user2->id]); 1199 } 1200 1201 /** 1202 * Test unmuting a conversation with no permission. 1203 */ 1204 public function test_unmute_conversation_no_permission() { 1205 $this->resetAfterTest(); 1206 1207 // Create some skeleton data just so we can call the WS. 1208 $user1 = self::getDataGenerator()->create_user(); 1209 $user2 = self::getDataGenerator()->create_user(); 1210 $user3 = self::getDataGenerator()->create_user(); 1211 1212 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 1213 [$user1->id, $user2->id]); 1214 1215 $this->setUser($user3); 1216 1217 // Ensure an exception is thrown. 1218 $this->expectException('required_capability_exception'); 1219 core_message_external::unmute_conversations($user1->id, [$conversation->id]); 1220 } 1221 1222 /** 1223 * Test blocking a user. 1224 */ 1225 public function test_block_user() { 1226 global $DB; 1227 1228 $this->resetAfterTest(true); 1229 1230 $user1 = self::getDataGenerator()->create_user(); 1231 $user2 = self::getDataGenerator()->create_user(); 1232 1233 $this->setUser($user1); 1234 1235 // Blocking a user. 1236 $return = core_message_external::block_user($user1->id, $user2->id); 1237 $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return); 1238 $this->assertEquals(array(), $return); 1239 1240 // Get list of blocked users. 1241 $record = $DB->get_record('message_users_blocked', []); 1242 1243 $this->assertEquals($user1->id, $record->userid); 1244 $this->assertEquals($user2->id, $record->blockeduserid); 1245 1246 // Blocking a user who is already blocked. 1247 $return = core_message_external::block_user($user1->id, $user2->id); 1248 $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return); 1249 $this->assertEquals(array(), $return); 1250 1251 $this->assertEquals(1, $DB->count_records('message_users_blocked')); 1252 } 1253 1254 /** 1255 * Test blocking a user. 1256 */ 1257 public function test_block_user_when_ineffective() { 1258 global $DB; 1259 1260 $this->resetAfterTest(true); 1261 1262 $user1 = self::getDataGenerator()->create_user(); 1263 $user2 = self::getDataGenerator()->create_user(); 1264 1265 $this->setUser($user1); 1266 1267 $authenticateduser = $DB->get_record('role', array('shortname' => 'user')); 1268 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, context_system::instance(), true); 1269 1270 // Blocking a user. 1271 $return = core_message_external::block_user($user1->id, $user2->id); 1272 $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return); 1273 $this->assertEquals(array(), $return); 1274 1275 $this->assertEquals(0, $DB->count_records('message_users_blocked')); 1276 } 1277 1278 /** 1279 * Test blocking a user with messaging disabled. 1280 */ 1281 public function test_block_user_messaging_disabled() { 1282 global $CFG; 1283 1284 $this->resetAfterTest(); 1285 1286 // Create some skeleton data just so we can call the WS. 1287 $user1 = self::getDataGenerator()->create_user(); 1288 $user2 = self::getDataGenerator()->create_user(); 1289 1290 $this->setUser($user1); 1291 1292 // Disable messaging. 1293 $CFG->messaging = 0; 1294 1295 // Ensure an exception is thrown. 1296 $this->expectException('moodle_exception'); 1297 core_message_external::block_user($user1->id, $user2->id); 1298 } 1299 1300 /** 1301 * Test blocking a user with no permission. 1302 */ 1303 public function test_block_user_no_permission() { 1304 $this->resetAfterTest(); 1305 1306 // Create some skeleton data just so we can call the WS. 1307 $user1 = self::getDataGenerator()->create_user(); 1308 $user2 = self::getDataGenerator()->create_user(); 1309 $user3 = self::getDataGenerator()->create_user(); 1310 1311 $this->setUser($user3); 1312 1313 // Ensure an exception is thrown. 1314 $this->expectException('required_capability_exception'); 1315 core_message_external::block_user($user1->id, $user2->id); 1316 } 1317 1318 /** 1319 * Test unblocking a user. 1320 */ 1321 public function test_unblock_user() { 1322 global $DB; 1323 1324 $this->resetAfterTest(true); 1325 1326 $user1 = self::getDataGenerator()->create_user(); 1327 $user2 = self::getDataGenerator()->create_user(); 1328 1329 $this->setUser($user1); 1330 1331 // Block the user. 1332 \core_message\api::block_user($user1->id, $user2->id); 1333 1334 // Unblocking a user. 1335 $return = core_message_external::unblock_user($user1->id, $user2->id); 1336 $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return); 1337 $this->assertEquals(array(), $return); 1338 1339 $this->assertEquals(0, $DB->count_records('message_users_blocked')); 1340 1341 // Unblocking a user who is already unblocked. 1342 $return = core_message_external::unblock_user($user1->id, $user2->id); 1343 $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return); 1344 $this->assertEquals(array(), $return); 1345 1346 $this->assertEquals(0, $DB->count_records('message_users_blocked')); 1347 } 1348 1349 /** 1350 * Test unblocking a user with messaging disabled. 1351 */ 1352 public function test_unblock_user_messaging_disabled() { 1353 global $CFG; 1354 1355 $this->resetAfterTest(); 1356 1357 // Create some skeleton data just so we can call the WS. 1358 $user1 = self::getDataGenerator()->create_user(); 1359 $user2 = self::getDataGenerator()->create_user(); 1360 1361 $this->setUser($user1); 1362 1363 // Disable messaging. 1364 $CFG->messaging = 0; 1365 1366 // Ensure an exception is thrown. 1367 $this->expectException('moodle_exception'); 1368 core_message_external::unblock_user($user1->id, $user2->id); 1369 } 1370 1371 /** 1372 * Test unblocking a user with no permission. 1373 */ 1374 public function test_unblock_user_no_permission() { 1375 $this->resetAfterTest(); 1376 1377 // Create some skeleton data just so we can call the WS. 1378 $user1 = self::getDataGenerator()->create_user(); 1379 $user2 = self::getDataGenerator()->create_user(); 1380 $user3 = self::getDataGenerator()->create_user(); 1381 1382 $this->setUser($user3); 1383 1384 // Ensure an exception is thrown. 1385 $this->expectException('required_capability_exception'); 1386 core_message_external::unblock_user($user1->id, $user2->id); 1387 } 1388 1389 /** 1390 * Test get_contacts. 1391 */ 1392 public function test_get_contacts() { 1393 $this->resetAfterTest(true); 1394 1395 $user1 = self::getDataGenerator()->create_user(); 1396 $user_stranger = self::getDataGenerator()->create_user(); 1397 $user_offline1 = self::getDataGenerator()->create_user(); 1398 $user_offline2 = self::getDataGenerator()->create_user(); 1399 $user_offline3 = self::getDataGenerator()->create_user(); 1400 $user_online = new stdClass(); 1401 $user_online->lastaccess = time(); 1402 $user_online = self::getDataGenerator()->create_user($user_online); 1403 $user_blocked = self::getDataGenerator()->create_user(); 1404 $noreplyuser = core_user::get_user(core_user::NOREPLY_USER); 1405 1406 // Login as user1. 1407 $this->setUser($user1); 1408 \core_message\api::add_contact($user1->id, $user_offline1->id); 1409 \core_message\api::add_contact($user1->id, $user_offline2->id); 1410 \core_message\api::add_contact($user1->id, $user_offline3->id); 1411 \core_message\api::add_contact($user1->id, $user_online->id); 1412 1413 // User_stranger sends a couple of messages to user1. 1414 $this->send_message($user_stranger, $user1, 'Hello there!'); 1415 $this->send_message($user_stranger, $user1, 'How you goin?'); 1416 $this->send_message($user_stranger, $user1, 'Cya!'); 1417 $this->send_message($noreplyuser, $user1, 'I am not a real user'); 1418 1419 // User_blocked sends a message to user1. 1420 $this->send_message($user_blocked, $user1, 'Here, have some spam.'); 1421 1422 // Retrieve the contacts of the user. 1423 $this->setUser($user1); 1424 $contacts = core_message_external::get_contacts(); 1425 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts); 1426 $this->assertCount(3, $contacts['offline']); 1427 $this->assertCount(1, $contacts['online']); 1428 $this->assertCount(3, $contacts['strangers']); 1429 core_message_external::block_contacts(array($user_blocked->id)); 1430 $this->assertDebuggingCalled(); 1431 $contacts = core_message_external::get_contacts(); 1432 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts); 1433 $this->assertCount(3, $contacts['offline']); 1434 $this->assertCount(1, $contacts['online']); 1435 $this->assertCount(2, $contacts['strangers']); 1436 1437 // Checking some of the fields returned. 1438 $stranger = array_pop($contacts['strangers']); 1439 1440 $this->assertEquals(core_user::NOREPLY_USER, $stranger['id']); 1441 $this->assertEquals(1, $stranger['unread']); 1442 1443 // Check that deleted users are not returned. 1444 delete_user($user_offline1); 1445 delete_user($user_stranger); 1446 delete_user($user_online); 1447 $contacts = core_message_external::get_contacts(); 1448 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts); 1449 $this->assertCount(2, $contacts['offline']); 1450 $this->assertCount(0, $contacts['online']); 1451 $this->assertCount(1, $contacts['strangers']); 1452 } 1453 1454 /** 1455 * Test search_contacts. 1456 * @expectedException moodle_exception 1457 */ 1458 public function test_search_contacts() { 1459 global $DB; 1460 $this->resetAfterTest(true); 1461 1462 $course1 = $this->getDataGenerator()->create_course(); 1463 $course2 = $this->getDataGenerator()->create_course(); 1464 1465 $user1 = new stdClass(); 1466 $user1->firstname = 'X'; 1467 $user1->lastname = 'X'; 1468 $user1 = $this->getDataGenerator()->create_user($user1); 1469 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 1470 $this->getDataGenerator()->enrol_user($user1->id, $course2->id); 1471 1472 $user2 = new stdClass(); 1473 $user2->firstname = 'Eric'; 1474 $user2->lastname = 'Cartman'; 1475 $user2 = self::getDataGenerator()->create_user($user2); 1476 $user3 = new stdClass(); 1477 $user3->firstname = 'Stan'; 1478 $user3->lastname = 'Marsh'; 1479 $user3 = self::getDataGenerator()->create_user($user3); 1480 self::getDataGenerator()->enrol_user($user3->id, $course1->id); 1481 $user4 = new stdClass(); 1482 $user4->firstname = 'Kyle'; 1483 $user4->lastname = 'Broflovski'; 1484 $user4 = self::getDataGenerator()->create_user($user4); 1485 $user5 = new stdClass(); 1486 $user5->firstname = 'Kenny'; 1487 $user5->lastname = 'McCormick'; 1488 $user5 = self::getDataGenerator()->create_user($user5); 1489 self::getDataGenerator()->enrol_user($user5->id, $course2->id); 1490 1491 $this->setUser($user1); 1492 1493 $results = core_message_external::search_contacts('r'); 1494 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results); 1495 $this->assertCount(5, $results); // Users 2 through 5 + admin 1496 1497 $results = core_message_external::search_contacts('r', true); 1498 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results); 1499 $this->assertCount(2, $results); 1500 1501 $results = core_message_external::search_contacts('Kyle', false); 1502 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results); 1503 $this->assertCount(1, $results); 1504 $result = reset($results); 1505 $this->assertEquals($user4->id, $result['id']); 1506 1507 $results = core_message_external::search_contacts('y', false); 1508 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results); 1509 $this->assertCount(2, $results); 1510 1511 $results = core_message_external::search_contacts('y', true); 1512 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results); 1513 $this->assertCount(1, $results); 1514 $result = reset($results); 1515 $this->assertEquals($user5->id, $result['id']); 1516 1517 // Empty query, will throw an exception. 1518 $results = core_message_external::search_contacts(''); 1519 } 1520 1521 /** 1522 * Test get_messages. 1523 */ 1524 public function test_get_messages() { 1525 global $CFG, $DB; 1526 $this->resetAfterTest(true); 1527 1528 $this->preventResetByRollback(); 1529 // This mark the messages as read!. 1530 $sink = $this->redirectMessages(); 1531 1532 $user1 = self::getDataGenerator()->create_user(); 1533 $user2 = self::getDataGenerator()->create_user(); 1534 $user3 = self::getDataGenerator()->create_user(); 1535 1536 $course = self::getDataGenerator()->create_course(); 1537 1538 // Send a message from one user to another. 1539 message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE); 1540 message_post_message($user1, $user3, 'some random text 2', FORMAT_MOODLE); 1541 message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE); 1542 message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE); 1543 message_post_message($user3, $user1, 'some random text 5', FORMAT_MOODLE); 1544 1545 $this->setUser($user1); 1546 // Get read conversations from user1 to user2. 1547 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0); 1548 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1549 $this->assertCount(1, $messages['messages']); 1550 1551 // Delete the message. 1552 $message = array_shift($messages['messages']); 1553 \core_message\api::delete_message($user1->id, $message['id']); 1554 1555 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0); 1556 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1557 $this->assertCount(0, $messages['messages']); 1558 1559 // Get unread conversations from user1 to user2. 1560 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', false, true, 0, 0); 1561 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1562 $this->assertCount(0, $messages['messages']); 1563 1564 // Get read messages send from user1. 1565 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0); 1566 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1567 $this->assertCount(1, $messages['messages']); 1568 1569 $this->setUser($user2); 1570 // Get read conversations from any user to user2. 1571 $messages = core_message_external::get_messages($user2->id, 0, 'conversations', true, true, 0, 0); 1572 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1573 $this->assertCount(2, $messages['messages']); 1574 1575 // Conversations from user3 to user2. 1576 $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0); 1577 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1578 $this->assertCount(1, $messages['messages']); 1579 1580 // Delete the message. 1581 $message = array_shift($messages['messages']); 1582 \core_message\api::delete_message($user2->id, $message['id']); 1583 1584 $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0); 1585 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1586 $this->assertCount(0, $messages['messages']); 1587 1588 $this->setUser($user3); 1589 // Get read notifications received by user3. 1590 $messages = core_message_external::get_messages($user3->id, 0, 'notifications', true, true, 0, 0); 1591 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1592 $this->assertCount(0, $messages['messages']); 1593 1594 // Now, create some notifications... 1595 // We are creating fake notifications but based on real ones. 1596 1597 // This one comes from a disabled plugin's provider and therefore is not sent. 1598 $eventdata = new \core\message\message(); 1599 $eventdata->courseid = $course->id; 1600 $eventdata->notification = 1; 1601 $eventdata->modulename = 'moodle'; 1602 $eventdata->component = 'enrol_paypal'; 1603 $eventdata->name = 'paypal_enrolment'; 1604 $eventdata->userfrom = get_admin(); 1605 $eventdata->userto = $user1; 1606 $eventdata->subject = "Moodle: PayPal payment"; 1607 $eventdata->fullmessage = "Your PayPal payment is pending."; 1608 $eventdata->fullmessageformat = FORMAT_PLAIN; 1609 $eventdata->fullmessagehtml = ''; 1610 $eventdata->smallmessage = ''; 1611 message_send($eventdata); 1612 $this->assertDebuggingCalled('Attempt to send msg from a provider enrol_paypal/paypal_enrolment '. 1613 'that is inactive or not allowed for the user id='.$user1->id); 1614 1615 // This one omits notification = 1. 1616 $message = new \core\message\message(); 1617 $message->courseid = $course->id; 1618 $message->component = 'enrol_manual'; 1619 $message->name = 'expiry_notification'; 1620 $message->userfrom = $user2; 1621 $message->userto = $user1; 1622 $message->subject = 'Test: This is not a notification but otherwise is valid'; 1623 $message->fullmessage = 'Test: Full message'; 1624 $message->fullmessageformat = FORMAT_MARKDOWN; 1625 $message->fullmessagehtml = markdown_to_html($message->fullmessage); 1626 $message->smallmessage = $message->subject; 1627 $message->contexturlname = $course->fullname; 1628 $message->contexturl = (string)new moodle_url('/course/view.php', array('id' => $course->id)); 1629 message_send($message); 1630 1631 $message = new \core\message\message(); 1632 $message->courseid = $course->id; 1633 $message->notification = 1; 1634 $message->component = 'enrol_manual'; 1635 $message->name = 'expiry_notification'; 1636 $message->userfrom = $user2; 1637 $message->userto = $user1; 1638 $message->subject = 'Enrolment expired'; 1639 $message->fullmessage = 'Enrolment expired blah blah blah'; 1640 $message->fullmessageformat = FORMAT_MARKDOWN; 1641 $message->fullmessagehtml = markdown_to_html($message->fullmessage); 1642 $message->smallmessage = $message->subject; 1643 $message->contexturlname = $course->fullname; 1644 $message->contexturl = (string)new moodle_url('/course/view.php', array('id' => $course->id)); 1645 message_send($message); 1646 1647 $userfrom = core_user::get_noreply_user(); 1648 $userfrom->maildisplay = true; 1649 $eventdata = new \core\message\message(); 1650 $eventdata->courseid = $course->id; 1651 $eventdata->component = 'moodle'; 1652 $eventdata->name = 'badgecreatornotice'; 1653 $eventdata->userfrom = $userfrom; 1654 $eventdata->userto = $user1; 1655 $eventdata->notification = 1; 1656 $eventdata->subject = 'New badge'; 1657 $eventdata->fullmessage = format_text_email($eventdata->subject, FORMAT_HTML); 1658 $eventdata->fullmessageformat = FORMAT_PLAIN; 1659 $eventdata->fullmessagehtml = $eventdata->subject; 1660 $eventdata->smallmessage = $eventdata->subject; 1661 message_send($eventdata); 1662 1663 $eventdata = new \core\message\message(); 1664 $eventdata->courseid = $course->id; 1665 $eventdata->name = 'submission'; 1666 $eventdata->component = 'mod_feedback'; 1667 $eventdata->userfrom = $user1; 1668 $eventdata->userto = $user2; 1669 $eventdata->subject = 'Feedback submitted'; 1670 $eventdata->fullmessage = 'Feedback submitted from an user'; 1671 $eventdata->fullmessageformat = FORMAT_PLAIN; 1672 $eventdata->fullmessagehtml = '<strong>Feedback submitted</strong>'; 1673 $eventdata->smallmessage = ''; 1674 $eventdata->customdata = ['datakey' => 'data']; 1675 message_send($eventdata); 1676 1677 $this->setUser($user1); 1678 // Get read notifications from any user to user1. 1679 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 0); 1680 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1681 $this->assertCount(3, $messages['messages']); 1682 1683 // Get one read notifications from any user to user1. 1684 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 1); 1685 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1686 $this->assertCount(1, $messages['messages']); 1687 1688 // Get unread notifications from any user to user1. 1689 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', false, true, 0, 0); 1690 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1691 $this->assertCount(0, $messages['messages']); 1692 1693 // Get read both type of messages from any user to user1. 1694 $messages = core_message_external::get_messages($user1->id, 0, 'both', true, true, 0, 0); 1695 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1696 $this->assertCount(4, $messages['messages']); 1697 1698 // Get read notifications from no-reply-user to user1. 1699 $messages = core_message_external::get_messages($user1->id, $userfrom->id, 'notifications', true, true, 0, 0); 1700 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1701 $this->assertCount(1, $messages['messages']); 1702 1703 // Get notifications send by user1 to any user. 1704 $messages = core_message_external::get_messages(0, $user1->id, 'notifications', true, true, 0, 0); 1705 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1706 $this->assertCount(1, $messages['messages']); 1707 // Check we receive custom data as a unserialisable json. 1708 $this->assertObjectHasAttribute('datakey', json_decode($messages['messages'][0]['customdata'])); 1709 $this->assertEquals('mod_feedback', $messages['messages'][0]['component']); 1710 $this->assertEquals('submission', $messages['messages'][0]['eventtype']); 1711 1712 // Test warnings. 1713 $CFG->messaging = 0; 1714 1715 $messages = core_message_external::get_messages(0, $user1->id, 'both', true, true, 0, 0); 1716 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1717 $this->assertCount(1, $messages['warnings']); 1718 1719 // Test exceptions. 1720 1721 // Messaging disabled. 1722 try { 1723 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0); 1724 $this->fail('Exception expected due messaging disabled.'); 1725 } catch (moodle_exception $e) { 1726 $this->assertEquals('disabled', $e->errorcode); 1727 } 1728 1729 $CFG->messaging = 1; 1730 1731 // Invalid users. 1732 try { 1733 $messages = core_message_external::get_messages(0, 0, 'conversations', true, true, 0, 0); 1734 $this->fail('Exception expected due invalid users.'); 1735 } catch (moodle_exception $e) { 1736 $this->assertEquals('accessdenied', $e->errorcode); 1737 } 1738 1739 // Invalid user ids. 1740 try { 1741 $messages = core_message_external::get_messages(2500, 0, 'conversations', true, true, 0, 0); 1742 $this->fail('Exception expected due invalid users.'); 1743 } catch (moodle_exception $e) { 1744 $this->assertEquals('invaliduser', $e->errorcode); 1745 } 1746 1747 // Invalid users (permissions). 1748 $this->setUser($user2); 1749 try { 1750 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0); 1751 $this->fail('Exception expected due invalid user.'); 1752 } catch (moodle_exception $e) { 1753 $this->assertEquals('accessdenied', $e->errorcode); 1754 } 1755 1756 } 1757 1758 /** 1759 * Test get_messages where we want all messages from a user, sent to any user. 1760 */ 1761 public function test_get_messages_useridto_all() { 1762 $this->resetAfterTest(true); 1763 1764 $user1 = self::getDataGenerator()->create_user(); 1765 $user2 = self::getDataGenerator()->create_user(); 1766 $user3 = self::getDataGenerator()->create_user(); 1767 1768 $this->setUser($user1); 1769 1770 // Send a message from user 1 to two other users. 1771 $this->send_message($user1, $user2, 'some random text 1', 0, 1); 1772 $this->send_message($user1, $user3, 'some random text 2', 0, 2); 1773 1774 // Get messages sent from user 1. 1775 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', false, false, 0, 0); 1776 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1777 1778 // Confirm the data is correct. 1779 $messages = $messages['messages']; 1780 $this->assertCount(2, $messages); 1781 1782 $message1 = array_shift($messages); 1783 $message2 = array_shift($messages); 1784 1785 $this->assertEquals($user1->id, $message1['useridfrom']); 1786 $this->assertEquals($user2->id, $message1['useridto']); 1787 1788 $this->assertEquals($user1->id, $message2['useridfrom']); 1789 $this->assertEquals($user3->id, $message2['useridto']); 1790 } 1791 1792 /** 1793 * Test get_messages where we want all messages to a user, sent by any user. 1794 */ 1795 public function test_get_messages_useridfrom_all() { 1796 $this->resetAfterTest(); 1797 1798 $user1 = self::getDataGenerator()->create_user(); 1799 $user2 = self::getDataGenerator()->create_user(); 1800 $user3 = self::getDataGenerator()->create_user(); 1801 1802 $this->setUser($user1); 1803 1804 // Send a message to user 1 from two other users. 1805 $this->send_message($user2, $user1, 'some random text 1', 0, 1); 1806 $this->send_message($user3, $user1, 'some random text 2', 0, 2); 1807 1808 // Get messages sent to user 1. 1809 $messages = core_message_external::get_messages($user1->id, 0, 'conversations', false, false, 0, 0); 1810 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages); 1811 1812 // Confirm the data is correct. 1813 $messages = $messages['messages']; 1814 $this->assertCount(2, $messages); 1815 1816 $message1 = array_shift($messages); 1817 $message2 = array_shift($messages); 1818 1819 $this->assertEquals($user2->id, $message1['useridfrom']); 1820 $this->assertEquals($user1->id, $message1['useridto']); 1821 1822 $this->assertEquals($user3->id, $message2['useridfrom']); 1823 $this->assertEquals($user1->id, $message2['useridto']); 1824 } 1825 1826 /** 1827 * Test get_blocked_users. 1828 */ 1829 public function test_get_blocked_users() { 1830 $this->resetAfterTest(true); 1831 1832 $user1 = self::getDataGenerator()->create_user(); 1833 $userstranger = self::getDataGenerator()->create_user(); 1834 $useroffline1 = self::getDataGenerator()->create_user(); 1835 $useroffline2 = self::getDataGenerator()->create_user(); 1836 $userblocked = self::getDataGenerator()->create_user(); 1837 1838 // Login as user1. 1839 $this->setUser($user1); 1840 1841 \core_message\api::add_contact($user1->id, $useroffline1->id); 1842 \core_message\api::add_contact($user1->id, $useroffline2->id); 1843 1844 // The userstranger sends a couple of messages to user1. 1845 $this->send_message($userstranger, $user1, 'Hello there!'); 1846 $this->send_message($userstranger, $user1, 'How you goin?'); 1847 1848 // The userblocked sends a message to user1. 1849 // Note that this user is not blocked at this point. 1850 $this->send_message($userblocked, $user1, 'Here, have some spam.'); 1851 1852 // Retrieve the list of blocked users. 1853 $this->setUser($user1); 1854 $blockedusers = core_message_external::get_blocked_users($user1->id); 1855 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers); 1856 $this->assertCount(0, $blockedusers['users']); 1857 1858 // Block the $userblocked and retrieve again the list. 1859 core_message_external::block_contacts(array($userblocked->id)); 1860 $this->assertDebuggingCalled(); 1861 $blockedusers = core_message_external::get_blocked_users($user1->id); 1862 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers); 1863 $this->assertCount(1, $blockedusers['users']); 1864 1865 // Remove the $userblocked and check that the list now is empty. 1866 delete_user($userblocked); 1867 $blockedusers = core_message_external::get_blocked_users($user1->id); 1868 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers); 1869 $this->assertCount(0, $blockedusers['users']); 1870 } 1871 1872 /** 1873 * Test mark_message_read. 1874 */ 1875 public function test_mark_message_read() { 1876 $this->resetAfterTest(true); 1877 1878 $user1 = self::getDataGenerator()->create_user(); 1879 $user2 = self::getDataGenerator()->create_user(); 1880 $user3 = self::getDataGenerator()->create_user(); 1881 1882 // Login as user1. 1883 $this->setUser($user1); 1884 \core_message\api::add_contact($user1->id, $user2->id); 1885 \core_message\api::add_contact($user1->id, $user3->id); 1886 1887 // The user2 sends a couple of messages to user1. 1888 $this->send_message($user2, $user1, 'Hello there!'); 1889 $this->send_message($user2, $user1, 'How you goin?'); 1890 $this->send_message($user3, $user1, 'How you goin?'); 1891 $this->send_message($user3, $user2, 'How you goin?'); 1892 1893 // Retrieve all messages sent by user2 (they are currently unread). 1894 $lastmessages = message_get_messages($user1->id, $user2->id, 0, false); 1895 1896 $messageids = array(); 1897 foreach ($lastmessages as $m) { 1898 $messageid = core_message_external::mark_message_read($m->id, time()); 1899 $messageids[] = external_api::clean_returnvalue(core_message_external::mark_message_read_returns(), $messageid); 1900 } 1901 1902 // Retrieve all messages sent (they are currently read). 1903 $lastmessages = message_get_messages($user1->id, $user2->id, 0, true); 1904 $this->assertCount(2, $lastmessages); 1905 $this->assertArrayHasKey($messageids[0]['messageid'], $lastmessages); 1906 $this->assertArrayHasKey($messageids[1]['messageid'], $lastmessages); 1907 1908 // Retrieve all messages sent by any user (that are currently unread). 1909 $lastmessages = message_get_messages($user1->id, 0, 0, false); 1910 $this->assertCount(1, $lastmessages); 1911 1912 // Invalid message ids. 1913 try { 1914 $messageid = core_message_external::mark_message_read(1337, time()); 1915 $this->fail('Exception expected due invalid messageid.'); 1916 } catch (dml_missing_record_exception $e) { 1917 $this->assertEquals('invalidrecordunknown', $e->errorcode); 1918 } 1919 1920 // A message to a different user. 1921 $lastmessages = message_get_messages($user2->id, $user3->id, 0, false); 1922 $messageid = array_pop($lastmessages)->id; 1923 try { 1924 $messageid = core_message_external::mark_message_read($messageid, time()); 1925 $this->fail('Exception expected due invalid messageid.'); 1926 } catch (invalid_parameter_exception $e) { 1927 $this->assertEquals('invalidparameter', $e->errorcode); 1928 } 1929 } 1930 1931 /** 1932 * Test mark_notification_read. 1933 */ 1934 public function test_mark_notification_read() { 1935 $this->resetAfterTest(true); 1936 1937 $user1 = self::getDataGenerator()->create_user(); 1938 $user2 = self::getDataGenerator()->create_user(); 1939 $user3 = self::getDataGenerator()->create_user(); 1940 1941 // Login as user1. 1942 $this->setUser($user1); 1943 \core_message\api::add_contact($user1->id, $user2->id); 1944 \core_message\api::add_contact($user1->id, $user3->id); 1945 1946 // The user2 sends a couple of notifications to user1. 1947 $this->send_message($user2, $user1, 'Hello there!', 1); 1948 $this->send_message($user2, $user1, 'How you goin?', 1); 1949 $this->send_message($user3, $user1, 'How you goin?', 1); 1950 $this->send_message($user3, $user2, 'How you goin?', 1); 1951 1952 // Retrieve all notifications sent by user2 (they are currently unread). 1953 $lastnotifications = message_get_messages($user1->id, $user2->id, 1, false); 1954 1955 $notificationids = array(); 1956 foreach ($lastnotifications as $n) { 1957 $notificationid = core_message_external::mark_notification_read($n->id, time()); 1958 $notificationids[] = external_api::clean_returnvalue(core_message_external::mark_notification_read_returns(), 1959 $notificationid); 1960 } 1961 1962 // Retrieve all notifications sent (they are currently read). 1963 $lastnotifications = message_get_messages($user1->id, $user2->id, 1, true); 1964 $this->assertCount(2, $lastnotifications); 1965 $this->assertArrayHasKey($notificationids[1]['notificationid'], $lastnotifications); 1966 $this->assertArrayHasKey($notificationids[0]['notificationid'], $lastnotifications); 1967 1968 // Retrieve all notifications sent by any user (that are currently unread). 1969 $lastnotifications = message_get_messages($user1->id, 0, 1, false); 1970 $this->assertCount(1, $lastnotifications); 1971 1972 // Invalid notification ids. 1973 try { 1974 $notificationid = core_message_external::mark_notification_read(1337, time()); 1975 $this->fail('Exception expected due invalid notificationid.'); 1976 } catch (dml_missing_record_exception $e) { 1977 $this->assertEquals('invalidrecord', $e->errorcode); 1978 } 1979 1980 // A notification to a different user. 1981 $lastnotifications = message_get_messages($user2->id, $user3->id, 1, false); 1982 $notificationid = array_pop($lastnotifications)->id; 1983 try { 1984 $notificationid = core_message_external::mark_notification_read($notificationid, time()); 1985 $this->fail('Exception expected due invalid notificationid.'); 1986 } catch (invalid_parameter_exception $e) { 1987 $this->assertEquals('invalidparameter', $e->errorcode); 1988 } 1989 } 1990 1991 /** 1992 * Test delete_message. 1993 */ 1994 public function test_delete_message() { 1995 global $DB; 1996 $this->resetAfterTest(true); 1997 1998 $user1 = self::getDataGenerator()->create_user(); 1999 $user2 = self::getDataGenerator()->create_user(); 2000 $user3 = self::getDataGenerator()->create_user(); 2001 $user4 = self::getDataGenerator()->create_user(); 2002 2003 // Login as user1. 2004 $this->setUser($user1); 2005 \core_message\api::add_contact($user1->id, $user2->id); 2006 \core_message\api::add_contact($user1->id, $user3->id); 2007 2008 // User user1 does not interchange messages with user3. 2009 $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE); 2010 $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE); 2011 $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE); 2012 $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE); 2013 2014 // Retrieve all messages sent by user2 (they are currently unread). 2015 $lastmessages = message_get_messages($user1->id, $user2->id, 0, false); 2016 2017 // Delete a message not read, as a user from. 2018 $result = core_message_external::delete_message($m1to2, $user1->id, false); 2019 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); 2020 $this->assertTrue($result['status']); 2021 $this->assertCount(0, $result['warnings']); 2022 $mua = $DB->get_record('message_user_actions', array('messageid' => $m1to2, 'userid' => $user1->id)); 2023 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua->action); 2024 2025 // Try to delete the same message again. 2026 $result = core_message_external::delete_message($m1to2, $user1->id, false); 2027 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); 2028 $this->assertFalse($result['status']); 2029 2030 // Try to delete a message that does not belong to me. 2031 try { 2032 $messageid = core_message_external::delete_message($m2to3, $user3->id, false); 2033 $this->fail('Exception expected due invalid messageid.'); 2034 } catch (moodle_exception $e) { 2035 $this->assertEquals('You do not have permission to delete this message', $e->errorcode); 2036 } 2037 2038 $this->setUser($user3); 2039 // Delete a message not read, as a user to. 2040 $result = core_message_external::delete_message($m2to3, $user3->id, false); 2041 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); 2042 $this->assertTrue($result['status']); 2043 $this->assertCount(0, $result['warnings']); 2044 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m2to3, 'userid' => $user3->id, 2045 'action' => \core_message\api::MESSAGE_ACTION_DELETED))); 2046 2047 // Delete a message read. 2048 $message = $DB->get_record('messages', ['id' => $m3to2]); 2049 \core_message\api::mark_message_as_read($user3->id, $message, time()); 2050 $result = core_message_external::delete_message($m3to2, $user3->id); 2051 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); 2052 $this->assertTrue($result['status']); 2053 $this->assertCount(0, $result['warnings']); 2054 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to2, 'userid' => $user3->id, 2055 'action' => \core_message\api::MESSAGE_ACTION_DELETED))); 2056 2057 // Invalid message ids. 2058 try { 2059 $result = core_message_external::delete_message(-1, $user1->id); 2060 $this->fail('Exception expected due invalid messageid.'); 2061 } catch (dml_missing_record_exception $e) { 2062 $this->assertEquals('invalidrecord', $e->errorcode); 2063 } 2064 2065 // Invalid user. 2066 try { 2067 $result = core_message_external::delete_message($m1to2, -1, false); 2068 $this->fail('Exception expected due invalid user.'); 2069 } catch (moodle_exception $e) { 2070 $this->assertEquals('invaliduser', $e->errorcode); 2071 } 2072 2073 // Not active user. 2074 delete_user($user2); 2075 try { 2076 $result = core_message_external::delete_message($m1to2, $user2->id, false); 2077 $this->fail('Exception expected due invalid user.'); 2078 } catch (moodle_exception $e) { 2079 $this->assertEquals('userdeleted', $e->errorcode); 2080 } 2081 2082 // Now, as an admin, try to delete any message. 2083 $this->setAdminUser(); 2084 $result = core_message_external::delete_message($m3to4, $user4->id, false); 2085 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); 2086 $this->assertTrue($result['status']); 2087 $this->assertCount(0, $result['warnings']); 2088 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to4, 'userid' => $user4->id, 2089 'action' => \core_message\api::MESSAGE_ACTION_DELETED))); 2090 2091 } 2092 2093 public function test_mark_all_notifications_as_read_invalid_user_exception() { 2094 $this->resetAfterTest(true); 2095 2096 $this->expectException('moodle_exception'); 2097 core_message_external::mark_all_notifications_as_read(-2132131, 0); 2098 } 2099 2100 public function test_mark_all_notifications_as_read_access_denied_exception() { 2101 $this->resetAfterTest(true); 2102 2103 $sender = $this->getDataGenerator()->create_user(); 2104 $user = $this->getDataGenerator()->create_user(); 2105 2106 $this->setUser($user); 2107 $this->expectException('moodle_exception'); 2108 core_message_external::mark_all_notifications_as_read($sender->id, 0); 2109 } 2110 2111 public function test_mark_all_notifications_as_read_missing_from_user_exception() { 2112 $this->resetAfterTest(true); 2113 2114 $sender = $this->getDataGenerator()->create_user(); 2115 2116 $this->setUser($sender); 2117 $this->expectException('moodle_exception'); 2118 core_message_external::mark_all_notifications_as_read($sender->id, 99999); 2119 } 2120 2121 public function test_mark_all_notifications_as_read() { 2122 global $DB; 2123 2124 $this->resetAfterTest(true); 2125 2126 $sender1 = $this->getDataGenerator()->create_user(); 2127 $sender2 = $this->getDataGenerator()->create_user(); 2128 $sender3 = $this->getDataGenerator()->create_user(); 2129 $recipient = $this->getDataGenerator()->create_user(); 2130 2131 $this->setUser($recipient); 2132 2133 $this->send_message($sender1, $recipient, 'Notification', 1); 2134 $this->send_message($sender1, $recipient, 'Notification', 1); 2135 $this->send_message($sender2, $recipient, 'Notification', 1); 2136 $this->send_message($sender2, $recipient, 'Notification', 1); 2137 $this->send_message($sender3, $recipient, 'Notification', 1); 2138 $this->send_message($sender3, $recipient, 'Notification', 1); 2139 2140 core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id); 2141 $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]); 2142 $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]); 2143 2144 $this->assertCount(2, $readnotifications); 2145 $this->assertCount(4, $unreadnotifications); 2146 2147 core_message_external::mark_all_notifications_as_read($recipient->id, 0); 2148 $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]); 2149 $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]); 2150 2151 $this->assertCount(6, $readnotifications); 2152 $this->assertCount(0, $unreadnotifications); 2153 } 2154 2155 public function test_mark_all_notifications_as_read_time_created_to() { 2156 global $DB; 2157 2158 $this->resetAfterTest(true); 2159 2160 $sender1 = $this->getDataGenerator()->create_user(); 2161 $sender2 = $this->getDataGenerator()->create_user(); 2162 2163 $recipient = $this->getDataGenerator()->create_user(); 2164 $this->setUser($recipient); 2165 2166 // Record messages as sent on one second intervals. 2167 $time = time(); 2168 2169 $this->send_message($sender1, $recipient, 'Message 1', 1, $time); 2170 $this->send_message($sender2, $recipient, 'Message 2', 1, $time + 1); 2171 $this->send_message($sender1, $recipient, 'Message 3', 1, $time + 2); 2172 $this->send_message($sender2, $recipient, 'Message 4', 1, $time + 3); 2173 2174 // Mark notifications sent from sender1 up until the second message; should only mark the first notification as read. 2175 core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id, $time + 1); 2176 2177 $params = [$recipient->id]; 2178 2179 $this->assertEquals(1, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); 2180 $this->assertEquals(3, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); 2181 2182 // Mark all notifications as read from any sender up to the time the third message was sent. 2183 core_message_external::mark_all_notifications_as_read($recipient->id, 0, $time + 2); 2184 2185 $this->assertEquals(3, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); 2186 $this->assertEquals(1, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); 2187 2188 // Mark all notifications as read from any sender with a time after all messages were sent. 2189 core_message_external::mark_all_notifications_as_read($recipient->id, 0, $time + 10); 2190 2191 $this->assertEquals(4, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); 2192 $this->assertEquals(0, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); 2193 } 2194 2195 /** 2196 * Test get_user_notification_preferences 2197 */ 2198 public function test_get_user_notification_preferences() { 2199 $this->resetAfterTest(true); 2200 2201 $user = self::getDataGenerator()->create_user(); 2202 $this->setUser($user); 2203 2204 // Set a couple of preferences to test. 2205 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user); 2206 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user); 2207 2208 $prefs = core_message_external::get_user_notification_preferences(); 2209 $prefs = external_api::clean_returnvalue(core_message_external::get_user_notification_preferences_returns(), $prefs); 2210 // Check processors. 2211 $this->assertGreaterThanOrEqual(2, count($prefs['preferences']['processors'])); 2212 $this->assertEquals($user->id, $prefs['preferences']['userid']); 2213 2214 // Check components. 2215 $this->assertGreaterThanOrEqual(8, count($prefs['preferences']['components'])); 2216 2217 // Check some preferences that we previously set. 2218 $found = 0; 2219 foreach ($prefs['preferences']['components'] as $component) { 2220 foreach ($component['notifications'] as $prefdata) { 2221 if ($prefdata['preferencekey'] != 'message_provider_mod_assign_assign_notification') { 2222 continue; 2223 } 2224 foreach ($prefdata['processors'] as $processor) { 2225 if ($processor['name'] == 'popup') { 2226 $this->assertTrue($processor['loggedin']['checked']); 2227 $found++; 2228 } else if ($processor['name'] == 'email') { 2229 $this->assertTrue($processor['loggedoff']['checked']); 2230 $found++; 2231 } 2232 } 2233 } 2234 } 2235 $this->assertEquals(2, $found); 2236 } 2237 2238 /** 2239 * Test get_user_notification_preferences permissions 2240 */ 2241 public function test_get_user_notification_preferences_permissions() { 2242 $this->resetAfterTest(true); 2243 2244 $user = self::getDataGenerator()->create_user(); 2245 $otheruser = self::getDataGenerator()->create_user(); 2246 $this->setUser($user); 2247 2248 $this->expectException('moodle_exception'); 2249 $prefs = core_message_external::get_user_notification_preferences($otheruser->id); 2250 } 2251 2252 /** 2253 * Tests searching users in a course. 2254 */ 2255 public function test_data_for_messagearea_search_users_in_course() { 2256 $this->resetAfterTest(true); 2257 2258 // Create some users. 2259 $user1 = new stdClass(); 2260 $user1->firstname = 'User'; 2261 $user1->lastname = 'One'; 2262 $user1 = self::getDataGenerator()->create_user($user1); 2263 2264 // The person doing the search. 2265 $this->setUser($user1); 2266 2267 // Set the second user's status to online by setting their last access to now. 2268 $user2 = new stdClass(); 2269 $user2->firstname = 'User'; 2270 $user2->lastname = 'Two'; 2271 $user2->lastaccess = time(); 2272 $user2 = self::getDataGenerator()->create_user($user2); 2273 2274 // Block the second user. 2275 \core_message\api::block_user($user1->id, $user2->id); 2276 2277 $user3 = new stdClass(); 2278 $user3->firstname = 'User'; 2279 $user3->lastname = 'Three'; 2280 $user3 = self::getDataGenerator()->create_user($user3); 2281 2282 // Create a course. 2283 $course1 = new stdClass(); 2284 $course1->fullname = 'Course'; 2285 $course1->shortname = 'One'; 2286 $course1 = $this->getDataGenerator()->create_course(); 2287 2288 // Enrol the user we are doing the search for and one user in the course. 2289 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 2290 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 2291 2292 // Perform a search. 2293 $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User'); 2294 2295 // We need to execute the return values cleaning process to simulate the web service. 2296 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(), 2297 $result); 2298 2299 // Check that we only retrieved a user that was enrolled, and that the user performing the search was not returned. 2300 $users = $result['contacts']; 2301 $this->assertCount(1, $users); 2302 2303 $user = $users[0]; 2304 $this->assertEquals($user2->id, $user['userid']); 2305 $this->assertEquals(fullname($user2), $user['fullname']); 2306 $this->assertFalse($user['ismessaging']); 2307 $this->assertFalse($user['sentfromcurrentuser']); 2308 $this->assertNull($user['lastmessage']); 2309 $this->assertNull($user['messageid']); 2310 $this->assertNull($user['isonline']); 2311 $this->assertFalse($user['isread']); 2312 $this->assertTrue($user['isblocked']); 2313 $this->assertNull($user['unreadcount']); 2314 } 2315 2316 /** 2317 * Tests searching users in course as another user. 2318 */ 2319 public function test_data_for_messagearea_search_users_in_course_as_other_user() { 2320 $this->resetAfterTest(true); 2321 2322 // The person doing the search for another user. 2323 $this->setAdminUser(); 2324 2325 // Create some users. 2326 $user1 = new stdClass(); 2327 $user1->firstname = 'User'; 2328 $user1->lastname = 'One'; 2329 $user1 = self::getDataGenerator()->create_user($user1); 2330 2331 $user2 = new stdClass(); 2332 $user2->firstname = 'User'; 2333 $user2->lastname = 'Two'; 2334 $user2 = self::getDataGenerator()->create_user($user2); 2335 2336 $user3 = new stdClass(); 2337 $user3->firstname = 'User'; 2338 $user3->lastname = 'Three'; 2339 $user3 = self::getDataGenerator()->create_user($user3); 2340 2341 // Create a course. 2342 $course1 = new stdClass(); 2343 $course1->fullname = 'Course'; 2344 $course1->shortname = 'One'; 2345 $course1 = $this->getDataGenerator()->create_course(); 2346 2347 // Enrol the user we are doing the search for and one user in the course. 2348 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 2349 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 2350 2351 // Perform a search. 2352 $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User'); 2353 2354 // We need to execute the return values cleaning process to simulate the web service server. 2355 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(), 2356 $result); 2357 2358 // Check that we got the user enrolled, and that the user we are performing the search on behalf of was not returned. 2359 $users = $result['contacts']; 2360 $this->assertCount(1, $users); 2361 2362 $user = $users[0]; 2363 $this->assertEquals($user2->id, $user['userid']); 2364 $this->assertEquals(fullname($user2), $user['fullname']); 2365 $this->assertFalse($user['ismessaging']); 2366 $this->assertFalse($user['sentfromcurrentuser']); 2367 $this->assertNull($user['lastmessage']); 2368 $this->assertNull($user['messageid']); 2369 $this->assertFalse($user['isonline']); 2370 $this->assertFalse($user['isread']); 2371 $this->assertFalse($user['isblocked']); 2372 $this->assertNull($user['unreadcount']); 2373 } 2374 2375 /** 2376 * Tests searching users in course as another user without the proper capabilities. 2377 */ 2378 public function test_data_for_messagearea_search_users_in_course_as_other_user_without_cap() { 2379 $this->resetAfterTest(true); 2380 2381 // Create some users. 2382 $user1 = self::getDataGenerator()->create_user(); 2383 $user2 = self::getDataGenerator()->create_user(); 2384 2385 // The person doing the search for another user. 2386 $this->setUser($user1); 2387 2388 // Create a course. 2389 $course = $this->getDataGenerator()->create_course(); 2390 2391 // Ensure an exception is thrown. 2392 $this->expectException('moodle_exception'); 2393 core_message_external::data_for_messagearea_search_users_in_course($user2->id, $course->id, 'User'); 2394 $this->assertDebuggingCalled(); 2395 } 2396 2397 /** 2398 * Tests searching users in course with messaging disabled. 2399 */ 2400 public function test_data_for_messagearea_search_users_in_course_messaging_disabled() { 2401 global $CFG; 2402 2403 $this->resetAfterTest(true); 2404 2405 // Create some skeleton data just so we can call the WS.. 2406 $user = self::getDataGenerator()->create_user(); 2407 $course = $this->getDataGenerator()->create_course(); 2408 2409 // The person doing the search for another user. 2410 $this->setUser($user); 2411 2412 // Disable messaging. 2413 $CFG->messaging = 0; 2414 2415 // Ensure an exception is thrown. 2416 $this->expectException('moodle_exception'); 2417 core_message_external::data_for_messagearea_search_users_in_course($user->id, $course->id, 'User'); 2418 $this->assertDebuggingCalled(); 2419 } 2420 2421 /** 2422 * Tests searching users. 2423 */ 2424 public function test_data_for_messagearea_search_users() { 2425 $this->resetAfterTest(true); 2426 2427 // Create some users. 2428 $user1 = new stdClass(); 2429 $user1->firstname = 'User'; 2430 $user1->lastname = 'One'; 2431 $user1 = self::getDataGenerator()->create_user($user1); 2432 2433 // Set as the user performing the search. 2434 $this->setUser($user1); 2435 2436 $user2 = new stdClass(); 2437 $user2->firstname = 'User search'; 2438 $user2->lastname = 'Two'; 2439 $user2 = self::getDataGenerator()->create_user($user2); 2440 2441 $user3 = new stdClass(); 2442 $user3->firstname = 'User search'; 2443 $user3->lastname = 'Three'; 2444 $user3 = self::getDataGenerator()->create_user($user3); 2445 2446 $user4 = new stdClass(); 2447 $user4->firstname = 'User'; 2448 $user4->lastname = 'Four'; 2449 $user4 = self::getDataGenerator()->create_user($user4); 2450 2451 $user5 = new stdClass(); 2452 $user5->firstname = 'User search'; 2453 $user5->lastname = 'Five'; 2454 $user5 = self::getDataGenerator()->create_user($user5); 2455 2456 $user6 = new stdClass(); 2457 $user6->firstname = 'User'; 2458 $user6->lastname = 'Six'; 2459 $user6 = self::getDataGenerator()->create_user($user6); 2460 2461 // Create some courses. 2462 $course1 = new stdClass(); 2463 $course1->fullname = 'Course search'; 2464 $course1->shortname = 'One'; 2465 $course1 = $this->getDataGenerator()->create_course($course1); 2466 2467 $course2 = new stdClass(); 2468 $course2->fullname = 'Course'; 2469 $course2->shortname = 'Two'; 2470 $course2 = $this->getDataGenerator()->create_course($course2); 2471 2472 $course3 = new stdClass(); 2473 $course3->fullname = 'Course'; 2474 $course3->shortname = 'Three search'; 2475 $course3 = $this->getDataGenerator()->create_course($course3); 2476 2477 $course4 = new stdClass(); 2478 $course4->fullname = 'Course Four'; 2479 $course4->shortname = 'CF100'; 2480 $course4 = $this->getDataGenerator()->create_course($course4); 2481 2482 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student'); 2483 $this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'student'); 2484 $this->getDataGenerator()->enrol_user($user1->id, $course3->id, 'student'); 2485 2486 // Add some users as contacts. 2487 \core_message\api::add_contact($user1->id, $user2->id); 2488 \core_message\api::add_contact($user1->id, $user3->id); 2489 \core_message\api::add_contact($user1->id, $user4->id); 2490 2491 // Perform a search $CFG->messagingallusers setting enabled. 2492 set_config('messagingallusers', 1); 2493 $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search'); 2494 2495 // We need to execute the return values cleaning process to simulate the web service server. 2496 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(), 2497 $result); 2498 2499 // Confirm that we returns contacts, courses and non-contacts. 2500 $contacts = $result['contacts']; 2501 $courses = $result['courses']; 2502 $noncontacts = $result['noncontacts']; 2503 2504 // Check that we retrieved the correct contacts. 2505 $this->assertCount(2, $contacts); 2506 $this->assertEquals($user3->id, $contacts[0]['userid']); 2507 $this->assertEquals($user2->id, $contacts[1]['userid']); 2508 2509 // Check that we retrieved the correct courses. 2510 $this->assertCount(2, $courses); 2511 $this->assertEquals($course3->id, $courses[0]['id']); 2512 $this->assertEquals($course1->id, $courses[1]['id']); 2513 2514 // Check that we retrieved the correct non-contacts. 2515 $this->assertCount(1, $noncontacts); 2516 $this->assertEquals($user5->id, $noncontacts[0]['userid']); 2517 } 2518 2519 /** 2520 * Tests searching users as another user. 2521 */ 2522 public function test_data_for_messagearea_search_users_as_other_user() { 2523 $this->resetAfterTest(true); 2524 2525 // The person doing the search. 2526 $this->setAdminUser(); 2527 2528 // Create some users. 2529 $user1 = new stdClass(); 2530 $user1->firstname = 'User'; 2531 $user1->lastname = 'One'; 2532 $user1 = self::getDataGenerator()->create_user($user1); 2533 2534 $user2 = new stdClass(); 2535 $user2->firstname = 'User search'; 2536 $user2->lastname = 'Two'; 2537 $user2 = self::getDataGenerator()->create_user($user2); 2538 2539 $user3 = new stdClass(); 2540 $user3->firstname = 'User search'; 2541 $user3->lastname = 'Three'; 2542 $user3 = self::getDataGenerator()->create_user($user3); 2543 2544 $user4 = new stdClass(); 2545 $user4->firstname = 'User'; 2546 $user4->lastname = 'Four'; 2547 $user4 = self::getDataGenerator()->create_user($user4); 2548 2549 $user5 = new stdClass(); 2550 $user5->firstname = 'User search'; 2551 $user5->lastname = 'Five'; 2552 $user5 = self::getDataGenerator()->create_user($user5); 2553 2554 $user6 = new stdClass(); 2555 $user6->firstname = 'User'; 2556 $user6->lastname = 'Six'; 2557 $user6 = self::getDataGenerator()->create_user($user6); 2558 2559 // Create some courses. 2560 $course1 = new stdClass(); 2561 $course1->fullname = 'Course search'; 2562 $course1->shortname = 'One'; 2563 $course1 = $this->getDataGenerator()->create_course($course1); 2564 2565 $course2 = new stdClass(); 2566 $course2->fullname = 'Course'; 2567 $course2->shortname = 'Two'; 2568 $course2 = $this->getDataGenerator()->create_course($course2); 2569 2570 $course3 = new stdClass(); 2571 $course3->fullname = 'Course'; 2572 $course3->shortname = 'Three search'; 2573 $course3 = $this->getDataGenerator()->create_course($course3); 2574 2575 // Add some users as contacts. 2576 \core_message\api::add_contact($user1->id, $user2->id); 2577 \core_message\api::add_contact($user1->id, $user3->id); 2578 \core_message\api::add_contact($user1->id, $user4->id); 2579 2580 // Perform a search $CFG->messagingallusers setting enabled. 2581 set_config('messagingallusers', 1); 2582 $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search'); 2583 2584 // We need to execute the return values cleaning process to simulate the web service server. 2585 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(), 2586 $result); 2587 2588 // Confirm that we returns contacts, courses and non-contacts. 2589 $contacts = $result['contacts']; 2590 $courses = $result['courses']; 2591 $noncontacts = $result['noncontacts']; 2592 2593 // Check that we retrieved the correct contacts. 2594 $this->assertCount(2, $contacts); 2595 $this->assertEquals($user3->id, $contacts[0]['userid']); 2596 $this->assertEquals($user2->id, $contacts[1]['userid']); 2597 2598 // Check that we retrieved the correct courses. 2599 $this->assertCount(0, $courses); 2600 2601 // Check that we retrieved the correct non-contacts. 2602 $this->assertCount(1, $noncontacts); 2603 $this->assertEquals($user5->id, $noncontacts[0]['userid']); 2604 } 2605 2606 /** 2607 * Tests searching users as another user without the proper capabilities. 2608 */ 2609 public function test_data_for_messagearea_search_users_as_other_user_without_cap() { 2610 $this->resetAfterTest(true); 2611 2612 // Create some users. 2613 $user1 = self::getDataGenerator()->create_user(); 2614 $user2 = self::getDataGenerator()->create_user(); 2615 2616 // The person doing the search for another user. 2617 $this->setUser($user1); 2618 2619 // Ensure an exception is thrown. 2620 $this->expectException('moodle_exception'); 2621 core_message_external::data_for_messagearea_search_users($user2->id, 'User'); 2622 $this->assertDebuggingCalled(); 2623 } 2624 2625 /** 2626 * Tests searching users with messaging disabled. 2627 */ 2628 public function test_data_for_messagearea_search_users_messaging_disabled() { 2629 global $CFG; 2630 2631 $this->resetAfterTest(true); 2632 2633 // Create some skeleton data just so we can call the WS. 2634 $user = self::getDataGenerator()->create_user(); 2635 2636 // The person doing the search. 2637 $this->setUser($user); 2638 2639 // Disable messaging. 2640 $CFG->messaging = 0; 2641 2642 // Ensure an exception is thrown. 2643 $this->expectException('moodle_exception'); 2644 core_message_external::data_for_messagearea_search_users($user->id, 'User'); 2645 $this->assertDebuggingCalled(); 2646 } 2647 2648 /** 2649 * Tests searching for users when site-wide messaging is disabled. 2650 * 2651 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view. 2652 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's 2653 * profile. 2654 */ 2655 public function test_message_search_users_messagingallusers_disabled() { 2656 global $DB; 2657 $this->resetAfterTest(); 2658 2659 // Create some users. 2660 $users = []; 2661 foreach (range(1, 8) as $i) { 2662 $user = new stdClass(); 2663 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 2664 $user->lastname = $i; 2665 $user = $this->getDataGenerator()->create_user($user); 2666 $users[$i] = $user; 2667 } 2668 2669 // Enrol a few users in the same course, but leave them as non-contacts. 2670 $course1 = $this->getDataGenerator()->create_course(); 2671 $course2 = $this->getDataGenerator()->create_course(); 2672 2673 $this->setAdminUser(); 2674 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id); 2675 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id); 2676 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id); 2677 2678 // Add some other users as contacts. 2679 \core_message\api::add_contact($users[1]->id, $users[2]->id); 2680 \core_message\api::add_contact($users[3]->id, $users[1]->id); 2681 \core_message\api::add_contact($users[1]->id, $users[4]->id); 2682 2683 // Enrol a user as a teacher in the course, and make the teacher role a course contact role. 2684 $this->getDataGenerator()->enrol_user($users[8]->id, $course2->id, 'editingteacher'); 2685 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 2686 set_config('coursecontact', $teacherrole->id); 2687 2688 // Create individual conversations between some users, one contact and one non-contact. 2689 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2690 [$users[1]->id, $users[2]->id]); 2691 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2692 [$users[6]->id, $users[1]->id]); 2693 2694 // Create a group conversation between 4 users, including a contact and a non-contact. 2695 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 2696 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat'); 2697 2698 // Set as the user performing the search. 2699 $this->setUser($users[1]); 2700 2701 // Perform a search with $CFG->messagingallusers disabled. 2702 set_config('messagingallusers', 0); 2703 $result = core_message_external::message_search_users($users[1]->id, 'search'); 2704 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2705 2706 // Confirm that we returns contacts and non-contacts. 2707 $this->assertArrayHasKey('contacts', $result); 2708 $this->assertArrayHasKey('noncontacts', $result); 2709 $contacts = $result['contacts']; 2710 $noncontacts = $result['noncontacts']; 2711 2712 // Check that we retrieved the correct contacts. 2713 $this->assertCount(2, $contacts); 2714 $this->assertEquals($users[2]->id, $contacts[0]['id']); 2715 $this->assertEquals($users[3]->id, $contacts[1]['id']); 2716 2717 // Verify the correct conversations were returned for the contacts. 2718 $this->assertCount(2, $contacts[0]['conversations']); 2719 // We can't rely on the ordering of conversations within the results, so sort by id first. 2720 usort($contacts[0]['conversations'], function($a, $b) { 2721 return $a['id'] < $b['id']; 2722 }); 2723 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']); 2724 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']); 2725 2726 $this->assertCount(0, $contacts[1]['conversations']); 2727 2728 // Check that we retrieved the correct non-contacts. 2729 // When site wide messaging is disabled, we expect to see only those users who we share a course with and whose profiles 2730 // are visible in that course. This excludes users like course contacts. 2731 $this->assertCount(3, $noncontacts); 2732 // Self-conversation first. 2733 $this->assertEquals($users[1]->id, $noncontacts[0]['id']); 2734 $this->assertEquals($users[6]->id, $noncontacts[1]['id']); 2735 $this->assertEquals($users[7]->id, $noncontacts[2]['id']); 2736 2737 // Verify the correct conversations were returned for the non-contacts. 2738 $this->assertCount(1, $noncontacts[1]['conversations']); 2739 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[1]['conversations'][0]['type']); 2740 2741 $this->assertCount(1, $noncontacts[2]['conversations']); 2742 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]['conversations'][0]['type']); 2743 } 2744 2745 /** 2746 * Tests searching for users when site-wide messaging is enabled. 2747 * 2748 * This test verifies that any contacts are returned, as well as any non-contacts, regardless of whether the searching user 2749 * can view their respective profile. 2750 */ 2751 public function test_message_search_users_messagingallusers_enabled() { 2752 global $DB; 2753 $this->resetAfterTest(); 2754 2755 // Create some users. 2756 $users = []; 2757 foreach (range(1, 9) as $i) { 2758 $user = new stdClass(); 2759 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 2760 $user->lastname = $i; 2761 $user = $this->getDataGenerator()->create_user($user); 2762 $users[$i] = $user; 2763 } 2764 2765 // Enrol a few users in the same course, but leave them as non-contacts. 2766 $course1 = $this->getDataGenerator()->create_course(); 2767 $course2 = $this->getDataGenerator()->create_course(); 2768 2769 $this->setAdminUser(); 2770 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id); 2771 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id); 2772 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id); 2773 2774 // Add some other users as contacts. 2775 \core_message\api::add_contact($users[1]->id, $users[2]->id); 2776 \core_message\api::add_contact($users[3]->id, $users[1]->id); 2777 \core_message\api::add_contact($users[1]->id, $users[4]->id); 2778 2779 // Enrol a user as a teacher in the course, and make the teacher role a course contact role. 2780 $this->getDataGenerator()->enrol_user($users[9]->id, $course2->id, 'editingteacher'); 2781 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher')); 2782 set_config('coursecontact', $teacherrole->id); 2783 2784 // Create individual conversations between some users, one contact and one non-contact. 2785 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2786 [$users[1]->id, $users[2]->id]); 2787 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 2788 [$users[6]->id, $users[1]->id]); 2789 2790 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course. 2791 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 2792 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat'); 2793 2794 // Set as the user performing the search. 2795 $this->setUser($users[1]); 2796 2797 // Perform a search with $CFG->messagingallusers enabled. 2798 set_config('messagingallusers', 1); 2799 $result = core_message_external::message_search_users($users[1]->id, 'search'); 2800 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2801 2802 // Confirm that we returns contacts and non-contacts. 2803 $this->assertArrayHasKey('contacts', $result); 2804 $this->assertArrayHasKey('noncontacts', $result); 2805 $contacts = $result['contacts']; 2806 $noncontacts = $result['noncontacts']; 2807 2808 // Check that we retrieved the correct contacts. 2809 $this->assertCount(2, $contacts); 2810 $this->assertEquals($users[2]->id, $contacts[0]['id']); 2811 $this->assertEquals($users[3]->id, $contacts[1]['id']); 2812 2813 // Verify the correct conversations were returned for the contacts. 2814 $this->assertCount(2, $contacts[0]['conversations']); 2815 // We can't rely on the ordering of conversations within the results, so sort by id first. 2816 usort($contacts[0]['conversations'], function($a, $b) { 2817 return $a['id'] < $b['id']; 2818 }); 2819 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']); 2820 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']); 2821 2822 $this->assertCount(0, $contacts[1]['conversations']); 2823 2824 // Check that we retrieved the correct non-contacts. 2825 // If site wide messaging is enabled, we expect to be able to search for any users whose profiles we can view. 2826 // In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1. 2827 $this->assertCount(4, $noncontacts); 2828 $this->assertEquals($users[1]->id, $noncontacts[0]['id']); 2829 $this->assertEquals($users[6]->id, $noncontacts[1]['id']); 2830 $this->assertEquals($users[7]->id, $noncontacts[2]['id']); 2831 $this->assertEquals($users[9]->id, $noncontacts[3]['id']); 2832 2833 // Verify the correct conversations were returned for the non-contacts. 2834 $this->assertCount(1, $noncontacts[1]['conversations']); 2835 $this->assertCount(1, $noncontacts[2]['conversations']); 2836 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[1]['conversations'][0]['type']); 2837 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]['conversations'][0]['type']); 2838 $this->assertCount(0, $noncontacts[3]['conversations']); 2839 } 2840 2841 /** 2842 * Verify searching for users find themselves when they have self-conversations. 2843 */ 2844 public function test_message_search_users_self_conversations() { 2845 $this->resetAfterTest(); 2846 2847 // Create some users. 2848 $user1 = new stdClass(); 2849 $user1->firstname = 'User'; 2850 $user1->lastname = 'One'; 2851 $user1 = $this->getDataGenerator()->create_user($user1); 2852 $user2 = new stdClass(); 2853 $user2->firstname = 'User'; 2854 $user2->lastname = 'Two'; 2855 $user2 = $this->getDataGenerator()->create_user($user2); 2856 2857 // Get self-conversation for user1. 2858 $sc1 = \core_message\api::get_self_conversation($user1->id); 2859 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi myself!'); 2860 2861 // Perform a search as user1. 2862 $this->setUser($user1); 2863 $result = core_message_external::message_search_users($user1->id, 'One'); 2864 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2865 2866 // Check results are empty. 2867 $this->assertCount(0, $result['contacts']); 2868 $this->assertCount(1, $result['noncontacts']); 2869 } 2870 2871 /** 2872 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found. 2873 */ 2874 public function test_message_search_users_with_empty_result() { 2875 $this->resetAfterTest(); 2876 2877 // Create some users, but make sure neither will match the search term. 2878 $user1 = new stdClass(); 2879 $user1->firstname = 'User'; 2880 $user1->lastname = 'One'; 2881 $user1 = $this->getDataGenerator()->create_user($user1); 2882 $user2 = new stdClass(); 2883 $user2->firstname = 'User'; 2884 $user2->lastname = 'Two'; 2885 $user2 = $this->getDataGenerator()->create_user($user2); 2886 2887 // Perform a search as user1. 2888 $this->setUser($user1); 2889 $result = core_message_external::message_search_users($user1->id, 'search'); 2890 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2891 2892 // Check results are empty. 2893 $this->assertCount(0, $result['contacts']); 2894 $this->assertCount(0, $result['noncontacts']); 2895 } 2896 2897 /** 2898 * Test verifying that limits and offsets work for both the contacts and non-contacts return data. 2899 */ 2900 public function test_message_search_users_limit_offset() { 2901 $this->resetAfterTest(); 2902 2903 // Create 20 users. 2904 $users = []; 2905 foreach (range(1, 20) as $i) { 2906 $user = new stdClass(); 2907 $user->firstname = "User search"; 2908 $user->lastname = $i; 2909 $user = $this->getDataGenerator()->create_user($user); 2910 $users[$i] = $user; 2911 } 2912 2913 // Enrol the first 8 users in the same course, but leave them as non-contacts. 2914 $this->setAdminUser(); 2915 $course1 = $this->getDataGenerator()->create_course(); 2916 foreach (range(1, 8) as $i) { 2917 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id); 2918 } 2919 2920 // Add 5 users, starting at the 11th user, as contacts for user1. 2921 foreach (range(11, 15) as $i) { 2922 \core_message\api::add_contact($users[1]->id, $users[$i]->id); 2923 } 2924 2925 // Set as the user performing the search. 2926 $this->setUser($users[1]); 2927 2928 // Search using a limit of 3. 2929 // This tests the case where we have more results than the limit for both contacts and non-contacts. 2930 $result = core_message_external::message_search_users($users[1]->id, 'search', 0, 3); 2931 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2932 $contacts = $result['contacts']; 2933 $noncontacts = $result['noncontacts']; 2934 2935 // Check that we retrieved the correct contacts. 2936 $this->assertCount(3, $contacts); 2937 $this->assertEquals($users[11]->id, $contacts[0]['id']); 2938 $this->assertEquals($users[12]->id, $contacts[1]['id']); 2939 $this->assertEquals($users[13]->id, $contacts[2]['id']); 2940 2941 // Check that we retrieved the correct non-contacts. 2942 // Consider first conversation is self-conversation. 2943 $this->assertCount(3, $noncontacts); 2944 $this->assertEquals($users[1]->id, $noncontacts[0]['id']); 2945 $this->assertEquals($users[2]->id, $noncontacts[1]['id']); 2946 $this->assertEquals($users[3]->id, $noncontacts[2]['id']); 2947 2948 // Now, offset to get the next batch of results. 2949 // We expect to see 2 contacts, and 3 non-contacts. 2950 $result = core_message_external::message_search_users($users[1]->id, 'search', 3, 3); 2951 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2952 $contacts = $result['contacts']; 2953 $noncontacts = $result['noncontacts']; 2954 $this->assertCount(2, $contacts); 2955 $this->assertEquals($users[14]->id, $contacts[0]['id']); 2956 $this->assertEquals($users[15]->id, $contacts[1]['id']); 2957 2958 $this->assertCount(3, $noncontacts); 2959 $this->assertEquals($users[4]->id, $noncontacts[0]['id']); 2960 $this->assertEquals($users[5]->id, $noncontacts[1]['id']); 2961 $this->assertEquals($users[6]->id, $noncontacts[2]['id']); 2962 2963 // Now, offset to get the next batch of results. 2964 // We expect to see 0 contacts, and 2 non-contacts. 2965 $result = core_message_external::message_search_users($users[1]->id, 'search', 6, 3); 2966 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 2967 $contacts = $result['contacts']; 2968 $noncontacts = $result['noncontacts']; 2969 $this->assertCount(0, $contacts); 2970 2971 $this->assertCount(2, $noncontacts); 2972 $this->assertEquals($users[7]->id, $noncontacts[0]['id']); 2973 $this->assertEquals($users[8]->id, $noncontacts[1]['id']); 2974 } 2975 2976 /** 2977 * Tests searching users as another user having the 'moodle/user:viewdetails' capability. 2978 */ 2979 public function test_message_search_users_with_cap() { 2980 $this->resetAfterTest(); 2981 global $DB; 2982 2983 // Create some users. 2984 $users = []; 2985 foreach (range(1, 8) as $i) { 2986 $user = new stdClass(); 2987 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term. 2988 $user->lastname = $i; 2989 $user = $this->getDataGenerator()->create_user($user); 2990 $users[$i] = $user; 2991 } 2992 2993 // Enrol a few users in the same course, but leave them as non-contacts. 2994 $course1 = $this->getDataGenerator()->create_course(); 2995 $this->setAdminUser(); 2996 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id); 2997 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id); 2998 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id); 2999 3000 // Add some other users as contacts. 3001 \core_message\api::add_contact($users[1]->id, $users[2]->id); 3002 \core_message\api::add_contact($users[3]->id, $users[1]->id); 3003 \core_message\api::add_contact($users[1]->id, $users[4]->id); 3004 3005 // Set as the user performing the search. 3006 $this->setUser($users[1]); 3007 3008 // Grant the authenticated user role the capability 'user:viewdetails' at site context. 3009 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST); 3010 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance()); 3011 3012 // Perform a search with $CFG->messagingallusers disabled. 3013 set_config('messagingallusers', 0); 3014 $result = core_message_external::message_search_users($users[1]->id, 'search'); 3015 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result); 3016 $contacts = $result['contacts']; 3017 $noncontacts = $result['noncontacts']; 3018 3019 // Check that we retrieved the correct contacts. 3020 $this->assertCount(2, $contacts); 3021 $this->assertEquals($users[2]->id, $contacts[0]['id']); 3022 $this->assertEquals($users[3]->id, $contacts[1]['id']); 3023 3024 // Check that we retrieved the correct non-contacts. 3025 // Site-wide messaging is disabled, so we expect to be able to search for any users whose profile we can view. 3026 // Consider first conversations is self-conversation. 3027 $this->assertCount(3, $noncontacts); 3028 $this->assertEquals($users[1]->id, $noncontacts[0]['id']); 3029 $this->assertEquals($users[6]->id, $noncontacts[1]['id']); 3030 $this->assertEquals($users[7]->id, $noncontacts[2]['id']); 3031 } 3032 3033 /** 3034 * Tests searching users as another user without the 'moodle/user:viewdetails' capability. 3035 */ 3036 public function test_message_search_users_without_cap() { 3037 $this->resetAfterTest(); 3038 3039 // Create some users. 3040 $user1 = $this->getDataGenerator()->create_user(); 3041 $user2 = $this->getDataGenerator()->create_user(); 3042 3043 // The person doing the search for another user. 3044 $this->setUser($user1); 3045 3046 // Ensure an exception is thrown. 3047 $this->expectException('moodle_exception'); 3048 core_message_external::message_search_users($user2->id, 'User'); 3049 $this->assertDebuggingCalled(); 3050 } 3051 3052 /** 3053 * Tests searching users with messaging disabled. 3054 */ 3055 public function test_message_search_users_messaging_disabled() { 3056 $this->resetAfterTest(); 3057 3058 // Create some skeleton data just so we can call the WS. 3059 $user = $this->getDataGenerator()->create_user(); 3060 3061 // The person doing the search. 3062 $this->setUser($user); 3063 3064 // Disable messaging. 3065 set_config('messaging', 0); 3066 3067 // Ensure an exception is thrown. 3068 $this->expectException('moodle_exception'); 3069 core_message_external::message_search_users($user->id, 'User'); 3070 } 3071 3072 /** 3073 * Tests searching messages. 3074 */ 3075 public function test_messagearea_search_messages() { 3076 $this->resetAfterTest(true); 3077 3078 // Create some users. 3079 $user1 = self::getDataGenerator()->create_user(); 3080 $user2 = self::getDataGenerator()->create_user(); 3081 3082 // The person doing the search. 3083 $this->setUser($user1); 3084 3085 // Send some messages back and forth. 3086 $time = time(); 3087 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3088 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3089 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3090 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3091 $convid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 3092 3093 // Perform a search. 3094 $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o'); 3095 3096 // We need to execute the return values cleaning process to simulate the web service server. 3097 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(), $result); 3098 3099 // Confirm the data is correct. 3100 $messages = $result['contacts']; 3101 $this->assertCount(2, $messages); 3102 3103 $message1 = $messages[0]; 3104 $message2 = $messages[1]; 3105 3106 $this->assertEquals($user2->id, $message1['userid']); 3107 $this->assertEquals(fullname($user2), $message1['fullname']); 3108 $this->assertTrue($message1['ismessaging']); 3109 $this->assertFalse($message1['sentfromcurrentuser']); 3110 $this->assertEquals('Word.', $message1['lastmessage']); 3111 $this->assertNotEmpty($message1['messageid']); 3112 $this->assertNull($message1['isonline']); 3113 $this->assertFalse($message1['isread']); 3114 $this->assertFalse($message1['isblocked']); 3115 $this->assertNull($message1['unreadcount']); 3116 $this->assertEquals($convid, $message1['conversationid']); 3117 3118 $this->assertEquals($user2->id, $message2['userid']); 3119 $this->assertEquals(fullname($user2), $message2['fullname']); 3120 $this->assertTrue($message2['ismessaging']); 3121 $this->assertTrue($message2['sentfromcurrentuser']); 3122 $this->assertEquals('Yo!', $message2['lastmessage']); 3123 $this->assertNotEmpty($message2['messageid']); 3124 $this->assertNull($message2['isonline']); 3125 $this->assertTrue($message2['isread']); 3126 $this->assertFalse($message2['isblocked']); 3127 $this->assertNull($message2['unreadcount']); 3128 $this->assertEquals($convid, $message2['conversationid']); 3129 } 3130 3131 /** 3132 * Tests searching messages as another user. 3133 */ 3134 public function test_messagearea_search_messages_as_other_user() { 3135 $this->resetAfterTest(true); 3136 3137 // The person doing the search. 3138 $this->setAdminUser(); 3139 3140 // Create some users. 3141 $user1 = self::getDataGenerator()->create_user(); 3142 $user2 = self::getDataGenerator()->create_user(); 3143 3144 // Send some messages back and forth. 3145 $time = time(); 3146 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3147 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3148 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3149 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3150 3151 // Perform a search. 3152 $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o'); 3153 3154 // We need to execute the return values cleaning process to simulate the web service server. 3155 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(), 3156 $result); 3157 3158 // Confirm the data is correct. 3159 $messages = $result['contacts']; 3160 $this->assertCount(2, $messages); 3161 3162 $message1 = $messages[0]; 3163 $message2 = $messages[1]; 3164 3165 $this->assertEquals($user2->id, $message1['userid']); 3166 $this->assertEquals(fullname($user2), $message1['fullname']); 3167 $this->assertTrue($message1['ismessaging']); 3168 $this->assertFalse($message1['sentfromcurrentuser']); 3169 $this->assertEquals('Word.', $message1['lastmessage']); 3170 $this->assertNotEmpty($message1['messageid']); 3171 $this->assertFalse($message1['isonline']); 3172 $this->assertFalse($message1['isread']); 3173 $this->assertFalse($message1['isblocked']); 3174 $this->assertNull($message1['unreadcount']); 3175 3176 $this->assertEquals($user2->id, $message2['userid']); 3177 $this->assertEquals(fullname($user2), $message2['fullname']); 3178 $this->assertTrue($message2['ismessaging']); 3179 $this->assertTrue($message2['sentfromcurrentuser']); 3180 $this->assertEquals('Yo!', $message2['lastmessage']); 3181 $this->assertNotEmpty($message2['messageid']); 3182 $this->assertFalse($message2['isonline']); 3183 $this->assertTrue($message2['isread']); 3184 $this->assertFalse($message2['isblocked']); 3185 $this->assertNull($message2['unreadcount']); 3186 } 3187 3188 /** 3189 * Tests searching messages as another user without the proper capabilities. 3190 */ 3191 public function test_messagearea_search_messages_as_other_user_without_cap() { 3192 $this->resetAfterTest(true); 3193 3194 // Create some users. 3195 $user1 = self::getDataGenerator()->create_user(); 3196 $user2 = self::getDataGenerator()->create_user(); 3197 3198 // The person doing the search for another user. 3199 $this->setUser($user1); 3200 3201 // Ensure an exception is thrown. 3202 $this->expectException('moodle_exception'); 3203 core_message_external::data_for_messagearea_search_messages($user2->id, 'Search'); 3204 } 3205 3206 /** 3207 * Tests searching messages with messaging disabled 3208 */ 3209 public function test_messagearea_search_messages_messaging_disabled() { 3210 global $CFG; 3211 3212 $this->resetAfterTest(true); 3213 3214 // Create some skeleton data just so we can call the WS. 3215 $user = self::getDataGenerator()->create_user(); 3216 3217 // The person doing the search . 3218 $this->setUser($user); 3219 3220 // Disable messaging. 3221 $CFG->messaging = 0; 3222 3223 // Ensure an exception is thrown. 3224 $this->expectException('moodle_exception'); 3225 core_message_external::data_for_messagearea_search_messages($user->id, 'Search'); 3226 } 3227 3228 /** 3229 * Tests retrieving conversations. 3230 */ 3231 public function test_messagearea_conversations() { 3232 $this->resetAfterTest(true); 3233 3234 // Create some users. 3235 $user1 = self::getDataGenerator()->create_user(); 3236 $user2 = self::getDataGenerator()->create_user(); 3237 $user3 = self::getDataGenerator()->create_user(); 3238 $user4 = self::getDataGenerator()->create_user(); 3239 3240 // The person retrieving the conversations. 3241 $this->setUser($user1); 3242 3243 // Send some messages back and forth, have some different conversations with different users. 3244 $time = time(); 3245 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3246 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3247 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3248 $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3249 3250 $this->send_message($user1, $user3, 'Booyah', 0, $time + 4); 3251 $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5); 3252 $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6); 3253 $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7); 3254 3255 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8); 3256 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9); 3257 $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10); 3258 3259 // Retrieve the conversations. 3260 $result = core_message_external::data_for_messagearea_conversations($user1->id); 3261 3262 // We need to execute the return values cleaning process to simulate the web service server. 3263 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(), 3264 $result); 3265 3266 // Confirm the data is correct. 3267 $messages = $result['contacts']; 3268 $this->assertCount(3, $messages); 3269 3270 $message1 = $messages[0]; 3271 $message2 = $messages[1]; 3272 $message3 = $messages[2]; 3273 3274 $this->assertEquals($user4->id, $message1['userid']); 3275 $this->assertTrue($message1['ismessaging']); 3276 $this->assertTrue($message1['sentfromcurrentuser']); 3277 $this->assertEquals('Dope.', $message1['lastmessage']); 3278 $this->assertEquals($messageid3, $message1['messageid']); 3279 $this->assertNull($message1['isonline']); 3280 $this->assertFalse($message1['isread']); 3281 $this->assertFalse($message1['isblocked']); 3282 $this->assertEquals(1, $message1['unreadcount']); 3283 3284 $this->assertEquals($user3->id, $message2['userid']); 3285 $this->assertTrue($message2['ismessaging']); 3286 $this->assertFalse($message2['sentfromcurrentuser']); 3287 $this->assertEquals('Cool.', $message2['lastmessage']); 3288 $this->assertEquals($messageid2, $message2['messageid']); 3289 $this->assertNull($message2['isonline']); 3290 $this->assertFalse($message2['isread']); 3291 $this->assertFalse($message2['isblocked']); 3292 $this->assertEquals(2, $message2['unreadcount']); 3293 3294 $this->assertEquals($user2->id, $message3['userid']); 3295 $this->assertTrue($message3['ismessaging']); 3296 $this->assertFalse($message3['sentfromcurrentuser']); 3297 $this->assertEquals('Word.', $message3['lastmessage']); 3298 $this->assertEquals($messageid1, $message3['messageid']); 3299 $this->assertNull($message3['isonline']); 3300 $this->assertFalse($message3['isread']); 3301 $this->assertFalse($message3['isblocked']); 3302 $this->assertEquals(2, $message3['unreadcount']); 3303 } 3304 3305 /** 3306 * Tests retrieving conversations as another user. 3307 */ 3308 public function test_messagearea_conversations_as_other_user() { 3309 $this->resetAfterTest(true); 3310 3311 // Set as admin. 3312 $this->setAdminUser(); 3313 3314 // Create some users. 3315 $user1 = self::getDataGenerator()->create_user(); 3316 $user2 = self::getDataGenerator()->create_user(); 3317 $user3 = self::getDataGenerator()->create_user(); 3318 $user4 = self::getDataGenerator()->create_user(); 3319 3320 // Send some messages back and forth, have some different conversations with different users. 3321 $time = time(); 3322 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3323 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3324 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3325 $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3326 3327 $this->send_message($user1, $user3, 'Booyah', 0, $time + 4); 3328 $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5); 3329 $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6); 3330 $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7); 3331 3332 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8); 3333 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9); 3334 $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10); 3335 3336 // Retrieve the conversations. 3337 $result = core_message_external::data_for_messagearea_conversations($user1->id); 3338 3339 // We need to execute the return values cleaning process to simulate the web service server. 3340 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(), 3341 $result); 3342 3343 // Confirm the data is correct. 3344 $messages = $result['contacts']; 3345 $this->assertCount(3, $messages); 3346 3347 $message1 = $messages[0]; 3348 $message2 = $messages[1]; 3349 $message3 = $messages[2]; 3350 3351 $this->assertEquals($user4->id, $message1['userid']); 3352 $this->assertTrue($message1['ismessaging']); 3353 $this->assertTrue($message1['sentfromcurrentuser']); 3354 $this->assertEquals('Dope.', $message1['lastmessage']); 3355 $this->assertEquals($messageid3, $message1['messageid']); 3356 $this->assertFalse($message1['isonline']); 3357 $this->assertFalse($message1['isread']); 3358 $this->assertFalse($message1['isblocked']); 3359 $this->assertEquals(1, $message1['unreadcount']); 3360 3361 $this->assertEquals($user3->id, $message2['userid']); 3362 $this->assertTrue($message2['ismessaging']); 3363 $this->assertFalse($message2['sentfromcurrentuser']); 3364 $this->assertEquals('Cool.', $message2['lastmessage']); 3365 $this->assertEquals($messageid2, $message2['messageid']); 3366 $this->assertFalse($message2['isonline']); 3367 $this->assertFalse($message2['isread']); 3368 $this->assertFalse($message2['isblocked']); 3369 $this->assertEquals(2, $message2['unreadcount']); 3370 3371 $this->assertEquals($user2->id, $message3['userid']); 3372 $this->assertTrue($message3['ismessaging']); 3373 $this->assertFalse($message3['sentfromcurrentuser']); 3374 $this->assertEquals('Word.', $message3['lastmessage']); 3375 $this->assertEquals($messageid1, $message3['messageid']); 3376 $this->assertFalse($message3['isonline']); 3377 $this->assertFalse($message3['isread']); 3378 $this->assertFalse($message3['isblocked']); 3379 $this->assertEquals(2, $message3['unreadcount']); 3380 } 3381 3382 /** 3383 * Tests retrieving conversations as another user without the proper capabilities. 3384 */ 3385 public function test_messagearea_conversations_as_other_user_without_cap() { 3386 $this->resetAfterTest(true); 3387 3388 // Create some users. 3389 $user1 = self::getDataGenerator()->create_user(); 3390 $user2 = self::getDataGenerator()->create_user(); 3391 3392 // The person retrieving the conversations for another user. 3393 $this->setUser($user1); 3394 3395 // Ensure an exception is thrown. 3396 $this->expectException('moodle_exception'); 3397 core_message_external::data_for_messagearea_conversations($user2->id); 3398 } 3399 3400 /** 3401 * Tests retrieving conversations with messaging disabled. 3402 */ 3403 public function test_messagearea_conversations_messaging_disabled() { 3404 global $CFG; 3405 3406 $this->resetAfterTest(true); 3407 3408 // Create some skeleton data just so we can call the WS. 3409 $user = self::getDataGenerator()->create_user(); 3410 3411 // The person retrieving the conversations. 3412 $this->setUser($user); 3413 3414 // Disable messaging. 3415 $CFG->messaging = 0; 3416 3417 // Ensure an exception is thrown. 3418 $this->expectException('moodle_exception'); 3419 core_message_external::data_for_messagearea_conversations($user->id); 3420 } 3421 3422 /** 3423 * Tests retrieving contacts. 3424 */ 3425 public function test_messagearea_contacts() { 3426 $this->resetAfterTest(true); 3427 3428 // Create some users. 3429 $user1 = self::getDataGenerator()->create_user(); 3430 3431 // Set as the user. 3432 $this->setUser($user1); 3433 3434 $user2 = new stdClass(); 3435 $user2->firstname = 'User'; 3436 $user2->lastname = 'A'; 3437 $user2 = self::getDataGenerator()->create_user($user2); 3438 3439 $user3 = new stdClass(); 3440 $user3->firstname = 'User'; 3441 $user3->lastname = 'B'; 3442 $user3 = self::getDataGenerator()->create_user($user3); 3443 3444 $user4 = new stdClass(); 3445 $user4->firstname = 'User'; 3446 $user4->lastname = 'C'; 3447 $user4 = self::getDataGenerator()->create_user($user4); 3448 3449 $user5 = new stdClass(); 3450 $user5->firstname = 'User'; 3451 $user5->lastname = 'D'; 3452 $user5 = self::getDataGenerator()->create_user($user5); 3453 3454 // Add some users as contacts. 3455 \core_message\api::add_contact($user1->id, $user2->id); 3456 \core_message\api::add_contact($user1->id, $user3->id); 3457 \core_message\api::add_contact($user1->id, $user4->id); 3458 3459 // Retrieve the contacts. 3460 $result = core_message_external::data_for_messagearea_contacts($user1->id); 3461 3462 // We need to execute the return values cleaning process to simulate the web service server. 3463 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(), 3464 $result); 3465 3466 // Confirm the data is correct. 3467 $contacts = $result['contacts']; 3468 usort($contacts, ['static', 'sort_contacts']); 3469 $this->assertCount(3, $contacts); 3470 3471 $contact1 = $contacts[0]; 3472 $contact2 = $contacts[1]; 3473 $contact3 = $contacts[2]; 3474 3475 $this->assertEquals($user2->id, $contact1['userid']); 3476 $this->assertFalse($contact1['ismessaging']); 3477 $this->assertFalse($contact1['sentfromcurrentuser']); 3478 $this->assertNull($contact1['lastmessage']); 3479 $this->assertNull($contact1['messageid']); 3480 $this->assertNull($contact1['isonline']); 3481 $this->assertFalse($contact1['isread']); 3482 $this->assertFalse($contact1['isblocked']); 3483 $this->assertNull($contact1['unreadcount']); 3484 3485 $this->assertEquals($user3->id, $contact2['userid']); 3486 $this->assertFalse($contact2['ismessaging']); 3487 $this->assertFalse($contact2['sentfromcurrentuser']); 3488 $this->assertNull($contact2['lastmessage']); 3489 $this->assertNull($contact2['messageid']); 3490 $this->assertNull($contact2['isonline']); 3491 $this->assertFalse($contact2['isread']); 3492 $this->assertFalse($contact2['isblocked']); 3493 $this->assertNull($contact2['unreadcount']); 3494 3495 $this->assertEquals($user4->id, $contact3['userid']); 3496 $this->assertFalse($contact3['ismessaging']); 3497 $this->assertFalse($contact3['sentfromcurrentuser']); 3498 $this->assertNull($contact3['lastmessage']); 3499 $this->assertNull($contact3['messageid']); 3500 $this->assertNull($contact3['isonline']); 3501 $this->assertFalse($contact3['isread']); 3502 $this->assertFalse($contact3['isblocked']); 3503 $this->assertNull($contact3['unreadcount']); 3504 } 3505 3506 /** 3507 * Tests retrieving contacts as another user. 3508 */ 3509 public function test_messagearea_contacts_as_other_user() { 3510 $this->resetAfterTest(true); 3511 3512 $this->setAdminUser(); 3513 3514 // Create some users. 3515 $user1 = self::getDataGenerator()->create_user(); 3516 3517 $user2 = new stdClass(); 3518 $user2->firstname = 'User'; 3519 $user2->lastname = 'A'; 3520 $user2 = self::getDataGenerator()->create_user($user2); 3521 3522 $user3 = new stdClass(); 3523 $user3->firstname = 'User'; 3524 $user3->lastname = 'B'; 3525 $user3 = self::getDataGenerator()->create_user($user3); 3526 3527 $user4 = new stdClass(); 3528 $user4->firstname = 'User'; 3529 $user4->lastname = 'C'; 3530 $user4 = self::getDataGenerator()->create_user($user4); 3531 3532 $user5 = new stdClass(); 3533 $user5->firstname = 'User'; 3534 $user5->lastname = 'D'; 3535 $user5 = self::getDataGenerator()->create_user($user5); 3536 3537 // Add some users as contacts. 3538 \core_message\api::add_contact($user1->id, $user2->id); 3539 \core_message\api::add_contact($user1->id, $user3->id); 3540 \core_message\api::add_contact($user1->id, $user4->id); 3541 3542 // Retrieve the contacts. 3543 $result = core_message_external::data_for_messagearea_contacts($user1->id); 3544 3545 // We need to execute the return values cleaning process to simulate the web service server. 3546 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(), 3547 $result); 3548 3549 // Confirm the data is correct. 3550 $contacts = $result['contacts']; 3551 usort($contacts, ['static', 'sort_contacts']); 3552 $this->assertCount(3, $contacts); 3553 3554 $contact1 = $contacts[0]; 3555 $contact2 = $contacts[1]; 3556 $contact3 = $contacts[2]; 3557 3558 $this->assertEquals($user2->id, $contact1['userid']); 3559 $this->assertFalse($contact1['ismessaging']); 3560 $this->assertFalse($contact1['sentfromcurrentuser']); 3561 $this->assertNull($contact1['lastmessage']); 3562 $this->assertNull($contact1['messageid']); 3563 $this->assertFalse($contact1['isonline']); 3564 $this->assertFalse($contact1['isread']); 3565 $this->assertFalse($contact1['isblocked']); 3566 $this->assertNull($contact1['unreadcount']); 3567 3568 $this->assertEquals($user3->id, $contact2['userid']); 3569 $this->assertFalse($contact2['ismessaging']); 3570 $this->assertFalse($contact2['sentfromcurrentuser']); 3571 $this->assertNull($contact2['lastmessage']); 3572 $this->assertNull($contact2['messageid']); 3573 $this->assertFalse($contact2['isonline']); 3574 $this->assertFalse($contact2['isread']); 3575 $this->assertFalse($contact2['isblocked']); 3576 $this->assertNull($contact2['unreadcount']); 3577 3578 $this->assertEquals($user4->id, $contact3['userid']); 3579 $this->assertFalse($contact3['ismessaging']); 3580 $this->assertFalse($contact3['sentfromcurrentuser']); 3581 $this->assertNull($contact3['lastmessage']); 3582 $this->assertNull($contact3['messageid']); 3583 $this->assertFalse($contact3['isonline']); 3584 $this->assertFalse($contact3['isread']); 3585 $this->assertFalse($contact3['isblocked']); 3586 $this->assertNull($contact3['unreadcount']); 3587 } 3588 3589 /** 3590 * Tests retrieving contacts as another user without the proper capabilities. 3591 */ 3592 public function test_messagearea_contacts_as_other_user_without_cap() { 3593 $this->resetAfterTest(true); 3594 3595 // Create some users. 3596 $user1 = self::getDataGenerator()->create_user(); 3597 $user2 = self::getDataGenerator()->create_user(); 3598 3599 // The person retrieving the contacts for another user. 3600 $this->setUser($user1); 3601 3602 // Perform the WS call and ensure an exception is thrown. 3603 $this->expectException('moodle_exception'); 3604 core_message_external::data_for_messagearea_contacts($user2->id); 3605 } 3606 3607 /** 3608 * Tests retrieving contacts with messaging disabled. 3609 */ 3610 public function test_messagearea_contacts_messaging_disabled() { 3611 global $CFG; 3612 3613 $this->resetAfterTest(true); 3614 3615 // Create some skeleton data just so we can call the WS. 3616 $user = self::getDataGenerator()->create_user(); 3617 3618 // The person retrieving the contacts. 3619 $this->setUser($user); 3620 3621 // Disable messaging. 3622 $CFG->messaging = 0; 3623 3624 // Perform the WS call and ensure we are shown that it is disabled. 3625 $this->expectException('moodle_exception'); 3626 core_message_external::data_for_messagearea_contacts($user->id); 3627 } 3628 3629 /** 3630 * Tests retrieving contacts. 3631 */ 3632 public function test_get_user_contacts() { 3633 $this->resetAfterTest(true); 3634 3635 // Create some users. 3636 $user1 = self::getDataGenerator()->create_user(); 3637 3638 // Set as the user. 3639 $this->setUser($user1); 3640 3641 $user2 = new stdClass(); 3642 $user2->firstname = 'User'; 3643 $user2->lastname = 'A'; 3644 $user2 = self::getDataGenerator()->create_user($user2); 3645 3646 $user3 = new stdClass(); 3647 $user3->firstname = 'User'; 3648 $user3->lastname = 'B'; 3649 $user3 = self::getDataGenerator()->create_user($user3); 3650 3651 $user4 = new stdClass(); 3652 $user4->firstname = 'User'; 3653 $user4->lastname = 'C'; 3654 $user4 = self::getDataGenerator()->create_user($user4); 3655 3656 $user5 = new stdClass(); 3657 $user5->firstname = 'User'; 3658 $user5->lastname = 'D'; 3659 $user5 = self::getDataGenerator()->create_user($user5); 3660 3661 // Add some users as contacts. 3662 \core_message\api::add_contact($user1->id, $user2->id); 3663 \core_message\api::add_contact($user1->id, $user3->id); 3664 \core_message\api::add_contact($user1->id, $user4->id); 3665 3666 // Retrieve the contacts. 3667 $result = core_message_external::get_user_contacts($user1->id); 3668 3669 // We need to execute the return values cleaning process to simulate the web service server. 3670 $result = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(), 3671 $result); 3672 3673 // Confirm the data is correct. 3674 $contacts = $result; 3675 usort($contacts, ['static', 'sort_contacts_id']); 3676 $this->assertCount(3, $contacts); 3677 3678 $contact1 = array_shift($contacts); 3679 $contact2 = array_shift($contacts); 3680 $contact3 = array_shift($contacts); 3681 3682 $this->assertEquals($user2->id, $contact1['id']); 3683 $this->assertEquals(fullname($user2), $contact1['fullname']); 3684 $this->assertTrue($contact1['iscontact']); 3685 3686 $this->assertEquals($user3->id, $contact2['id']); 3687 $this->assertEquals(fullname($user3), $contact2['fullname']); 3688 $this->assertTrue($contact2['iscontact']); 3689 3690 $this->assertEquals($user4->id, $contact3['id']); 3691 $this->assertEquals(fullname($user4), $contact3['fullname']); 3692 $this->assertTrue($contact3['iscontact']); 3693 } 3694 3695 /** 3696 * Tests retrieving contacts as another user. 3697 */ 3698 public function test_get_user_contacts_as_other_user() { 3699 $this->resetAfterTest(true); 3700 3701 $this->setAdminUser(); 3702 3703 // Create some users. 3704 $user1 = self::getDataGenerator()->create_user(); 3705 3706 $user2 = new stdClass(); 3707 $user2->firstname = 'User'; 3708 $user2->lastname = 'A'; 3709 $user2 = self::getDataGenerator()->create_user($user2); 3710 3711 $user3 = new stdClass(); 3712 $user3->firstname = 'User'; 3713 $user3->lastname = 'B'; 3714 $user3 = self::getDataGenerator()->create_user($user3); 3715 3716 $user4 = new stdClass(); 3717 $user4->firstname = 'User'; 3718 $user4->lastname = 'C'; 3719 $user4 = self::getDataGenerator()->create_user($user4); 3720 3721 $user5 = new stdClass(); 3722 $user5->firstname = 'User'; 3723 $user5->lastname = 'D'; 3724 $user5 = self::getDataGenerator()->create_user($user5); 3725 3726 // Add some users as contacts. 3727 \core_message\api::add_contact($user1->id, $user2->id); 3728 \core_message\api::add_contact($user1->id, $user3->id); 3729 \core_message\api::add_contact($user1->id, $user4->id); 3730 3731 // Retrieve the contacts. 3732 $result = core_message_external::get_user_contacts($user1->id); 3733 3734 // We need to execute the return values cleaning process to simulate the web service server. 3735 $result = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(), 3736 $result); 3737 3738 // Confirm the data is correct. 3739 $contacts = $result; 3740 usort($contacts, ['static', 'sort_contacts_id']); 3741 $this->assertCount(3, $contacts); 3742 3743 $contact1 = array_shift($contacts); 3744 $contact2 = array_shift($contacts); 3745 $contact3 = array_shift($contacts); 3746 3747 $this->assertEquals($user2->id, $contact1['id']); 3748 $this->assertEquals(fullname($user2), $contact1['fullname']); 3749 $this->assertTrue($contact1['iscontact']); 3750 3751 $this->assertEquals($user3->id, $contact2['id']); 3752 $this->assertEquals(fullname($user3), $contact2['fullname']); 3753 $this->assertTrue($contact2['iscontact']); 3754 3755 $this->assertEquals($user4->id, $contact3['id']); 3756 $this->assertEquals(fullname($user4), $contact3['fullname']); 3757 $this->assertTrue($contact3['iscontact']); 3758 } 3759 3760 /** 3761 * Tests retrieving contacts as another user without the proper capabilities. 3762 */ 3763 public function test_get_user_contacts_as_other_user_without_cap() { 3764 $this->resetAfterTest(true); 3765 3766 // Create some users. 3767 $user1 = self::getDataGenerator()->create_user(); 3768 $user2 = self::getDataGenerator()->create_user(); 3769 3770 // The person retrieving the contacts for another user. 3771 $this->setUser($user1); 3772 3773 // Perform the WS call and ensure an exception is thrown. 3774 $this->expectException('moodle_exception'); 3775 core_message_external::get_user_contacts($user2->id); 3776 } 3777 3778 /** 3779 * Tests retrieving contacts with messaging disabled. 3780 */ 3781 public function test_get_user_contacts_messaging_disabled() { 3782 global $CFG; 3783 3784 $this->resetAfterTest(true); 3785 3786 // Create some skeleton data just so we can call the WS. 3787 $user = self::getDataGenerator()->create_user(); 3788 3789 // The person retrieving the contacts. 3790 $this->setUser($user); 3791 3792 // Disable messaging. 3793 $CFG->messaging = 0; 3794 3795 // Perform the WS call and ensure we are shown that it is disabled. 3796 $this->expectException('moodle_exception'); 3797 core_message_external::get_user_contacts($user->id); 3798 } 3799 3800 /** 3801 * Test getting contacts when there are no results. 3802 */ 3803 public function test_get_user_contacts_no_results() { 3804 $this->resetAfterTest(); 3805 3806 $user1 = self::getDataGenerator()->create_user(); 3807 3808 $this->setUser($user1); 3809 3810 $requests = core_message_external::get_user_contacts($user1->id); 3811 $requests = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(), $requests); 3812 3813 $this->assertEmpty($requests); 3814 } 3815 3816 /** 3817 * Tests retrieving messages. 3818 */ 3819 public function test_messagearea_messages() { 3820 $this->resetAfterTest(true); 3821 3822 // Create some users. 3823 $user1 = self::getDataGenerator()->create_user(); 3824 $user2 = self::getDataGenerator()->create_user(); 3825 3826 // The person asking for the messages. 3827 $this->setUser($user1); 3828 3829 // Send some messages back and forth. 3830 $time = time(); 3831 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3832 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3833 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3834 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3835 3836 // Retrieve the messages. 3837 $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id); 3838 3839 // We need to execute the return values cleaning process to simulate the web service server. 3840 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(), 3841 $result); 3842 3843 // Check the results are correct. 3844 $this->assertTrue($result['iscurrentuser']); 3845 $this->assertEquals($user1->id, $result['currentuserid']); 3846 $this->assertEquals($user2->id, $result['otheruserid']); 3847 $this->assertEquals(fullname($user2), $result['otheruserfullname']); 3848 $this->assertNull($result['isonline']); 3849 3850 // Confirm the message data is correct. 3851 $messages = $result['messages']; 3852 $this->assertCount(4, $messages); 3853 3854 $message1 = $messages[0]; 3855 $message2 = $messages[1]; 3856 $message3 = $messages[2]; 3857 $message4 = $messages[3]; 3858 3859 $this->assertEquals($user1->id, $message1['useridfrom']); 3860 $this->assertEquals($user2->id, $message1['useridto']); 3861 $this->assertTrue($message1['displayblocktime']); 3862 $this->assertContains('Yo!', $message1['text']); 3863 3864 $this->assertEquals($user2->id, $message2['useridfrom']); 3865 $this->assertEquals($user1->id, $message2['useridto']); 3866 $this->assertFalse($message2['displayblocktime']); 3867 $this->assertContains('Sup mang?', $message2['text']); 3868 3869 $this->assertEquals($user1->id, $message3['useridfrom']); 3870 $this->assertEquals($user2->id, $message3['useridto']); 3871 $this->assertFalse($message3['displayblocktime']); 3872 $this->assertContains('Writing PHPUnit tests!', $message3['text']); 3873 3874 $this->assertEquals($user2->id, $message4['useridfrom']); 3875 $this->assertEquals($user1->id, $message4['useridto']); 3876 $this->assertFalse($message4['displayblocktime']); 3877 $this->assertContains('Word.', $message4['text']); 3878 } 3879 3880 /** 3881 * Tests retrieving messages. 3882 */ 3883 public function test_messagearea_messages_timefrom() { 3884 $this->resetAfterTest(true); 3885 3886 // Create some users. 3887 $user1 = self::getDataGenerator()->create_user(); 3888 $user2 = self::getDataGenerator()->create_user(); 3889 3890 // The person asking for the messages. 3891 $this->setUser($user1); 3892 3893 // Send some messages back and forth. 3894 $time = time(); 3895 $this->send_message($user1, $user2, 'Message 1', 0, $time - 4); 3896 $this->send_message($user2, $user1, 'Message 2', 0, $time - 3); 3897 $this->send_message($user1, $user2, 'Message 3', 0, $time - 2); 3898 $this->send_message($user2, $user1, 'Message 4', 0, $time - 1); 3899 3900 // Retrieve the messages from $time - 3, which should be the 3 most recent messages. 3901 $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id, 0, 0, false, $time - 3); 3902 3903 // We need to execute the return values cleaning process to simulate the web service server. 3904 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(), 3905 $result); 3906 3907 // Confirm the message data is correct. We shouldn't get 'Message 1' back. 3908 $messages = $result['messages']; 3909 $this->assertCount(3, $messages); 3910 3911 $message1 = $messages[0]; 3912 $message2 = $messages[1]; 3913 $message3 = $messages[2]; 3914 3915 $this->assertContains('Message 2', $message1['text']); 3916 $this->assertContains('Message 3', $message2['text']); 3917 $this->assertContains('Message 4', $message3['text']); 3918 } 3919 3920 /** 3921 * Tests retrieving messages as another user. 3922 */ 3923 public function test_messagearea_messages_as_other_user() { 3924 $this->resetAfterTest(true); 3925 3926 // Set as admin. 3927 $this->setAdminUser(); 3928 3929 // Create some users. 3930 $user1 = self::getDataGenerator()->create_user(); 3931 $user2 = self::getDataGenerator()->create_user(); 3932 3933 // Send some messages back and forth. 3934 $time = time(); 3935 $this->send_message($user1, $user2, 'Yo!', 0, $time); 3936 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 3937 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 3938 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 3939 3940 // Retrieve the messages. 3941 $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id); 3942 3943 // We need to execute the return values cleaning process to simulate the web service server. 3944 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(), 3945 $result); 3946 3947 // Check the results are correct. 3948 $this->assertFalse($result['iscurrentuser']); 3949 $this->assertEquals($user1->id, $result['currentuserid']); 3950 $this->assertEquals($user2->id, $result['otheruserid']); 3951 $this->assertEquals(fullname($user2), $result['otheruserfullname']); 3952 $this->assertFalse($result['isonline']); 3953 3954 // Confirm the message data is correct. 3955 $messages = $result['messages']; 3956 $this->assertCount(4, $messages); 3957 3958 $message1 = $messages[0]; 3959 $message2 = $messages[1]; 3960 $message3 = $messages[2]; 3961 $message4 = $messages[3]; 3962 3963 $this->assertEquals($user1->id, $message1['useridfrom']); 3964 $this->assertEquals($user2->id, $message1['useridto']); 3965 $this->assertTrue($message1['displayblocktime']); 3966 $this->assertContains('Yo!', $message1['text']); 3967 3968 $this->assertEquals($user2->id, $message2['useridfrom']); 3969 $this->assertEquals($user1->id, $message2['useridto']); 3970 $this->assertFalse($message2['displayblocktime']); 3971 $this->assertContains('Sup mang?', $message2['text']); 3972 3973 $this->assertEquals($user1->id, $message3['useridfrom']); 3974 $this->assertEquals($user2->id, $message3['useridto']); 3975 $this->assertFalse($message3['displayblocktime']); 3976 $this->assertContains('Writing PHPUnit tests!', $message3['text']); 3977 3978 $this->assertEquals($user2->id, $message4['useridfrom']); 3979 $this->assertEquals($user1->id, $message4['useridto']); 3980 $this->assertFalse($message4['displayblocktime']); 3981 $this->assertContains('Word.', $message4['text']); 3982 } 3983 3984 /** 3985 * Tests retrieving messages as another user without the proper capabilities. 3986 */ 3987 public function test_messagearea_messages_as_other_user_without_cap() { 3988 $this->resetAfterTest(true); 3989 3990 // Create some users. 3991 $user1 = self::getDataGenerator()->create_user(); 3992 $user2 = self::getDataGenerator()->create_user(); 3993 $user3 = self::getDataGenerator()->create_user(); 3994 3995 // The person asking for the messages for another user. 3996 $this->setUser($user1); 3997 3998 // Ensure an exception is thrown. 3999 $this->expectException('moodle_exception'); 4000 core_message_external::data_for_messagearea_messages($user2->id, $user3->id); 4001 } 4002 4003 /** 4004 * Tests retrieving messages with messaging disabled. 4005 */ 4006 public function test_messagearea_messages_messaging_disabled() { 4007 global $CFG; 4008 4009 $this->resetAfterTest(true); 4010 4011 // Create some skeleton data just so we can call the WS. 4012 $user1 = self::getDataGenerator()->create_user(); 4013 $user2 = self::getDataGenerator()->create_user(); 4014 4015 // The person asking for the messages for another user. 4016 $this->setUser($user1); 4017 4018 // Disable messaging. 4019 $CFG->messaging = 0; 4020 4021 // Ensure an exception is thrown. 4022 $this->expectException('moodle_exception'); 4023 core_message_external::data_for_messagearea_messages($user1->id, $user2->id); 4024 } 4025 4026 /** 4027 * Tests get_conversation_messages for retrieving messages. 4028 */ 4029 public function test_get_conversation_messages() { 4030 $this->resetAfterTest(true); 4031 4032 // Create some users. 4033 $user1 = self::getDataGenerator()->create_user(); 4034 $user2 = self::getDataGenerator()->create_user(); 4035 $user3 = self::getDataGenerator()->create_user(); 4036 $user4 = self::getDataGenerator()->create_user(); 4037 $user5 = self::getDataGenerator()->create_user(); 4038 4039 // Create group conversation. 4040 $conversation = \core_message\api::create_conversation( 4041 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4042 [$user1->id, $user2->id, $user3->id, $user4->id] 4043 ); 4044 4045 // The person asking for the messages. 4046 $this->setUser($user1); 4047 4048 // Send some messages back and forth. 4049 $time = time(); 4050 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time); 4051 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Sup mang?', $time + 1); 4052 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Writing PHPUnit tests!', $time + 2); 4053 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 3); 4054 4055 // Retrieve the messages. 4056 $result = core_message_external::get_conversation_messages($user1->id, $conversation->id); 4057 4058 // We need to execute the return values cleaning process to simulate the web service server. 4059 $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(), 4060 $result); 4061 4062 // Check the results are correct. 4063 $this->assertEquals($conversation->id, $result['id']); 4064 4065 // Confirm the members data is correct. 4066 $members = $result['members']; 4067 $this->assertCount(3, $members); 4068 $membersid = [$members[0]['id'], $members[1]['id'], $members[2]['id']]; 4069 $this->assertContains($user1->id, $membersid); 4070 $this->assertContains($user2->id, $membersid); 4071 $this->assertContains($user3->id, $membersid); 4072 4073 $membersfullnames = [$members[0]['fullname'], $members[1]['fullname'], $members[2]['fullname']]; 4074 $this->assertContains(fullname($user1), $membersfullnames); 4075 $this->assertContains(fullname($user2), $membersfullnames); 4076 $this->assertContains(fullname($user3), $membersfullnames); 4077 4078 // Confirm the messages data is correct. 4079 $messages = $result['messages']; 4080 $this->assertCount(4, $messages); 4081 4082 $message1 = $messages[0]; 4083 $message2 = $messages[1]; 4084 $message3 = $messages[2]; 4085 $message4 = $messages[3]; 4086 4087 $this->assertEquals($user1->id, $message1['useridfrom']); 4088 $this->assertContains('Yo!', $message1['text']); 4089 4090 $this->assertEquals($user3->id, $message2['useridfrom']); 4091 $this->assertContains('Sup mang?', $message2['text']); 4092 4093 $this->assertEquals($user2->id, $message3['useridfrom']); 4094 $this->assertContains('Writing PHPUnit tests!', $message3['text']); 4095 4096 $this->assertEquals($user1->id, $message4['useridfrom']); 4097 $this->assertContains('Word.', $message4['text']); 4098 } 4099 4100 /** 4101 * Tests get_conversation_messages for retrieving messages using timefrom parameter. 4102 */ 4103 public function test_get_conversation_messages_timefrom() { 4104 $this->resetAfterTest(true); 4105 4106 // Create some users. 4107 $user1 = self::getDataGenerator()->create_user(); 4108 $user2 = self::getDataGenerator()->create_user(); 4109 $user3 = self::getDataGenerator()->create_user(); 4110 $user4 = self::getDataGenerator()->create_user(); 4111 4112 // Create group conversation. 4113 $conversation = \core_message\api::create_conversation( 4114 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4115 [$user1->id, $user2->id, $user3->id] 4116 ); 4117 4118 // The person asking for the messages. 4119 $this->setUser($user1); 4120 4121 // Send some messages back and forth. 4122 $time = time(); 4123 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time - 4); 4124 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time - 3); 4125 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 3', $time - 2); 4126 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 4', $time - 1); 4127 4128 // Retrieve the messages from $time - 3, which should be the 3 most recent messages. 4129 $result = core_message_external::get_conversation_messages($user1->id, $conversation->id, 0, 0, false, $time - 3); 4130 4131 // We need to execute the return values cleaning process to simulate the web service server. 4132 $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(), 4133 $result); 4134 4135 // Check the results are correct. 4136 $this->assertEquals($conversation->id, $result['id']); 4137 4138 // Confirm the messages data is correct. 4139 $messages = $result['messages']; 4140 $this->assertCount(3, $messages); 4141 4142 $message1 = $messages[0]; 4143 $message2 = $messages[1]; 4144 $message3 = $messages[2]; 4145 4146 $this->assertContains('Message 2', $message1['text']); 4147 $this->assertContains('Message 3', $message2['text']); 4148 $this->assertContains('Message 4', $message3['text']); 4149 4150 // Confirm the members data is correct. 4151 $members = $result['members']; 4152 $this->assertCount(1, $members); 4153 $this->assertEquals($user2->id, $members[0]['id']); 4154 } 4155 4156 /** 4157 * Tests get_conversation_messages for retrieving messages as another user. 4158 */ 4159 public function test_get_conversation_messages_as_other_user() { 4160 $this->resetAfterTest(true); 4161 4162 // Set as admin. 4163 $this->setAdminUser(); 4164 4165 // Create some users. 4166 $user1 = self::getDataGenerator()->create_user(); 4167 $user2 = self::getDataGenerator()->create_user(); 4168 $user3 = self::getDataGenerator()->create_user(); 4169 $user4 = self::getDataGenerator()->create_user(); 4170 4171 // Create group conversation. 4172 $conversation = \core_message\api::create_conversation( 4173 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4174 [$user1->id, $user2->id, $user3->id, $user4->id] 4175 ); 4176 4177 // Send some messages back and forth. 4178 $time = time(); 4179 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time); 4180 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Sup mang?', $time + 1); 4181 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Writing PHPUnit tests!', $time + 2); 4182 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 3); 4183 4184 // Retrieve the messages. 4185 $result = core_message_external::get_conversation_messages($user1->id, $conversation->id); 4186 4187 // We need to execute the return values cleaning process to simulate the web service server. 4188 $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(), 4189 $result); 4190 4191 // Check the results are correct. 4192 $this->assertEquals($conversation->id, $result['id']); 4193 4194 // Confirm the members data is correct. 4195 $members = $result['members']; 4196 $this->assertCount(3, $members); 4197 $membersid = [$members[0]['id'], $members[1]['id'], $members[2]['id']]; 4198 $this->assertContains($user1->id, $membersid); 4199 $this->assertContains($user2->id, $membersid); 4200 $this->assertContains($user3->id, $membersid); 4201 4202 // Confirm the message data is correct. 4203 $messages = $result['messages']; 4204 $this->assertCount(4, $messages); 4205 4206 $message1 = $messages[0]; 4207 $message2 = $messages[1]; 4208 $message3 = $messages[2]; 4209 $message4 = $messages[3]; 4210 4211 $this->assertEquals($user1->id, $message1['useridfrom']); 4212 $this->assertContains('Yo!', $message1['text']); 4213 4214 $this->assertEquals($user3->id, $message2['useridfrom']); 4215 $this->assertContains('Sup mang?', $message2['text']); 4216 4217 $this->assertEquals($user2->id, $message3['useridfrom']); 4218 $this->assertContains('Writing PHPUnit tests!', $message3['text']); 4219 4220 $this->assertEquals($user1->id, $message4['useridfrom']); 4221 $this->assertContains('Word.', $message4['text']); 4222 } 4223 4224 /** 4225 * Tests get_conversation_messages for retrieving messages as another user without the proper capabilities. 4226 */ 4227 public function test_get_conversation_messages_as_other_user_without_cap() { 4228 $this->resetAfterTest(true); 4229 4230 // Create some users. 4231 $user1 = self::getDataGenerator()->create_user(); 4232 $user2 = self::getDataGenerator()->create_user(); 4233 $user3 = self::getDataGenerator()->create_user(); 4234 $user4 = self::getDataGenerator()->create_user(); 4235 4236 // Create group conversation. 4237 $conversation = \core_message\api::create_conversation( 4238 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4239 [$user1->id, $user2->id, $user3->id, $user4->id] 4240 ); 4241 4242 // The person asking for the messages for another user. 4243 $this->setUser($user1); 4244 4245 // Ensure an exception is thrown. 4246 $this->expectException('moodle_exception'); 4247 core_message_external::get_conversation_messages($user2->id, $conversation->id); 4248 } 4249 4250 /** 4251 * Tests get_conversation_messages for retrieving messages as another user not in the conversation. 4252 */ 4253 public function test_get_conversation_messages_as_user_not_in_conversation() { 4254 $this->resetAfterTest(true); 4255 4256 // Create some users. 4257 $user1 = self::getDataGenerator()->create_user(); 4258 $user2 = self::getDataGenerator()->create_user(); 4259 $user3 = self::getDataGenerator()->create_user(); // Not in group. 4260 4261 // Create group conversation. 4262 $conversation = \core_message\api::create_conversation( 4263 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4264 [$user1->id, $user2->id] 4265 ); 4266 4267 // The person asking for the messages for a conversation he does not belong to. 4268 $this->setUser($user3); 4269 4270 // Ensure an exception is thrown. 4271 $this->expectExceptionMessage('User is not part of conversation.'); 4272 core_message_external::get_conversation_messages($user3->id, $conversation->id); 4273 } 4274 4275 /** 4276 * Tests get_conversation_messages for retrieving messages with messaging disabled. 4277 */ 4278 public function test_get_conversation_messages_messaging_disabled() { 4279 $this->resetAfterTest(true); 4280 4281 // Create some skeleton data just so we can call the WS. 4282 $user1 = self::getDataGenerator()->create_user(); 4283 $user2 = self::getDataGenerator()->create_user(); 4284 $user3 = self::getDataGenerator()->create_user(); 4285 $user4 = self::getDataGenerator()->create_user(); 4286 4287 // Create group conversation. 4288 $conversation = \core_message\api::create_conversation( 4289 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 4290 [$user1->id, $user2->id, $user3->id, $user4->id] 4291 ); 4292 4293 // The person asking for the messages for another user. 4294 $this->setUser($user1); 4295 4296 // Disable messaging. 4297 set_config('messaging', 0); 4298 4299 // Ensure an exception is thrown. 4300 $this->expectException('moodle_exception'); 4301 core_message_external::get_conversation_messages($user1->id, $conversation->id); 4302 } 4303 4304 /** 4305 * Tests retrieving most recent message. 4306 */ 4307 public function test_messagearea_get_most_recent_message() { 4308 $this->resetAfterTest(true); 4309 4310 // Create some users. 4311 $user1 = self::getDataGenerator()->create_user(); 4312 $user2 = self::getDataGenerator()->create_user(); 4313 4314 // The person doing the search. 4315 $this->setUser($user1); 4316 4317 // Send some messages back and forth. 4318 $time = time(); 4319 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4320 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4321 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4322 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4323 4324 // Get the most recent message. 4325 $result = core_message_external::data_for_messagearea_get_most_recent_message($user1->id, $user2->id); 4326 4327 // We need to execute the return values cleaning process to simulate the web service server. 4328 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_get_most_recent_message_returns(), 4329 $result); 4330 4331 // Check the results are correct. 4332 $this->assertEquals($user2->id, $result['useridfrom']); 4333 $this->assertEquals($user1->id, $result['useridto']); 4334 $this->assertContains('Word.', $result['text']); 4335 } 4336 4337 /** 4338 * Tests retrieving most recent message as another user. 4339 */ 4340 public function test_messagearea_get_most_recent_message_as_other_user() { 4341 $this->resetAfterTest(true); 4342 4343 // The person doing the search. 4344 $this->setAdminUser(); 4345 4346 // Create some users. 4347 $user1 = self::getDataGenerator()->create_user(); 4348 $user2 = self::getDataGenerator()->create_user(); 4349 4350 // Send some messages back and forth. 4351 $time = time(); 4352 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4353 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4354 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4355 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4356 4357 // Get the most recent message. 4358 $result = core_message_external::data_for_messagearea_get_most_recent_message($user1->id, $user2->id); 4359 4360 // We need to execute the return values cleaning process to simulate the web service server. 4361 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_get_most_recent_message_returns(), 4362 $result); 4363 4364 // Check the results are correct. 4365 $this->assertEquals($user2->id, $result['useridfrom']); 4366 $this->assertEquals($user1->id, $result['useridto']); 4367 $this->assertContains('Word.', $result['text']); 4368 } 4369 4370 /** 4371 * Tests retrieving most recent message as another user without the proper capabilities. 4372 */ 4373 public function test_messagearea_get_most_recent_message_as_other_user_without_cap() { 4374 $this->resetAfterTest(true); 4375 4376 // Create some users. 4377 $user1 = self::getDataGenerator()->create_user(); 4378 $user2 = self::getDataGenerator()->create_user(); 4379 $user3 = self::getDataGenerator()->create_user(); 4380 4381 // The person asking for the most recent message for another user. 4382 $this->setUser($user1); 4383 4384 // Ensure an exception is thrown. 4385 $this->expectException('moodle_exception'); 4386 core_message_external::data_for_messagearea_get_most_recent_message($user2->id, $user3->id); 4387 } 4388 4389 /** 4390 * Tests retrieving most recent message with messaging disabled. 4391 */ 4392 public function test_messagearea_get_most_recent_message_messaging_disabled() { 4393 global $CFG; 4394 4395 $this->resetAfterTest(true); 4396 4397 // Create some skeleton data just so we can call the WS. 4398 $user1 = self::getDataGenerator()->create_user(); 4399 $user2 = self::getDataGenerator()->create_user(); 4400 4401 // The person asking for the most recent message. 4402 $this->setUser($user1); 4403 4404 // Disable messaging. 4405 $CFG->messaging = 0; 4406 4407 // Ensure an exception is thrown. 4408 $this->expectException('moodle_exception'); 4409 core_message_external::data_for_messagearea_get_most_recent_message($user1->id, $user2->id); 4410 } 4411 4412 /** 4413 * Tests retrieving a user's profile. 4414 */ 4415 public function test_messagearea_get_profile() { 4416 $this->resetAfterTest(true); 4417 4418 // Create some users. 4419 $user1 = self::getDataGenerator()->create_user(); 4420 $user2 = self::getDataGenerator()->create_user(); 4421 4422 // The person asking for the profile information. 4423 $this->setUser($user1); 4424 4425 // Get the profile. 4426 $result = core_message_external::data_for_messagearea_get_profile($user1->id, $user2->id); 4427 4428 // We need to execute the return values cleaning process to simulate the web service server. 4429 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_get_profile_returns(), 4430 $result); 4431 4432 $this->assertEquals($user2->id, $result['userid']); 4433 $this->assertEmpty($result['email']); 4434 $this->assertEmpty($result['country']); 4435 $this->assertEmpty($result['city']); 4436 $this->assertEquals(fullname($user2), $result['fullname']); 4437 $this->assertNull($result['isonline']); 4438 $this->assertFalse($result['isblocked']); 4439 $this->assertFalse($result['iscontact']); 4440 } 4441 4442 /** 4443 * Tests retrieving a user's profile as another user. 4444 */ 4445 public function test_messagearea_profile_as_other_user() { 4446 $this->resetAfterTest(true); 4447 4448 // The person asking for the profile information. 4449 $this->setAdminUser(); 4450 4451 // Create some users. 4452 $user1 = self::getDataGenerator()->create_user(); 4453 4454 $user2 = new stdClass(); 4455 $user2->country = 'AU'; 4456 $user2->city = 'Perth'; 4457 $user2 = self::getDataGenerator()->create_user($user2); 4458 4459 // Get the profile. 4460 $result = core_message_external::data_for_messagearea_get_profile($user1->id, $user2->id); 4461 4462 // We need to execute the return values cleaning process to simulate the web service server. 4463 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_get_profile_returns(), 4464 $result); 4465 4466 $this->assertEquals($user2->id, $result['userid']); 4467 $this->assertEquals($user2->email, $result['email']); 4468 $this->assertEquals(get_string($user2->country, 'countries'), $result['country']); 4469 $this->assertEquals($user2->city, $result['city']); 4470 $this->assertEquals(fullname($user2), $result['fullname']); 4471 $this->assertFalse($result['isonline']); 4472 $this->assertFalse($result['isblocked']); 4473 $this->assertFalse($result['iscontact']); 4474 } 4475 4476 /** 4477 * Tests retrieving a user's profile as another user without the proper capabilities. 4478 */ 4479 public function test_messagearea_profile_as_other_user_without_cap() { 4480 $this->resetAfterTest(true); 4481 4482 // Create some users. 4483 $user1 = self::getDataGenerator()->create_user(); 4484 $user2 = self::getDataGenerator()->create_user(); 4485 $user3 = self::getDataGenerator()->create_user(); 4486 4487 // The person asking for the profile information for another user. 4488 $this->setUser($user1); 4489 4490 // Ensure an exception is thrown. 4491 $this->expectException('moodle_exception'); 4492 core_message_external::data_for_messagearea_get_profile($user2->id, $user3->id); 4493 } 4494 4495 /** 4496 * Tests retrieving a user's profile with messaging disabled. 4497 */ 4498 public function test_messagearea_profile_messaging_disabled() { 4499 global $CFG; 4500 4501 $this->resetAfterTest(true); 4502 4503 // Create some skeleton data just so we can call the WS. 4504 $user1 = self::getDataGenerator()->create_user(); 4505 $user2 = self::getDataGenerator()->create_user(); 4506 4507 // The person asking for the profile information. 4508 $this->setUser($user1); 4509 4510 // Disable messaging. 4511 $CFG->messaging = 0; 4512 4513 // Ensure an exception is thrown. 4514 $this->expectException('moodle_exception'); 4515 core_message_external::data_for_messagearea_get_profile($user1->id, $user2->id); 4516 } 4517 4518 /** 4519 * Test marking all message as read with an invalid user. 4520 */ 4521 public function test_mark_all_messages_as_read_invalid_user_exception() { 4522 $this->resetAfterTest(true); 4523 4524 $this->expectException('moodle_exception'); 4525 core_message_external::mark_all_messages_as_read(-2132131, 0); 4526 } 4527 4528 /** 4529 * Test marking all message as read without proper access. 4530 */ 4531 public function test_mark_all_messages_as_read_access_denied_exception() { 4532 $this->resetAfterTest(true); 4533 4534 $sender = $this->getDataGenerator()->create_user(); 4535 $user = $this->getDataGenerator()->create_user(); 4536 4537 $this->setUser($user); 4538 $this->expectException('moodle_exception'); 4539 core_message_external::mark_all_messages_as_read($sender->id, 0); 4540 } 4541 4542 /** 4543 * Test marking all message as read with missing from user. 4544 */ 4545 public function test_mark_all_messages_as_read_missing_from_user_exception() { 4546 $this->resetAfterTest(true); 4547 4548 $sender = $this->getDataGenerator()->create_user(); 4549 4550 $this->setUser($sender); 4551 $this->expectException('moodle_exception'); 4552 core_message_external::mark_all_messages_as_read($sender->id, 99999); 4553 } 4554 4555 /** 4556 * Test marking all message as read. 4557 */ 4558 public function test_mark_all_messages_as_read() { 4559 global $DB; 4560 4561 $this->resetAfterTest(true); 4562 4563 $sender1 = $this->getDataGenerator()->create_user(); 4564 $sender2 = $this->getDataGenerator()->create_user(); 4565 $sender3 = $this->getDataGenerator()->create_user(); 4566 $recipient = $this->getDataGenerator()->create_user(); 4567 4568 $this->setUser($recipient); 4569 4570 $this->send_message($sender1, $recipient, 'Message'); 4571 $this->send_message($sender1, $recipient, 'Message'); 4572 $this->send_message($sender2, $recipient, 'Message'); 4573 $this->send_message($sender2, $recipient, 'Message'); 4574 $this->send_message($sender3, $recipient, 'Message'); 4575 $this->send_message($sender3, $recipient, 'Message'); 4576 4577 core_message_external::mark_all_messages_as_read($recipient->id, $sender1->id); 4578 $this->assertEquals(2, $DB->count_records('message_user_actions')); 4579 4580 core_message_external::mark_all_messages_as_read($recipient->id, 0); 4581 $this->assertEquals(6, $DB->count_records('message_user_actions')); 4582 } 4583 4584 /** 4585 * Test marking all conversation messages as read with an invalid user. 4586 */ 4587 public function test_mark_all_conversation_messages_as_read_invalid_user_exception() { 4588 $this->resetAfterTest(true); 4589 4590 $user1 = self::getDataGenerator()->create_user(); 4591 $user2 = self::getDataGenerator()->create_user(); 4592 4593 // Send some messages back and forth. 4594 $time = time(); 4595 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4596 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4597 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4598 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4599 4600 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4601 4602 $this->expectException('moodle_exception'); 4603 core_message_external::mark_all_conversation_messages_as_read(-2132131, $conversationid); 4604 } 4605 4606 /** 4607 * Test marking all conversation messages as read without proper access. 4608 */ 4609 public function test_mark_all_conversation_messages_as_read_access_denied_exception() { 4610 $this->resetAfterTest(true); 4611 4612 $user1 = self::getDataGenerator()->create_user(); 4613 $user2 = self::getDataGenerator()->create_user(); 4614 $user3 = self::getDataGenerator()->create_user(); 4615 4616 // Send some messages back and forth. 4617 $time = time(); 4618 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4619 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4620 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4621 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4622 4623 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4624 4625 // User 3 is not in the conversation. 4626 $this->expectException('moodle_exception'); 4627 core_message_external::mark_all_conversation_messages_as_read($user3->id, $conversationid); 4628 } 4629 4630 /** 4631 * Test marking all conversation messages as read for another user. 4632 */ 4633 public function test_mark_all_conversation_messages_as_read_wrong_user() { 4634 $this->resetAfterTest(true); 4635 4636 $user1 = self::getDataGenerator()->create_user(); 4637 $user2 = self::getDataGenerator()->create_user(); 4638 4639 // Send some messages back and forth. 4640 $time = time(); 4641 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4642 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4643 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4644 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4645 4646 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4647 4648 // Can't mark the messages as read for user 2. 4649 $this->setUser($user1); 4650 $this->expectException('moodle_exception'); 4651 core_message_external::mark_all_conversation_messages_as_read($user2->id, $conversationid); 4652 } 4653 4654 /** 4655 * Test marking all conversation messages as admin. 4656 */ 4657 public function test_mark_all_conversation_messages_as_admin() { 4658 global $DB; 4659 4660 $this->resetAfterTest(true); 4661 4662 $user1 = self::getDataGenerator()->create_user(); 4663 $user2 = self::getDataGenerator()->create_user(); 4664 4665 // Send some messages back and forth. 4666 $time = time(); 4667 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4668 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4669 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4670 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4671 4672 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4673 4674 // Admin can do anything. 4675 $this->setAdminUser(); 4676 core_message_external::mark_all_conversation_messages_as_read($user2->id, $conversationid); 4677 $this->assertEquals(2, $DB->count_records('message_user_actions')); 4678 } 4679 4680 /** 4681 * Test marking all conversation messages. 4682 */ 4683 public function test_mark_all_conversation_messages_as_read() { 4684 global $DB; 4685 4686 $this->resetAfterTest(true); 4687 4688 $user1 = self::getDataGenerator()->create_user(); 4689 $user2 = self::getDataGenerator()->create_user(); 4690 4691 // Send some messages back and forth. 4692 $time = time(); 4693 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4694 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4695 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4696 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4697 4698 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4699 4700 // We are the user we want to mark the messages for and we are in the conversation, all good. 4701 $this->setUser($user1); 4702 core_message_external::mark_all_conversation_messages_as_read($user1->id, $conversationid); 4703 $this->assertEquals(2, $DB->count_records('message_user_actions')); 4704 } 4705 4706 /** 4707 * Test getting unread conversation count. 4708 */ 4709 public function test_get_unread_conversations_count() { 4710 $this->resetAfterTest(true); 4711 4712 // Create some users. 4713 $user1 = self::getDataGenerator()->create_user(); 4714 $user2 = self::getDataGenerator()->create_user(); 4715 $user3 = self::getDataGenerator()->create_user(); 4716 $user4 = self::getDataGenerator()->create_user(); 4717 4718 // The person wanting the conversation count. 4719 $this->setUser($user1); 4720 4721 // Send some messages back and forth, have some different conversations with different users. 4722 $this->send_message($user1, $user2, 'Yo!'); 4723 $this->send_message($user2, $user1, 'Sup mang?'); 4724 $this->send_message($user1, $user2, 'Writing PHPUnit tests!'); 4725 $this->send_message($user2, $user1, 'Word.'); 4726 4727 $this->send_message($user1, $user3, 'Booyah'); 4728 $this->send_message($user3, $user1, 'Whaaat?'); 4729 $this->send_message($user1, $user3, 'Nothing.'); 4730 $this->send_message($user3, $user1, 'Cool.'); 4731 4732 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 4733 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 4734 $this->send_message($user1, $user4, 'Dope.'); 4735 4736 // Get the unread conversation count. 4737 $result = core_message_external::get_unread_conversations_count($user1->id); 4738 4739 // We need to execute the return values cleaning process to simulate the web service server. 4740 $result = external_api::clean_returnvalue(core_message_external::get_unread_conversations_count_returns(), 4741 $result); 4742 4743 $this->assertEquals(3, $result); 4744 } 4745 4746 /** 4747 * Test getting unread conversation count as other user. 4748 */ 4749 public function test_get_unread_conversations_count_as_other_user() { 4750 $this->resetAfterTest(true); 4751 4752 // The person wanting the conversation count. 4753 $this->setAdminUser(); 4754 4755 // Create some users. 4756 $user1 = self::getDataGenerator()->create_user(); 4757 $user2 = self::getDataGenerator()->create_user(); 4758 $user3 = self::getDataGenerator()->create_user(); 4759 $user4 = self::getDataGenerator()->create_user(); 4760 4761 // Send some messages back and forth, have some different conversations with different users. 4762 $this->send_message($user1, $user2, 'Yo!'); 4763 $this->send_message($user2, $user1, 'Sup mang?'); 4764 $this->send_message($user1, $user2, 'Writing PHPUnit tests!'); 4765 $this->send_message($user2, $user1, 'Word.'); 4766 4767 $this->send_message($user1, $user3, 'Booyah'); 4768 $this->send_message($user3, $user1, 'Whaaat?'); 4769 $this->send_message($user1, $user3, 'Nothing.'); 4770 $this->send_message($user3, $user1, 'Cool.'); 4771 4772 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 4773 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 4774 $this->send_message($user1, $user4, 'Dope.'); 4775 4776 // Get the unread conversation count. 4777 $result = core_message_external::get_unread_conversations_count($user1->id); 4778 4779 // We need to execute the return values cleaning process to simulate the web service server. 4780 $result = external_api::clean_returnvalue(core_message_external::get_unread_conversations_count_returns(), 4781 $result); 4782 4783 $this->assertEquals(3, $result); 4784 } 4785 4786 /** 4787 * Test getting unread conversation count as other user without proper capability. 4788 */ 4789 public function test_get_unread_conversations_count_as_other_user_without_cap() { 4790 $this->resetAfterTest(true); 4791 4792 // Create some users. 4793 $user1 = self::getDataGenerator()->create_user(); 4794 $user2 = self::getDataGenerator()->create_user(); 4795 4796 // The person wanting the conversation count. 4797 $this->setUser($user1); 4798 4799 // Ensure an exception is thrown. 4800 $this->expectException('moodle_exception'); 4801 core_message_external::get_unread_conversations_count($user2->id); 4802 } 4803 4804 /** 4805 * Test deleting conversation. 4806 */ 4807 public function test_delete_conversation() { 4808 global $DB; 4809 4810 $this->resetAfterTest(true); 4811 4812 // Create some users. 4813 $user1 = self::getDataGenerator()->create_user(); 4814 $user2 = self::getDataGenerator()->create_user(); 4815 4816 // The person wanting to delete the conversation. 4817 $this->setUser($user1); 4818 4819 // Send some messages back and forth. 4820 $time = time(); 4821 $m1id = $this->send_message($user1, $user2, 'Yo!', 0, $time); 4822 $m2id = $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4823 $m3id = $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4824 $m4id = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4825 4826 // Delete the conversation. 4827 core_message_external::delete_conversation($user1->id, $user2->id); 4828 4829 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 4830 $this->assertCount(4, $muas); 4831 // Sort by id. 4832 ksort($muas); 4833 4834 $mua1 = array_shift($muas); 4835 $mua2 = array_shift($muas); 4836 $mua3 = array_shift($muas); 4837 $mua4 = array_shift($muas); 4838 4839 $this->assertEquals($user1->id, $mua1->userid); 4840 $this->assertEquals($m1id, $mua1->messageid); 4841 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action); 4842 4843 $this->assertEquals($user1->id, $mua2->userid); 4844 $this->assertEquals($m2id, $mua2->messageid); 4845 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action); 4846 4847 $this->assertEquals($user1->id, $mua3->userid); 4848 $this->assertEquals($m3id, $mua3->messageid); 4849 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action); 4850 4851 $this->assertEquals($user1->id, $mua4->userid); 4852 $this->assertEquals($m4id, $mua4->messageid); 4853 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action); 4854 } 4855 4856 /** 4857 * Test deleting conversation as other user. 4858 */ 4859 public function test_delete_conversation_as_other_user() { 4860 global $DB; 4861 4862 $this->resetAfterTest(true); 4863 4864 $this->setAdminUser(); 4865 4866 // Create some users. 4867 $user1 = self::getDataGenerator()->create_user(); 4868 $user2 = self::getDataGenerator()->create_user(); 4869 4870 // Send some messages back and forth. 4871 $time = time(); 4872 $m1id = $this->send_message($user1, $user2, 'Yo!', 0, $time); 4873 $m2id = $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4874 $m3id = $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4875 $m4id = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4876 4877 // Delete the conversation. 4878 core_message_external::delete_conversation($user1->id, $user2->id); 4879 4880 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 4881 $this->assertCount(4, $muas); 4882 // Sort by id. 4883 ksort($muas); 4884 4885 $mua1 = array_shift($muas); 4886 $mua2 = array_shift($muas); 4887 $mua3 = array_shift($muas); 4888 $mua4 = array_shift($muas); 4889 4890 $this->assertEquals($user1->id, $mua1->userid); 4891 $this->assertEquals($m1id, $mua1->messageid); 4892 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action); 4893 4894 $this->assertEquals($user1->id, $mua2->userid); 4895 $this->assertEquals($m2id, $mua2->messageid); 4896 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action); 4897 4898 $this->assertEquals($user1->id, $mua3->userid); 4899 $this->assertEquals($m3id, $mua3->messageid); 4900 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action); 4901 4902 $this->assertEquals($user1->id, $mua4->userid); 4903 $this->assertEquals($m4id, $mua4->messageid); 4904 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action); 4905 } 4906 4907 /** 4908 * Test deleting conversation as other user without proper capability. 4909 */ 4910 public function test_delete_conversation_as_other_user_without_cap() { 4911 $this->resetAfterTest(true); 4912 4913 // Create some users. 4914 $user1 = self::getDataGenerator()->create_user(); 4915 $user2 = self::getDataGenerator()->create_user(); 4916 $user3 = self::getDataGenerator()->create_user(); 4917 4918 // Send some messages back and forth. 4919 $time = time(); 4920 $this->send_message($user1, $user2, 'Yo!', 0, $time); 4921 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4922 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4923 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4924 4925 // The person wanting to delete the conversation. 4926 $this->setUser($user3); 4927 4928 // Ensure an exception is thrown. 4929 $this->expectException('moodle_exception'); 4930 core_message_external::delete_conversation($user1->id, $user2->id); 4931 } 4932 4933 /** 4934 * Test deleting conversation with messaging disabled. 4935 */ 4936 public function test_delete_conversation_messaging_disabled() { 4937 global $CFG; 4938 4939 $this->resetAfterTest(true); 4940 4941 // Create some users. 4942 $user1 = self::getDataGenerator()->create_user(); 4943 $user2 = self::getDataGenerator()->create_user(); 4944 4945 // The person wanting to delete the conversation. 4946 $this->setUser($user1); 4947 4948 // Disable messaging. 4949 $CFG->messaging = 0; 4950 4951 // Ensure an exception is thrown. 4952 $this->expectException('moodle_exception'); 4953 core_message_external::delete_conversation($user1->id, $user2->id); 4954 } 4955 4956 /** 4957 * Test deleting conversations. 4958 */ 4959 public function test_delete_conversations_by_id() { 4960 global $DB; 4961 4962 $this->resetAfterTest(true); 4963 4964 // Create some users. 4965 $user1 = self::getDataGenerator()->create_user(); 4966 $user2 = self::getDataGenerator()->create_user(); 4967 4968 // The person wanting to delete the conversation. 4969 $this->setUser($user1); 4970 4971 // Send some messages back and forth. 4972 $time = time(); 4973 $m1id = $this->send_message($user1, $user2, 'Yo!', 0, $time); 4974 $m2id = $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 4975 $m3id = $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 4976 $m4id = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 4977 4978 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 4979 4980 // Delete the conversation. 4981 core_message_external::delete_conversations_by_id($user1->id, [$conversationid]); 4982 4983 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 4984 $this->assertCount(4, $muas); 4985 // Sort by id. 4986 ksort($muas); 4987 4988 $mua1 = array_shift($muas); 4989 $mua2 = array_shift($muas); 4990 $mua3 = array_shift($muas); 4991 $mua4 = array_shift($muas); 4992 4993 $this->assertEquals($user1->id, $mua1->userid); 4994 $this->assertEquals($m1id, $mua1->messageid); 4995 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action); 4996 4997 $this->assertEquals($user1->id, $mua2->userid); 4998 $this->assertEquals($m2id, $mua2->messageid); 4999 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action); 5000 5001 $this->assertEquals($user1->id, $mua3->userid); 5002 $this->assertEquals($m3id, $mua3->messageid); 5003 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action); 5004 5005 $this->assertEquals($user1->id, $mua4->userid); 5006 $this->assertEquals($m4id, $mua4->messageid); 5007 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action); 5008 } 5009 5010 /** 5011 * Test deleting conversations as other user. 5012 */ 5013 public function test_delete_conversations_by_id_as_other_user() { 5014 global $DB; 5015 5016 $this->resetAfterTest(true); 5017 5018 $this->setAdminUser(); 5019 5020 // Create some users. 5021 $user1 = self::getDataGenerator()->create_user(); 5022 $user2 = self::getDataGenerator()->create_user(); 5023 5024 // Send some messages back and forth. 5025 $time = time(); 5026 $m1id = $this->send_message($user1, $user2, 'Yo!', 0, $time); 5027 $m2id = $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5028 $m3id = $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5029 $m4id = $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 5030 5031 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5032 5033 // Delete the conversation. 5034 core_message_external::delete_conversations_by_id($user1->id, [$conversationid]); 5035 5036 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC'); 5037 $this->assertCount(4, $muas); 5038 // Sort by id. 5039 ksort($muas); 5040 5041 $mua1 = array_shift($muas); 5042 $mua2 = array_shift($muas); 5043 $mua3 = array_shift($muas); 5044 $mua4 = array_shift($muas); 5045 5046 $this->assertEquals($user1->id, $mua1->userid); 5047 $this->assertEquals($m1id, $mua1->messageid); 5048 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action); 5049 5050 $this->assertEquals($user1->id, $mua2->userid); 5051 $this->assertEquals($m2id, $mua2->messageid); 5052 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action); 5053 5054 $this->assertEquals($user1->id, $mua3->userid); 5055 $this->assertEquals($m3id, $mua3->messageid); 5056 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action); 5057 5058 $this->assertEquals($user1->id, $mua4->userid); 5059 $this->assertEquals($m4id, $mua4->messageid); 5060 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action); 5061 } 5062 5063 /** 5064 * Test deleting conversations as other user without proper capability. 5065 */ 5066 public function test_delete_conversations_by_id_as_other_user_without_cap() { 5067 $this->resetAfterTest(true); 5068 5069 // Create some users. 5070 $user1 = self::getDataGenerator()->create_user(); 5071 $user2 = self::getDataGenerator()->create_user(); 5072 $user3 = self::getDataGenerator()->create_user(); 5073 5074 // Send some messages back and forth. 5075 $time = time(); 5076 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5077 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5078 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5079 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 5080 5081 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5082 5083 // The person wanting to delete the conversation. 5084 $this->setUser($user3); 5085 5086 // Ensure an exception is thrown. 5087 $this->expectException('moodle_exception'); 5088 core_message_external::delete_conversations_by_id($user1->id, [$conversationid]); 5089 } 5090 5091 /** 5092 * Test deleting conversations with messaging disabled. 5093 */ 5094 public function test_delete_conversations_by_id_messaging_disabled() { 5095 global $CFG; 5096 5097 $this->resetAfterTest(true); 5098 5099 // Create some users. 5100 $user1 = self::getDataGenerator()->create_user(); 5101 $user2 = self::getDataGenerator()->create_user(); 5102 5103 // Send some messages back and forth. 5104 $time = time(); 5105 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5106 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5107 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5108 $this->send_message($user2, $user1, 'Word.', 0, $time + 3); 5109 5110 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5111 5112 // The person wanting to delete the conversation. 5113 $this->setUser($user1); 5114 5115 // Disable messaging. 5116 $CFG->messaging = 0; 5117 5118 // Ensure an exception is thrown. 5119 $this->expectException('moodle_exception'); 5120 core_message_external::delete_conversations_by_id($user1->id, [$conversationid]); 5121 } 5122 5123 /** 5124 * Test get message processor. 5125 */ 5126 public function test_get_message_processor() { 5127 $this->resetAfterTest(true); 5128 5129 // Create a user. 5130 $user1 = self::getDataGenerator()->create_user(); 5131 5132 // Set you as the user. 5133 $this->setUser($user1); 5134 5135 // Get the message processors. 5136 $result = core_message_external::get_message_processor($user1->id, 'popup'); 5137 5138 // We need to execute the return values cleaning process to simulate the web service server. 5139 $result = external_api::clean_returnvalue(core_message_external::get_message_processor_returns(), $result); 5140 5141 $this->assertNotEmpty($result['systemconfigured']); 5142 $this->assertNotEmpty($result['userconfigured']); 5143 } 5144 5145 /** 5146 * Test get_user_notification_preferences 5147 */ 5148 public function test_get_user_message_preferences() { 5149 $this->resetAfterTest(true); 5150 5151 $user = self::getDataGenerator()->create_user(); 5152 $this->setUser($user); 5153 5154 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody. 5155 set_config('messagingallusers', true); 5156 5157 // Set a couple of preferences to test. 5158 set_user_preference('message_provider_moodle_instantmessage_loggedin', 'email', $user); 5159 set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user); 5160 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user); 5161 5162 $prefs = core_message_external::get_user_message_preferences(); 5163 $prefs = external_api::clean_returnvalue(core_message_external::get_user_message_preferences_returns(), $prefs); 5164 $this->assertEquals($user->id, $prefs['preferences']['userid']); 5165 5166 // Check components. 5167 $this->assertCount(1, $prefs['preferences']['components']); 5168 $this->assertEquals(\core_message\api::MESSAGE_PRIVACY_SITE, $prefs['blocknoncontacts']); 5169 5170 // Check some preferences that we previously set. 5171 $found = false; 5172 foreach ($prefs['preferences']['components'] as $component) { 5173 foreach ($component['notifications'] as $prefdata) { 5174 if ($prefdata['preferencekey'] != 'message_provider_moodle_instantmessage') { 5175 continue; 5176 } 5177 foreach ($prefdata['processors'] as $processor) { 5178 if ($processor['name'] == 'email') { 5179 $this->assertTrue($processor['loggedin']['checked']); 5180 $this->assertTrue($processor['loggedoff']['checked']); 5181 $found = true; 5182 } 5183 } 5184 } 5185 } 5186 $this->assertTrue($found); 5187 } 5188 5189 /** 5190 * Test get_user_message_preferences permissions 5191 */ 5192 public function test_get_user_message_preferences_permissions() { 5193 $this->resetAfterTest(true); 5194 5195 $user = self::getDataGenerator()->create_user(); 5196 $otheruser = self::getDataGenerator()->create_user(); 5197 $this->setUser($user); 5198 5199 $this->expectException('moodle_exception'); 5200 $prefs = core_message_external::get_user_message_preferences($otheruser->id); 5201 } 5202 5203 /** 5204 * Comparison function for sorting contacts. 5205 * 5206 * @param array $a 5207 * @param array $b 5208 * @return bool 5209 */ 5210 protected static function sort_contacts($a, $b) { 5211 return $a['userid'] > $b['userid']; 5212 } 5213 5214 /** 5215 * Comparison function for sorting contacts. 5216 * 5217 * @param array $a 5218 * @param array $b 5219 * @return bool 5220 */ 5221 protected static function sort_contacts_id($a, $b) { 5222 return $a['id'] > $b['id']; 5223 } 5224 5225 /** 5226 * Test verifying that conversations can be marked as favourite conversations. 5227 */ 5228 public function test_set_favourite_conversations_basic() { 5229 $this->resetAfterTest(); 5230 5231 $user1 = self::getDataGenerator()->create_user(); 5232 $user2 = self::getDataGenerator()->create_user(); 5233 $user3 = self::getDataGenerator()->create_user(); 5234 $user4 = self::getDataGenerator()->create_user(); 5235 5236 $this->setUser($user1); 5237 5238 // Now, create some conversations. 5239 $time = time(); 5240 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5241 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5242 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5243 5244 $this->send_message($user1, $user3, 'Booyah'); 5245 $this->send_message($user3, $user1, 'Whaaat?'); 5246 $this->send_message($user1, $user3, 'Nothing.'); 5247 5248 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 5249 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 5250 5251 // Favourite 2 conversations as user 1. 5252 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5253 $conversation2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]); 5254 $result = core_message_external::set_favourite_conversations($user1->id, [$conversation1, $conversation2]); 5255 5256 // We need to execute the return values cleaning process to simulate the web service server. 5257 $result = external_api::clean_returnvalue(core_message_external::set_favourite_conversations_returns(), $result); 5258 $this->assertCount(0, $result); 5259 } 5260 5261 /** 5262 * Test confirming that a user can't favourite a conversation on behalf of another user. 5263 */ 5264 public function test_set_favourite_conversations_another_users_conversation() { 5265 $this->resetAfterTest(); 5266 5267 $user1 = self::getDataGenerator()->create_user(); 5268 $user2 = self::getDataGenerator()->create_user(); 5269 $user3 = self::getDataGenerator()->create_user(); 5270 5271 $this->setUser($user3); 5272 5273 // Now, create some conversations. 5274 $time = time(); 5275 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5276 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5277 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5278 5279 $this->send_message($user1, $user3, 'Booyah'); 5280 $this->send_message($user3, $user1, 'Whaaat?'); 5281 $this->send_message($user1, $user3, 'Nothing.'); 5282 5283 // Try to favourite conversation 1 for user 2, as user3. 5284 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5285 $this->expectException(\moodle_exception::class); 5286 $result = core_message_external::set_favourite_conversations($user2->id, [$conversation1]); 5287 } 5288 5289 /** 5290 * Test confirming that a user can't mark a conversation as their own favourite if it's a conversation they're not a member of. 5291 */ 5292 public function test_set_favourite_conversations_non_member() { 5293 $this->resetAfterTest(); 5294 5295 $user1 = self::getDataGenerator()->create_user(); 5296 $user2 = self::getDataGenerator()->create_user(); 5297 $user3 = self::getDataGenerator()->create_user(); 5298 5299 $this->setUser($user3); 5300 5301 // Now, create some conversations. 5302 $time = time(); 5303 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5304 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5305 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5306 5307 $this->send_message($user1, $user3, 'Booyah'); 5308 $this->send_message($user3, $user1, 'Whaaat?'); 5309 $this->send_message($user1, $user3, 'Nothing.'); 5310 5311 // Try to favourite conversation 1 as user 3. 5312 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5313 $conversation2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]); 5314 $this->expectException(\moodle_exception::class); 5315 $result = core_message_external::set_favourite_conversations($user3->id, [$conversation1]); 5316 } 5317 5318 /** 5319 * Test confirming that a user can't favourite a non-existent conversation. 5320 */ 5321 public function test_set_favourite_conversations_non_existent_conversation() { 5322 $this->resetAfterTest(); 5323 5324 $user1 = self::getDataGenerator()->create_user(); 5325 $this->setUser($user1); 5326 5327 // Try to favourite a non-existent conversation. 5328 $this->expectException(\moodle_exception::class); 5329 $result = core_message_external::set_favourite_conversations($user1->id, [0]); 5330 } 5331 5332 /** 5333 * Test confirming that a user can unset a favourite conversation, or list of favourite conversations. 5334 */ 5335 public function test_unset_favourite_conversations_basic() { 5336 $this->resetAfterTest(); 5337 5338 $user1 = self::getDataGenerator()->create_user(); 5339 $user2 = self::getDataGenerator()->create_user(); 5340 $user3 = self::getDataGenerator()->create_user(); 5341 $user4 = self::getDataGenerator()->create_user(); 5342 5343 $this->setUser($user1); 5344 5345 // Now, create some conversations. 5346 $time = time(); 5347 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5348 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5349 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5350 5351 $this->send_message($user1, $user3, 'Booyah'); 5352 $this->send_message($user3, $user1, 'Whaaat?'); 5353 $this->send_message($user1, $user3, 'Nothing.'); 5354 5355 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?'); 5356 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.'); 5357 5358 // Favourite 2 conversations as user 1. 5359 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5360 $conversation2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]); 5361 \core_message\api::set_favourite_conversation($conversation1, $user1->id); 5362 \core_message\api::set_favourite_conversation($conversation2, $user1->id); 5363 // Consider first conversations is self-conversation. 5364 $this->assertCount(3, \core_message\api::get_conversations($user1->id, 0, 20, null, true)); 5365 5366 // Unset favourite self-conversation. 5367 $selfconversation = \core_message\api::get_self_conversation($user1->id); 5368 $result = core_message_external::unset_favourite_conversations($user1->id, [$selfconversation->id]); 5369 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 0, 20, null, true)); 5370 5371 // Now, using the web service, unset the favourite conversations. 5372 $result = core_message_external::unset_favourite_conversations($user1->id, [$conversation1, $conversation2]); 5373 5374 // We need to execute the return values cleaning process to simulate the web service server. 5375 $result = external_api::clean_returnvalue(core_message_external::unset_favourite_conversations_returns(), $result); 5376 $this->assertCount(0, $result); 5377 } 5378 5379 /** 5380 * Test confirming that a user can't unfavourite a conversation for another user. 5381 */ 5382 public function test_unset_favourite_conversations_another_users_conversation() { 5383 $this->resetAfterTest(); 5384 5385 $user1 = self::getDataGenerator()->create_user(); 5386 $user2 = self::getDataGenerator()->create_user(); 5387 $user3 = self::getDataGenerator()->create_user(); 5388 5389 $this->setUser($user3); 5390 5391 // Now, create some conversations. 5392 $time = time(); 5393 $this->send_message($user1, $user2, 'Yo!', 0, $time); 5394 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1); 5395 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2); 5396 5397 $this->send_message($user1, $user3, 'Booyah'); 5398 $this->send_message($user3, $user1, 'Whaaat?'); 5399 $this->send_message($user1, $user3, 'Nothing.'); 5400 5401 // Favourite conversation 1 for user1. The current user ($USER) isn't checked for this action. 5402 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5403 \core_message\api::set_favourite_conversation($conversation1, $user1->id); 5404 // Consider first conversations is self-conversation. 5405 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 0, 20, null, true)); 5406 5407 // Try to unfavourite conversation 1 for user 2, as user3. 5408 $conversation1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]); 5409 $this->expectException(\moodle_exception::class); 5410 $result = core_message_external::unset_favourite_conversations($user2->id, [$conversation1]); 5411 } 5412 5413 /** 5414 * Test confirming that a user can't unfavourite a non-existent conversation. 5415 */ 5416 public function test_unset_favourite_conversations_non_existent_conversation() { 5417 $this->resetAfterTest(); 5418 5419 $user1 = self::getDataGenerator()->create_user(); 5420 $this->setUser($user1); 5421 5422 // Try to unfavourite a non-existent conversation. 5423 $this->expectException(\moodle_exception::class); 5424 $result = core_message_external::unset_favourite_conversations($user1->id, [0]); 5425 } 5426 5427 /** 5428 * Helper to seed the database with initial state. 5429 */ 5430 protected function create_conversation_test_data() { 5431 // Create some users. 5432 $user1 = self::getDataGenerator()->create_user(); 5433 $user2 = self::getDataGenerator()->create_user(); 5434 $user3 = self::getDataGenerator()->create_user(); 5435 $user4 = self::getDataGenerator()->create_user(); 5436 5437 $time = 1; 5438 5439 // Create some conversations. We want: 5440 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message. 5441 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message. 5442 // 3) At least one of each type (group, individual) of which user1 IS NOT a member. 5443 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering). 5444 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member. 5445 5446 // Individual conversation, user1 is a member, last message from other user. 5447 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5448 [$user1->id, $user2->id]); 5449 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time); 5450 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1); 5451 5452 // Individual conversation, user1 is a member, last message from user1. 5453 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5454 [$user1->id, $user3->id]); 5455 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2); 5456 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3); 5457 5458 // Individual conversation, user1 is not a member. 5459 $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5460 [$user2->id, $user3->id]); 5461 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4); 5462 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5); 5463 5464 // Group conversation, user1 is not a member. 5465 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5466 [$user2->id, $user3->id, $user4->id], 'Project discussions'); 5467 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6); 5468 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7); 5469 5470 // Group conversation, user1 is a member, last message from another user. 5471 $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5472 [$user1->id, $user3->id, $user4->id], 'Group chat'); 5473 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8); 5474 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9); 5475 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10); 5476 5477 // Group conversation, user1 is a member, last message from user1. 5478 $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5479 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!'); 5480 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11); 5481 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12); 5482 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13); 5483 5484 // Empty group conversations (x2), user1 is a member. 5485 $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5486 [$user1->id, $user2->id, $user3->id], 'Empty group'); 5487 $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5488 [$user1->id, $user2->id, $user4->id], 'Another empty group'); 5489 5490 // Empty group conversation, user1 is NOT a member. 5491 $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 5492 [$user2->id, $user3->id, $user4->id], 'Empty group 3'); 5493 5494 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6]; 5495 } 5496 5497 /** 5498 * Test confirming the basic use of get_conversations, with no limits, nor type or favourite restrictions. 5499 */ 5500 public function test_get_conversations_no_restrictions() { 5501 $this->resetAfterTest(true); 5502 5503 // Get a bunch of conversations, some group, some individual and in different states. 5504 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5505 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5506 5507 // The user making the request. 5508 $this->setUser($user1); 5509 5510 // Get all conversations for user1. 5511 $result = core_message_external::get_conversations($user1->id); 5512 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5513 $conversations = $result['conversations']; 5514 5515 $selfconversation = \core_message\api::get_self_conversation($user1->id); 5516 5517 // Verify there are 7 conversations: 2 individual, 2 group with message, 2 group without messages 5518 // and a self-conversation. 5519 // The conversations with the most recent messages should be listed first, followed by the most newly created 5520 // conversations without messages. 5521 $this->assertCount(7, $conversations); 5522 $this->assertEquals($gc3->id, $conversations[0]['id']); 5523 $this->assertEquals($gc2->id, $conversations[1]['id']); 5524 $this->assertEquals($ic2->id, $conversations[2]['id']); 5525 $this->assertEquals($ic1->id, $conversations[3]['id']); 5526 $this->assertEquals($gc5->id, $conversations[4]['id']); 5527 $this->assertEquals($gc4->id, $conversations[5]['id']); 5528 $this->assertEquals($selfconversation->id, $conversations[6]['id']); 5529 5530 foreach ($conversations as $conv) { 5531 $this->assertArrayHasKey('id', $conv); 5532 $this->assertArrayHasKey('name', $conv); 5533 $this->assertArrayHasKey('subname', $conv); 5534 $this->assertArrayHasKey('imageurl', $conv); 5535 $this->assertArrayHasKey('type', $conv); 5536 $this->assertArrayHasKey('membercount', $conv); 5537 $this->assertArrayHasKey('isfavourite', $conv); 5538 $this->assertArrayHasKey('isread', $conv); 5539 $this->assertArrayHasKey('unreadcount', $conv); 5540 $this->assertArrayHasKey('members', $conv); 5541 foreach ($conv['members'] as $member) { 5542 $this->assertArrayHasKey('id', $member); 5543 $this->assertArrayHasKey('fullname', $member); 5544 $this->assertArrayHasKey('profileimageurl', $member); 5545 $this->assertArrayHasKey('profileimageurlsmall', $member); 5546 $this->assertArrayHasKey('isonline', $member); 5547 $this->assertArrayHasKey('showonlinestatus', $member); 5548 $this->assertArrayHasKey('isblocked', $member); 5549 $this->assertArrayHasKey('iscontact', $member); 5550 $this->assertArrayHasKey('isdeleted', $member); 5551 $this->assertArrayHasKey('canmessage', $member); 5552 $this->assertArrayHasKey('requirescontact', $member); 5553 $this->assertArrayHasKey('contactrequests', $member); 5554 } 5555 $this->assertArrayHasKey('messages', $conv); 5556 foreach ($conv['messages'] as $message) { 5557 $this->assertArrayHasKey('id', $message); 5558 $this->assertArrayHasKey('useridfrom', $message); 5559 $this->assertArrayHasKey('text', $message); 5560 $this->assertArrayHasKey('timecreated', $message); 5561 } 5562 } 5563 } 5564 5565 /** 5566 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately. 5567 */ 5568 public function test_get_conversations_message_format() { 5569 $this->resetAfterTest(); 5570 5571 global $DB; 5572 // Create some users. 5573 $user1 = self::getDataGenerator()->create_user(); 5574 $user2 = self::getDataGenerator()->create_user(); 5575 5576 // Create conversation. 5577 $conversation = \core_message\api::create_conversation( 5578 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5579 [$user1->id, $user2->id] 5580 ); 5581 5582 // Send some messages back and forth. 5583 $time = 1; 5584 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1); 5585 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2); 5586 $message = $DB->get_record('messages', ['id' => $mid]); 5587 5588 // The user in scope. 5589 $this->setUser($user1); 5590 5591 // Verify the format of the html message. 5592 $expectedmessagetext = message_format_message_text($message); 5593 $result = core_message_external::get_conversations($user1->id); 5594 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5595 $conversations = $result['conversations']; 5596 $messages = $conversations[0]['messages']; 5597 $this->assertEquals($expectedmessagetext, $messages[0]['text']); 5598 } 5599 5600 /** 5601 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly. 5602 */ 5603 public function test_get_conversations_limit_offset() { 5604 $this->resetAfterTest(true); 5605 5606 // Get a bunch of conversations, some group, some individual and in different states. 5607 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5608 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5609 5610 // The user making the request. 5611 $this->setUser($user1); 5612 5613 // Get all conversations for user1. 5614 $result = core_message_external::get_conversations($user1->id, 0, 1); 5615 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5616 $conversations = $result['conversations']; 5617 5618 // Verify the first conversation. 5619 $this->assertCount(1, $conversations); 5620 $conversation = array_shift($conversations); 5621 $this->assertEquals($gc3->id, $conversation['id']); 5622 5623 // Verify the next conversation. 5624 $result = core_message_external::get_conversations($user1->id, 1, 1); 5625 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5626 $conversations = $result['conversations']; 5627 $this->assertCount(1, $conversations); 5628 $this->assertEquals($gc2->id, $conversations[0]['id']); 5629 5630 // Verify the next conversation. 5631 $result = core_message_external::get_conversations($user1->id, 2, 1); 5632 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5633 $conversations = $result['conversations']; 5634 $this->assertCount(1, $conversations); 5635 $this->assertEquals($ic2->id, $conversations[0]['id']); 5636 5637 // Skip one and get both empty conversations. 5638 $result = core_message_external::get_conversations($user1->id, 4, 2); 5639 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5640 $conversations = $result['conversations']; 5641 $this->assertCount(2, $conversations); 5642 $this->assertEquals($gc5->id, $conversations[0]['id']); 5643 $this->assertEmpty($conversations[0]['messages']); 5644 $this->assertEquals($gc4->id, $conversations[1]['id']); 5645 $this->assertEmpty($conversations[1]['messages']); 5646 5647 // Ask for an offset that doesn't exist and verify no conversations are returned. 5648 $conversations = \core_message\api::get_conversations($user1->id, 10, 1); 5649 $this->assertCount(0, $conversations); 5650 } 5651 5652 /** 5653 * Test verifying the type filtering behaviour of the get_conversations external method. 5654 */ 5655 public function test_get_conversations_type_filter() { 5656 $this->resetAfterTest(true); 5657 5658 // Get a bunch of conversations, some group, some individual and in different states. 5659 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5660 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5661 5662 // The user making the request. 5663 $this->setUser($user1); 5664 5665 // Verify we can ask for only individual conversations. 5666 $result = core_message_external::get_conversations($user1->id, 0, 20, 5667 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL); 5668 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5669 $conversations = $result['conversations']; 5670 $this->assertCount(2, $conversations); 5671 5672 // Verify we can ask for only group conversations. 5673 $result = core_message_external::get_conversations($user1->id, 0, 20, 5674 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP); 5675 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5676 $conversations = $result['conversations']; 5677 $this->assertCount(4, $conversations); 5678 5679 // Verify an exception is thrown if an unrecognized type is specified. 5680 $this->expectException(\moodle_exception::class); 5681 core_message_external::get_conversations($user1->id, 0, 20, 0); 5682 } 5683 5684 /** 5685 * Tests retrieving conversations when a 'self' conversation exists. 5686 */ 5687 public function test_get_conversations_self_conversations() { 5688 global $DB; 5689 $this->resetAfterTest(); 5690 5691 // Create a conversation between one user and themself. 5692 $user1 = self::getDataGenerator()->create_user(); 5693 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, 5694 [$user1->id]); 5695 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Test message to self!'); 5696 5697 // Verify we are in a 'self' conversation state. 5698 $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation->id]); 5699 $this->assertCount(1, $members); 5700 $member = array_pop($members); 5701 $this->assertEquals($user1->id, $member->userid); 5702 5703 // Verify this conversation is returned by the method. 5704 $this->setUser($user1); 5705 $result = core_message_external::get_conversations($user1->id, 0, 20); 5706 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5707 $conversations = $result['conversations']; 5708 $this->assertCount(1, $conversations); 5709 } 5710 5711 /** 5712 * Tests retrieving conversations when a conversation contains a deleted user. 5713 */ 5714 public function test_get_conversations_deleted_user() { 5715 $this->resetAfterTest(true); 5716 5717 // Get a bunch of conversations, some group, some individual and in different states. 5718 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5719 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5720 5721 // The user making the request. 5722 $this->setUser($user1); 5723 5724 $selfconversation = \core_message\api::get_self_conversation($user1->id); 5725 5726 // Delete the second user and retrieve the conversations. 5727 // We should have 6 still, as conversations with soft-deleted users are still returned. 5728 // Group conversations are also present, albeit with less members. 5729 delete_user($user2); 5730 $result = core_message_external::get_conversations($user1->id); 5731 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5732 $conversations = $result['conversations']; 5733 $this->assertCount(7, $conversations); 5734 $this->assertEquals($gc3->id, $conversations[0]['id']); 5735 $this->assertcount(1, $conversations[0]['members']); 5736 $this->assertEquals($gc2->id, $conversations[1]['id']); 5737 $this->assertcount(1, $conversations[1]['members']); 5738 $this->assertEquals($ic2->id, $conversations[2]['id']); 5739 $this->assertEquals($ic1->id, $conversations[3]['id']); 5740 $this->assertEquals($gc5->id, $conversations[4]['id']); 5741 $this->assertEquals($gc4->id, $conversations[5]['id']); 5742 $this->assertEquals($selfconversation->id, $conversations[6]['id']); 5743 5744 // Delete a user from a group conversation where that user had sent the most recent message. 5745 // This user will still be present in the members array, as will the message in the messages array. 5746 delete_user($user4); 5747 $result = core_message_external::get_conversations($user1->id); 5748 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5749 $conversations = $result['conversations']; 5750 $this->assertCount(7, $conversations); 5751 $this->assertEquals($gc2->id, $conversations[1]['id']); 5752 $this->assertcount(1, $conversations[1]['members']); 5753 $this->assertEquals($user4->id, $conversations[1]['members'][0]['id']); 5754 $this->assertcount(1, $conversations[1]['messages']); 5755 $this->assertEquals($user4->id, $conversations[1]['messages'][0]['useridfrom']); 5756 5757 // Delete the third user and retrieve the conversations. 5758 // We should have 7 still (including self-conversation), as conversations with soft-deleted users are still returned. 5759 // Group conversations are also present, albeit with less members. 5760 delete_user($user3); 5761 $result = core_message_external::get_conversations($user1->id); 5762 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5763 $conversations = $result['conversations']; 5764 $this->assertCount(7, $conversations); 5765 $this->assertEquals($gc3->id, $conversations[0]['id']); 5766 $this->assertcount(1, $conversations[0]['members']); 5767 $this->assertEquals($gc2->id, $conversations[1]['id']); 5768 $this->assertcount(1, $conversations[1]['members']); 5769 $this->assertEquals($ic2->id, $conversations[2]['id']); 5770 $this->assertEquals($ic1->id, $conversations[3]['id']); 5771 $this->assertEquals($gc5->id, $conversations[4]['id']); 5772 $this->assertEquals($gc4->id, $conversations[5]['id']); 5773 $this->assertEquals($selfconversation->id, $conversations[6]['id']); 5774 } 5775 5776 /** 5777 * Tests retrieving conversations when a conversation contains a deleted from the database user. 5778 */ 5779 public function test_get_conversations_deleted_user_from_database() { 5780 global $DB; 5781 5782 $this->resetAfterTest(); 5783 5784 $user1 = self::getDataGenerator()->create_user(); 5785 $user2 = self::getDataGenerator()->create_user(); 5786 $user3 = self::getDataGenerator()->create_user(); 5787 5788 $conversation1 = \core_message\api::create_conversation( 5789 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5790 [ 5791 $user1->id, 5792 $user2->id 5793 ], 5794 'Individual conversation 1' 5795 ); 5796 5797 testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'A'); 5798 testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'B'); 5799 testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'C'); 5800 5801 $conversation2 = \core_message\api::create_conversation( 5802 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 5803 [ 5804 $user1->id, 5805 $user3->id 5806 ], 5807 'Individual conversation 2' 5808 ); 5809 5810 testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'A'); 5811 testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'B'); 5812 testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'C'); 5813 5814 $this->setUser($user1); 5815 5816 // Delete the second user (from DB as well as this could happen in the past). 5817 delete_user($user2); 5818 $DB->delete_records('user', ['id' => $user2->id]); 5819 $result = core_message_external::get_conversations($user1->id, 0, 20, 1, false); 5820 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5821 5822 $conversation = $result['conversations']; 5823 5824 $this->assertCount(1, $conversation); 5825 5826 $conversation = reset($conversation); 5827 5828 $this->assertEquals($conversation2->id, $conversation['id']); 5829 } 5830 5831 /** 5832 * Test verifying the behaviour of get_conversations() when fetching favourite conversations. 5833 */ 5834 public function test_get_conversations_favourite_conversations() { 5835 $this->resetAfterTest(true); 5836 5837 // Get a bunch of conversations, some group, some individual and in different states. 5838 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 5839 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 5840 5841 // The user making the request. 5842 $this->setUser($user1); 5843 5844 // Unset favourite self-conversation. 5845 $selfconversation = \core_message\api::get_self_conversation($user1->id); 5846 \core_message\api::unset_favourite_conversation($selfconversation->id, $user1->id); 5847 5848 // Try to get ONLY favourite conversations, when no favourites exist. 5849 $result = core_message_external::get_conversations($user1->id, 0, 20, null, true); 5850 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5851 $conversations = $result['conversations']; 5852 $this->assertEquals([], $conversations); 5853 5854 // Try to get NO favourite conversations, when no favourites exist. 5855 $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); 5856 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5857 $conversations = $result['conversations']; 5858 // Consider first conversations is self-conversation. 5859 $this->assertCount(7, $conversations); 5860 5861 // Mark a few conversations as favourites. 5862 \core_message\api::set_favourite_conversation($ic1->id, $user1->id); 5863 \core_message\api::set_favourite_conversation($gc2->id, $user1->id); 5864 \core_message\api::set_favourite_conversation($gc5->id, $user1->id); 5865 5866 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations. 5867 $result = core_message_external::get_conversations($user1->id); 5868 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5869 $conversations = $result['conversations']; 5870 $this->assertCount(7, $conversations); 5871 foreach ($conversations as $conv) { 5872 if (in_array($conv['id'], [$ic1->id, $gc2->id, $gc5->id])) { 5873 $this->assertTrue($conv['isfavourite']); 5874 } 5875 } 5876 5877 // Now, get ONLY favourite conversations. 5878 $result = core_message_external::get_conversations($user1->id, 0, 20, null, true); 5879 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5880 $conversations = $result['conversations']; 5881 $this->assertCount(3, $conversations); 5882 foreach ($conversations as $conv) { 5883 $this->assertTrue($conv['isfavourite']); 5884 } 5885 5886 // Now, try ONLY favourites of type 'group'. 5887 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 5888 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true); 5889 $this->assertCount(2, $conversations); 5890 foreach ($conversations as $conv) { 5891 $this->assertTrue($conv->isfavourite); 5892 } 5893 5894 // And NO favourite conversations. 5895 $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); 5896 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5897 $conversations = $result['conversations']; 5898 $this->assertCount(4, $conversations); 5899 foreach ($conversations as $conv) { 5900 $this->assertFalse($conv['isfavourite']); 5901 } 5902 } 5903 5904 /** 5905 * Test verifying that group linked conversations are returned and contain a subname matching the course name. 5906 */ 5907 public function test_get_conversations_group_linked() { 5908 $this->resetAfterTest(); 5909 global $CFG, $DB; 5910 5911 // Create some users. 5912 $user1 = self::getDataGenerator()->create_user(); 5913 $user2 = self::getDataGenerator()->create_user(); 5914 $user3 = self::getDataGenerator()->create_user(); 5915 5916 $course1 = $this->getDataGenerator()->create_course(); 5917 5918 // Create a group with a linked conversation. 5919 $this->setAdminUser(); 5920 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 5921 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 5922 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 5923 $group1 = $this->getDataGenerator()->create_group([ 5924 'courseid' => $course1->id, 5925 'enablemessaging' => 1, 5926 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' 5927 ]); 5928 5929 // Add users to group1. 5930 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 5931 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 5932 5933 $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); 5934 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5935 $conversations = $result['conversations']; 5936 5937 $this->assertEquals(2, $conversations[0]['membercount']); 5938 $this->assertEquals($course1->shortname, $conversations[0]['subname']); 5939 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true); 5940 $this->assertEquals($groupimageurl, $conversations[0]['imageurl']); 5941 5942 // Now, disable the conversation linked to the group and verify it's no longer returned. 5943 $DB->set_field('message_conversations', 'enabled', 0, ['id' => $conversations[0]['id']]); 5944 $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); 5945 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5946 $conversations = $result['conversations']; 5947 $this->assertCount(0, $conversations); 5948 } 5949 5950 /** 5951 * Test that group conversations containing MathJax don't break the WebService. 5952 */ 5953 public function test_get_conversations_group_with_mathjax() { 5954 $this->resetAfterTest(true); 5955 $this->setAdminUser(); 5956 5957 // Enable MathJax filter in content and headings. 5958 $this->configure_filters([ 5959 ['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true], 5960 ]); 5961 5962 // Create some users, a course and a group with a linked conversation. 5963 $user1 = self::getDataGenerator()->create_user(); 5964 $user2 = self::getDataGenerator()->create_user(); 5965 5966 $coursename = 'Course $$(a+b)=2$$'; 5967 $groupname = 'Group $$(a+b)=2$$'; 5968 $course1 = $this->getDataGenerator()->create_course(['shortname' => $coursename]); 5969 5970 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 5971 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 5972 $group1 = $this->getDataGenerator()->create_group([ 5973 'name' => $groupname, 5974 'courseid' => $course1->id, 5975 'enablemessaging' => 1, 5976 ]); 5977 5978 // Add users to group1. 5979 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 5980 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 5981 5982 // Call the WebService. 5983 $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); 5984 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 5985 $conversations = $result['conversations']; 5986 5987 // Format original data. 5988 $coursecontext = \context_course::instance($course1->id); 5989 $coursename = external_format_string($coursename, $coursecontext->id); 5990 $groupname = external_format_string($groupname, $coursecontext->id); 5991 5992 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', $conversations[0]['name']); 5993 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', $conversations[0]['subname']); 5994 $this->assertEquals($groupname, $conversations[0]['name']); 5995 $this->assertEquals($coursename, $conversations[0]['subname']); 5996 } 5997 5998 /** 5999 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this 6000 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want 6001 * to confirm this happens. 6002 */ 6003 public function test_get_conversations_user_in_group_and_individual_chat() { 6004 $this->resetAfterTest(); 6005 6006 $user1 = self::getDataGenerator()->create_user(); 6007 $user2 = self::getDataGenerator()->create_user(); 6008 $user3 = self::getDataGenerator()->create_user(); 6009 6010 $conversation = \core_message\api::create_conversation( 6011 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6012 [ 6013 $user1->id, 6014 $user2->id 6015 ], 6016 'Individual conversation' 6017 ); 6018 6019 testhelper::send_fake_message_to_conversation($user1, $conversation->id); 6020 6021 $conversation = \core_message\api::create_conversation( 6022 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6023 [ 6024 $user1->id, 6025 $user2->id, 6026 ], 6027 'Group conversation' 6028 ); 6029 6030 testhelper::send_fake_message_to_conversation($user1, $conversation->id); 6031 6032 \core_message\api::create_contact_request($user1->id, $user2->id); 6033 \core_message\api::create_contact_request($user1->id, $user3->id); 6034 6035 $this->setUser($user2); 6036 $result = core_message_external::get_conversations($user2->id); 6037 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 6038 $conversations = $result['conversations']; 6039 6040 $groupconversation = array_shift($conversations); 6041 $individualconversation = array_shift($conversations); 6042 6043 $this->assertEquals('Group conversation', $groupconversation['name']); 6044 $this->assertEquals('Individual conversation', $individualconversation['name']); 6045 6046 $this->assertCount(1, $groupconversation['members']); 6047 $this->assertCount(1, $individualconversation['members']); 6048 6049 $groupmember = reset($groupconversation['members']); 6050 $this->assertNull($groupmember['requirescontact']); 6051 $this->assertNull($groupmember['canmessage']); 6052 $this->assertEmpty($groupmember['contactrequests']); 6053 6054 $individualmember = reset($individualconversation['members']); 6055 $this->assertNotNull($individualmember['requirescontact']); 6056 $this->assertNotNull($individualmember['canmessage']); 6057 $this->assertNotEmpty($individualmember['contactrequests']); 6058 } 6059 6060 /** 6061 * Test verifying get_conversations identifies if a conversation is muted or not. 6062 */ 6063 public function test_get_conversations_some_muted() { 6064 $this->resetAfterTest(); 6065 6066 // Create some users. 6067 $user1 = self::getDataGenerator()->create_user(); 6068 $user2 = self::getDataGenerator()->create_user(); 6069 $user3 = self::getDataGenerator()->create_user(); 6070 6071 $conversation1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6072 [$user1->id, $user2->id]); 6073 testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1'); 6074 testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2'); 6075 \core_message\api::mute_conversation($user1->id, $conversation1->id); 6076 6077 $conversation2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6078 [$user1->id, $user3->id]); 6079 testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 1'); 6080 testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2'); 6081 6082 $conversation3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6083 [$user1->id, $user2->id]); 6084 \core_message\api::mute_conversation($user1->id, $conversation3->id); 6085 6086 $conversation4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6087 [$user1->id, $user3->id]); 6088 6089 $this->setUser($user1); 6090 $result = core_message_external::get_conversations($user1->id); 6091 $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); 6092 $conversations = $result['conversations']; 6093 6094 usort($conversations, function($first, $second){ 6095 return $first['id'] > $second['id']; 6096 }); 6097 6098 $selfconversation = array_shift($conversations); 6099 $conv1 = array_shift($conversations); 6100 $conv2 = array_shift($conversations); 6101 $conv3 = array_shift($conversations); 6102 $conv4 = array_shift($conversations); 6103 6104 $this->assertTrue($conv1['ismuted']); 6105 $this->assertFalse($conv2['ismuted']); 6106 $this->assertTrue($conv3['ismuted']); 6107 $this->assertFalse($conv4['ismuted']); 6108 } 6109 6110 /** 6111 * Test returning members in a conversation with no contact requests. 6112 */ 6113 public function test_get_conversation_members_messaging_disabled() { 6114 global $CFG; 6115 6116 $this->resetAfterTest(); 6117 6118 $CFG->messaging = 0; 6119 6120 $this->expectException('moodle_exception'); 6121 core_message_external::get_conversation_members(1, 2); 6122 } 6123 6124 /** 6125 * Test returning members in a conversation with no contact requests. 6126 */ 6127 public function test_get_conversation_members_wrong_user() { 6128 $this->resetAfterTest(); 6129 6130 $user1 = self::getDataGenerator()->create_user(); 6131 $user2 = self::getDataGenerator()->create_user(); 6132 6133 $this->setUser($user2); 6134 6135 $this->expectException('moodle_exception'); 6136 core_message_external::get_conversation_members($user1->id, 2); 6137 } 6138 6139 /** 6140 * Test returning members in a conversation with no contact requests. 6141 */ 6142 public function test_get_conversation_members() { 6143 $this->resetAfterTest(); 6144 6145 $lastaccess = new stdClass(); 6146 $lastaccess->lastaccess = time(); 6147 6148 $user1 = self::getDataGenerator()->create_user($lastaccess); 6149 $user2 = self::getDataGenerator()->create_user(); 6150 $user3 = self::getDataGenerator()->create_user(); 6151 6152 // This user will not be in the conversation, but a contact request will exist for them. 6153 $user4 = self::getDataGenerator()->create_user(); 6154 6155 // Add some contact requests. 6156 \core_message\api::create_contact_request($user1->id, $user3->id); 6157 \core_message\api::create_contact_request($user1->id, $user4->id); 6158 \core_message\api::create_contact_request($user2->id, $user3->id); 6159 6160 // User 1 and 2 are already contacts. 6161 \core_message\api::add_contact($user1->id, $user2->id); 6162 6163 // User 1 has blocked user 3. 6164 \core_message\api::block_user($user1->id, $user3->id); 6165 6166 $conversation = \core_message\api::create_conversation( 6167 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6168 [ 6169 $user1->id, 6170 $user2->id, 6171 $user3->id 6172 ] 6173 ); 6174 $conversationid = $conversation->id; 6175 6176 $this->setAdminUser(); 6177 6178 $members = core_message_external::get_conversation_members($user1->id, $conversationid, false); 6179 external_api::clean_returnvalue(core_message_external::get_conversation_members_returns(), $members); 6180 6181 // Sort them by id. 6182 ksort($members); 6183 $this->assertCount(3, $members); 6184 $member1 = array_shift($members); 6185 $member2 = array_shift($members); 6186 $member3 = array_shift($members); 6187 6188 // Confirm the standard fields are OK. 6189 $this->assertEquals($user1->id, $member1->id); 6190 $this->assertEquals(fullname($user1), $member1->fullname); 6191 $this->assertEquals(true, $member1->isonline); 6192 $this->assertEquals(true, $member1->showonlinestatus); 6193 $this->assertEquals(false, $member1->iscontact); 6194 $this->assertEquals(false, $member1->isblocked); 6195 $this->assertObjectHasAttribute('contactrequests', $member1); 6196 $this->assertEmpty($member1->contactrequests); 6197 6198 $this->assertEquals($user2->id, $member2->id); 6199 $this->assertEquals(fullname($user2), $member2->fullname); 6200 $this->assertEquals(false, $member2->isonline); 6201 $this->assertEquals(true, $member2->showonlinestatus); 6202 $this->assertEquals(true, $member2->iscontact); 6203 $this->assertEquals(false, $member2->isblocked); 6204 $this->assertObjectHasAttribute('contactrequests', $member2); 6205 $this->assertEmpty($member2->contactrequests); 6206 6207 $this->assertEquals($user3->id, $member3->id); 6208 $this->assertEquals(fullname($user3), $member3->fullname); 6209 $this->assertEquals(false, $member3->isonline); 6210 $this->assertEquals(true, $member3->showonlinestatus); 6211 $this->assertEquals(false, $member3->iscontact); 6212 $this->assertEquals(true, $member3->isblocked); 6213 $this->assertObjectHasAttribute('contactrequests', $member3); 6214 $this->assertEmpty($member3->contactrequests); 6215 } 6216 6217 /** 6218 * Test returning members in a conversation with contact requests. 6219 */ 6220 public function test_get_conversation_members_with_contact_requests() { 6221 $this->resetAfterTest(); 6222 6223 $lastaccess = new stdClass(); 6224 $lastaccess->lastaccess = time(); 6225 6226 $user1 = self::getDataGenerator()->create_user($lastaccess); 6227 $user2 = self::getDataGenerator()->create_user(); 6228 $user3 = self::getDataGenerator()->create_user(); 6229 6230 // This user will not be in the conversation, but a contact request will exist for them. 6231 $user4 = self::getDataGenerator()->create_user(); 6232 6233 // Add some contact requests. 6234 \core_message\api::create_contact_request($user1->id, $user2->id); 6235 \core_message\api::create_contact_request($user1->id, $user3->id); 6236 \core_message\api::create_contact_request($user1->id, $user4->id); 6237 \core_message\api::create_contact_request($user2->id, $user3->id); 6238 6239 // User 1 and 2 are already contacts. 6240 \core_message\api::add_contact($user1->id, $user2->id); 6241 // User 1 has blocked user 3. 6242 \core_message\api::block_user($user1->id, $user3->id); 6243 6244 $conversation = \core_message\api::create_conversation( 6245 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6246 [ 6247 $user1->id, 6248 $user2->id, 6249 $user3->id 6250 ] 6251 ); 6252 $conversationid = $conversation->id; 6253 6254 $this->setAdminUser(); 6255 6256 $members = core_message_external::get_conversation_members($user1->id, $conversationid, true); 6257 external_api::clean_returnvalue(core_message_external::get_conversation_members_returns(), $members); 6258 6259 // Sort them by id. 6260 ksort($members); 6261 $this->assertCount(3, $members); 6262 $member1 = array_shift($members); 6263 $member2 = array_shift($members); 6264 $member3 = array_shift($members); 6265 6266 // Confirm the standard fields are OK. 6267 $this->assertEquals($user1->id, $member1->id); 6268 $this->assertEquals(fullname($user1), $member1->fullname); 6269 $this->assertEquals(true, $member1->isonline); 6270 $this->assertEquals(true, $member1->showonlinestatus); 6271 $this->assertEquals(false, $member1->iscontact); 6272 $this->assertEquals(false, $member1->isblocked); 6273 $this->assertCount(2, $member1->contactrequests); 6274 6275 $this->assertEquals($user2->id, $member2->id); 6276 $this->assertEquals(fullname($user2), $member2->fullname); 6277 $this->assertEquals(false, $member2->isonline); 6278 $this->assertEquals(true, $member2->showonlinestatus); 6279 $this->assertEquals(true, $member2->iscontact); 6280 $this->assertEquals(false, $member2->isblocked); 6281 $this->assertCount(1, $member2->contactrequests); 6282 6283 $this->assertEquals($user3->id, $member3->id); 6284 $this->assertEquals(fullname($user3), $member3->fullname); 6285 $this->assertEquals(false, $member3->isonline); 6286 $this->assertEquals(true, $member3->showonlinestatus); 6287 $this->assertEquals(false, $member3->iscontact); 6288 $this->assertEquals(true, $member3->isblocked); 6289 $this->assertCount(1, $member3->contactrequests); 6290 6291 // Confirm the contact requests are OK. 6292 $request1 = array_shift($member1->contactrequests); 6293 $request2 = array_shift($member1->contactrequests); 6294 6295 $this->assertEquals($user1->id, $request1->userid); 6296 $this->assertEquals($user2->id, $request1->requesteduserid); 6297 6298 $this->assertEquals($user1->id, $request2->userid); 6299 $this->assertEquals($user3->id, $request2->requesteduserid); 6300 6301 $request1 = array_shift($member2->contactrequests); 6302 6303 $this->assertEquals($user1->id, $request1->userid); 6304 $this->assertEquals($user2->id, $request1->requesteduserid); 6305 6306 $request1 = array_shift($member3->contactrequests); 6307 6308 $this->assertEquals($user1->id, $request1->userid); 6309 $this->assertEquals($user3->id, $request1->requesteduserid); 6310 } 6311 6312 /** 6313 * Test returning members in a conversation when you are not a member. 6314 */ 6315 public function test_get_conversation_members_not_a_member() { 6316 $this->resetAfterTest(); 6317 6318 $user1 = self::getDataGenerator()->create_user(); 6319 $user2 = self::getDataGenerator()->create_user(); 6320 6321 // This user will not be in the conversation. 6322 $user3 = self::getDataGenerator()->create_user(); 6323 6324 $conversation = \core_message\api::create_conversation( 6325 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 6326 [ 6327 $user1->id, 6328 $user2->id, 6329 ] 6330 ); 6331 $conversationid = $conversation->id; 6332 6333 $this->setUser($user3); 6334 6335 $this->expectException('moodle_exception'); 6336 core_message_external::get_conversation_members($user3->id, $conversationid); 6337 } 6338 6339 /** 6340 * Test verifying multiple messages can be sent to an individual conversation. 6341 */ 6342 public function test_send_messages_to_conversation_individual() { 6343 $this->resetAfterTest(true); 6344 6345 // Get a bunch of conversations, some group, some individual and in different states. 6346 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 6347 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 6348 6349 // Enrol the users in the same course, so the default privacy controls (course + contacts) can be used. 6350 $course1 = $this->getDataGenerator()->create_course(); 6351 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6352 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6353 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 6354 $this->getDataGenerator()->enrol_user($user4->id, $course1->id); 6355 6356 // The user making the request. 6357 $this->setUser($user1); 6358 6359 // Try to send a message as user1 to a conversation user1 is a a part of. 6360 $messages = [ 6361 [ 6362 'text' => 'a message from user 1', 6363 'textformat' => FORMAT_MOODLE 6364 ], 6365 [ 6366 'text' => 'another message from user 1', 6367 'textformat' => FORMAT_MOODLE 6368 ], 6369 ]; 6370 // Redirect messages. 6371 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 6372 // based on the message_viewed events generated as part of marking the message as read for each user. 6373 $this->preventResetByRollback(); 6374 $sink = $this->redirectMessages(); 6375 $writtenmessages = core_message_external::send_messages_to_conversation($ic1->id, $messages); 6376 6377 external_api::clean_returnvalue(core_message_external::send_messages_to_conversation_returns(), $writtenmessages); 6378 6379 $this->assertCount(2, $writtenmessages); 6380 $this->assertObjectHasAttribute('id', $writtenmessages[0]); 6381 $this->assertEquals($user1->id, $writtenmessages[0]->useridfrom); 6382 $this->assertEquals('<p>a message from user 1</p>', $writtenmessages[0]->text); 6383 $this->assertNotEmpty($writtenmessages[0]->timecreated); 6384 6385 $this->assertObjectHasAttribute('id', $writtenmessages[1]); 6386 $this->assertEquals($user1->id, $writtenmessages[1]->useridfrom); 6387 $this->assertEquals('<p>another message from user 1</p>', $writtenmessages[1]->text); 6388 $this->assertNotEmpty($writtenmessages[1]->timecreated); 6389 } 6390 6391 /** 6392 * Test verifying multiple messages can be sent to an group conversation. 6393 */ 6394 public function test_send_messages_to_conversation_group() { 6395 $this->resetAfterTest(true); 6396 6397 // Get a bunch of conversations, some group, some individual and in different states. 6398 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 6399 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 6400 6401 // Enrol the users in the same course, so the default privacy controls (course + contacts) can be used. 6402 $course1 = $this->getDataGenerator()->create_course(); 6403 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6404 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6405 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 6406 $this->getDataGenerator()->enrol_user($user4->id, $course1->id); 6407 6408 // The user making the request. 6409 $this->setUser($user1); 6410 6411 // Try to send a message as user1 to a conversation user1 is a a part of. 6412 $messages = [ 6413 [ 6414 'text' => 'a message from user 1 to group conv', 6415 'textformat' => FORMAT_MOODLE 6416 ], 6417 [ 6418 'text' => 'another message from user 1 to group conv', 6419 'textformat' => FORMAT_MOODLE 6420 ], 6421 ]; 6422 // Redirect messages. 6423 // This marks messages as read, but we can still observe and verify the number of conversation recipients, 6424 // based on the message_viewed events generated as part of marking the message as read for each user. 6425 $this->preventResetByRollback(); 6426 $sink = $this->redirectMessages(); 6427 $writtenmessages = core_message_external::send_messages_to_conversation($gc2->id, $messages); 6428 6429 external_api::clean_returnvalue(core_message_external::send_messages_to_conversation_returns(), $writtenmessages); 6430 6431 $this->assertCount(2, $writtenmessages); 6432 $this->assertObjectHasAttribute('id', $writtenmessages[0]); 6433 $this->assertEquals($user1->id, $writtenmessages[0]->useridfrom); 6434 $this->assertEquals('<p>a message from user 1 to group conv</p>', $writtenmessages[0]->text); 6435 $this->assertNotEmpty($writtenmessages[0]->timecreated); 6436 6437 $this->assertObjectHasAttribute('id', $writtenmessages[1]); 6438 $this->assertEquals($user1->id, $writtenmessages[1]->useridfrom); 6439 $this->assertEquals('<p>another message from user 1 to group conv</p>', $writtenmessages[1]->text); 6440 $this->assertNotEmpty($writtenmessages[1]->timecreated); 6441 } 6442 6443 /** 6444 * Test verifying multiple messages can not be sent to a non existent conversation. 6445 */ 6446 public function test_send_messages_to_conversation_non_existent_conversation() { 6447 $this->resetAfterTest(true); 6448 6449 // Get a bunch of conversations, some group, some individual and in different states. 6450 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 6451 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 6452 6453 // The user making the request. 6454 $this->setUser($user1); 6455 6456 // Try to send a message as user1 to a conversation user1 is a a part of. 6457 $messages = [ 6458 [ 6459 'text' => 'a message from user 1', 6460 'textformat' => FORMAT_MOODLE 6461 ], 6462 [ 6463 'text' => 'another message from user 1', 6464 'textformat' => FORMAT_MOODLE 6465 ], 6466 ]; 6467 $this->expectException(\moodle_exception::class); 6468 $writtenmessages = core_message_external::send_messages_to_conversation(0, $messages); 6469 } 6470 6471 /** 6472 * Test verifying multiple messages can not be sent to a conversation by a non-member. 6473 */ 6474 public function test_send_messages_to_conversation_non_member() { 6475 $this->resetAfterTest(true); 6476 6477 // Get a bunch of conversations, some group, some individual and in different states. 6478 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 6479 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 6480 6481 // Enrol the users in the same course, so the default privacy controls (course + contacts) can be used. 6482 $course1 = $this->getDataGenerator()->create_course(); 6483 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6484 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6485 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 6486 $this->getDataGenerator()->enrol_user($user4->id, $course1->id); 6487 6488 // The user making the request. This user is not a member of group conversation 1 (gc1). 6489 $this->setUser($user1); 6490 6491 // Try to send a message as user1 to a conversation user1 is a a part of. 6492 $messages = [ 6493 [ 6494 'text' => 'a message from user 1 to group conv', 6495 'textformat' => FORMAT_MOODLE 6496 ], 6497 [ 6498 'text' => 'another message from user 1 to group conv', 6499 'textformat' => FORMAT_MOODLE 6500 ], 6501 ]; 6502 $this->expectException(\moodle_exception::class); 6503 $writtenmessages = core_message_external::send_messages_to_conversation($gc1->id, $messages); 6504 } 6505 6506 /** 6507 * Test verifying a to long message can not be sent to a conversation. 6508 */ 6509 public function test_send_messages_to_conversation_long_text() { 6510 $this->resetAfterTest(true); 6511 6512 // Get a bunch of conversations, some group, some individual and in different states. 6513 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, 6514 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data(); 6515 6516 // Enrol the users in the same course, so the default privacy controls (course + contacts) can be used. 6517 $course1 = $this->getDataGenerator()->create_course(); 6518 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6519 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6520 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 6521 $this->getDataGenerator()->enrol_user($user4->id, $course1->id); 6522 6523 // The user making the request. 6524 $this->setUser($user1); 6525 6526 // Try to send a message as user1 to a conversation user1 is a a part of. 6527 $messages = [ 6528 [ 6529 'text' => str_repeat("M", \core_message\api::MESSAGE_MAX_LENGTH + 100), 6530 'textformat' => FORMAT_MOODLE 6531 ], 6532 ]; 6533 6534 $this->expectException(moodle_exception::class); 6535 $writtenmessages = core_message_external::send_messages_to_conversation($gc2->id, $messages); 6536 } 6537 6538 /** 6539 * Test getting a conversation that doesn't exist. 6540 */ 6541 public function test_get_conversation_no_conversation() { 6542 $this->resetAfterTest(); 6543 6544 $user1 = self::getDataGenerator()->create_user(); 6545 $user2 = self::getDataGenerator()->create_user(); 6546 6547 $name = 'lol conversation'; 6548 $conversation = \core_message\api::create_conversation( 6549 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6550 [ 6551 $user1->id, 6552 $user2->id, 6553 ], 6554 $name 6555 ); 6556 $conversationid = $conversation->id; 6557 6558 $this->setUser($user1); 6559 6560 $this->expectException('moodle_exception'); 6561 $conv = core_message_external::get_conversation($user1->id, $conversationid + 1); 6562 external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6563 } 6564 6565 /** 6566 * Test verifying that the correct favourite information is returned for a non-linked converastion at user context. 6567 */ 6568 public function test_get_conversation_favourited() { 6569 $this->resetAfterTest(); 6570 6571 $user1 = self::getDataGenerator()->create_user(); 6572 $user2 = self::getDataGenerator()->create_user(); 6573 6574 // Create a conversation between the 2 users. 6575 $conversation = \core_message\api::create_conversation( 6576 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6577 [ 6578 $user1->id, 6579 $user2->id, 6580 ], 6581 'An individual conversation' 6582 ); 6583 6584 // Favourite the conversation as user 1 only. 6585 \core_message\api::set_favourite_conversation($conversation->id, $user1->id); 6586 6587 // Get the conversation for user1 and confirm it's favourited. 6588 $this->setUser($user1); 6589 $conv = core_message_external::get_conversation($user1->id, $conversation->id); 6590 $conv = external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6591 $this->assertTrue($conv['isfavourite']); 6592 6593 // Get the conversation for user2 and confirm it's NOT favourited. 6594 $this->setUser($user2); 6595 $conv = core_message_external::get_conversation($user2->id, $conversation->id); 6596 $conv = external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6597 $this->assertFalse($conv['isfavourite']); 6598 } 6599 6600 /** 6601 * Test verifying that the correct favourite information is returned for a group-linked conversation at course context. 6602 */ 6603 public function test_get_conversation_favourited_group_linked() { 6604 $this->resetAfterTest(); 6605 global $DB; 6606 6607 $user1 = self::getDataGenerator()->create_user(); 6608 $user2 = self::getDataGenerator()->create_user(); 6609 $user3 = self::getDataGenerator()->create_user(); 6610 6611 $course1 = $this->getDataGenerator()->create_course(); 6612 $course1context = \context_course::instance($course1->id); 6613 6614 // Create a group with a linked conversation and a valid image. 6615 $this->setAdminUser(); 6616 $this->getDataGenerator()->enrol_user($user1->id, $course1->id); 6617 $this->getDataGenerator()->enrol_user($user2->id, $course1->id); 6618 $this->getDataGenerator()->enrol_user($user3->id, $course1->id); 6619 $group1 = $this->getDataGenerator()->create_group([ 6620 'courseid' => $course1->id, 6621 'enablemessaging' => 1 6622 ]); 6623 6624 // Add users to group1. 6625 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); 6626 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); 6627 6628 // Verify that the conversation is a group linked conversation in the course context. 6629 $conversationrecord = $DB->get_record('message_conversations', ['component' => 'core_group', 'itemtype' => 'groups']); 6630 $this->assertEquals($course1context->id, $conversationrecord->contextid); 6631 6632 // Favourite the conversation as user 1 only. 6633 \core_message\api::set_favourite_conversation($conversationrecord->id, $user1->id); 6634 6635 // Get the conversation for user1 and confirm it's favourited. 6636 $this->setUser($user1); 6637 $conv = core_message_external::get_conversation($user1->id, $conversationrecord->id); 6638 $conv = external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6639 $this->assertTrue($conv['isfavourite']); 6640 6641 // Get the conversation for user2 and confirm it's NOT favourited. 6642 $this->setUser($user2); 6643 $conv = core_message_external::get_conversation($user2->id, $conversationrecord->id); 6644 $conv = external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6645 $this->assertFalse($conv['isfavourite']); 6646 } 6647 6648 /** 6649 * Test getting a conversation with no messages. 6650 */ 6651 public function test_get_conversation_no_messages() { 6652 $this->resetAfterTest(); 6653 6654 $user1 = self::getDataGenerator()->create_user(); 6655 $user2 = self::getDataGenerator()->create_user(); 6656 6657 $name = 'lol conversation'; 6658 $conversation = \core_message\api::create_conversation( 6659 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6660 [ 6661 $user1->id, 6662 $user2->id, 6663 ], 6664 $name 6665 ); 6666 $conversationid = $conversation->id; 6667 6668 $this->setUser($user1); 6669 6670 $conv = core_message_external::get_conversation($user1->id, $conversationid); 6671 external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6672 6673 $conv = (array) $conv; 6674 $this->assertEquals($conversationid, $conv['id']); 6675 $this->assertEquals($name, $conv['name']); 6676 $this->assertArrayHasKey('subname', $conv); 6677 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conv['type']); 6678 $this->assertEquals(2, $conv['membercount']); 6679 $this->assertEquals(false, $conv['isfavourite']); 6680 $this->assertEquals(true, $conv['isread']); 6681 $this->assertEquals(0, $conv['unreadcount']); 6682 $this->assertCount(1, $conv['members']); 6683 foreach ($conv['members'] as $member) { 6684 $member = (array) $member; 6685 $this->assertArrayHasKey('id', $member); 6686 $this->assertArrayHasKey('fullname', $member); 6687 $this->assertArrayHasKey('profileimageurl', $member); 6688 $this->assertArrayHasKey('profileimageurlsmall', $member); 6689 $this->assertArrayHasKey('isonline', $member); 6690 $this->assertArrayHasKey('showonlinestatus', $member); 6691 $this->assertArrayHasKey('isblocked', $member); 6692 $this->assertArrayHasKey('iscontact', $member); 6693 } 6694 $this->assertEmpty($conv['messages']); 6695 } 6696 6697 /** 6698 * Test getting a conversation with messages. 6699 */ 6700 public function test_get_conversation_with_messages() { 6701 $this->resetAfterTest(); 6702 6703 $user1 = self::getDataGenerator()->create_user(); 6704 $user2 = self::getDataGenerator()->create_user(); 6705 $user3 = self::getDataGenerator()->create_user(); 6706 6707 // Some random conversation. 6708 $otherconversation = \core_message\api::create_conversation( 6709 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6710 [ 6711 $user1->id, 6712 $user3->id, 6713 ] 6714 ); 6715 6716 $conversation = \core_message\api::create_conversation( 6717 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 6718 [ 6719 $user1->id, 6720 $user2->id, 6721 ] 6722 ); 6723 $conversationid = $conversation->id; 6724 6725 $time = time(); 6726 $message1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'A', $time - 10); 6727 $message2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'B', $time - 5); 6728 $message3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'C', $time); 6729 6730 // Add some messages to the other convo to make sure they aren't included. 6731 testhelper::send_fake_message_to_conversation($user1, $otherconversation->id, 'foo'); 6732 6733 $this->setUser($user1); 6734 6735 // Test newest first. 6736 $conv = core_message_external::get_conversation( 6737 $user1->id, 6738 $conversationid, 6739 false, 6740 false, 6741 0, 6742 0, 6743 0, 6744 0, 6745 true 6746 ); 6747 external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6748 6749 $conv = (array) $conv; 6750 $this->assertEquals(false, $conv['isread']); 6751 $this->assertEquals(1, $conv['unreadcount']); 6752 $this->assertCount(3, $conv['messages']); 6753 $this->assertEquals($message3id, $conv['messages'][0]->id); 6754 $this->assertEquals($user1->id, $conv['messages'][0]->useridfrom); 6755 $this->assertEquals($message2id, $conv['messages'][1]->id); 6756 $this->assertEquals($user2->id, $conv['messages'][1]->useridfrom); 6757 $this->assertEquals($message1id, $conv['messages'][2]->id); 6758 $this->assertEquals($user1->id, $conv['messages'][2]->useridfrom); 6759 6760 // Test newest last. 6761 $conv = core_message_external::get_conversation( 6762 $user1->id, 6763 $conversationid, 6764 false, 6765 false, 6766 0, 6767 0, 6768 0, 6769 0, 6770 false 6771 ); 6772 external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6773 6774 $conv = (array) $conv; 6775 $this->assertCount(3, $conv['messages']); 6776 $this->assertEquals($message3id, $conv['messages'][2]->id); 6777 $this->assertEquals($user1->id, $conv['messages'][2]->useridfrom); 6778 $this->assertEquals($message2id, $conv['messages'][1]->id); 6779 $this->assertEquals($user2->id, $conv['messages'][1]->useridfrom); 6780 $this->assertEquals($message1id, $conv['messages'][0]->id); 6781 $this->assertEquals($user1->id, $conv['messages'][0]->useridfrom); 6782 6783 // Test message offest and limit. 6784 $conv = core_message_external::get_conversation( 6785 $user1->id, 6786 $conversationid, 6787 false, 6788 false, 6789 0, 6790 0, 6791 1, 6792 1, 6793 true 6794 ); 6795 external_api::clean_returnvalue(core_message_external::get_conversation_returns(), $conv); 6796 6797 $conv = (array) $conv; 6798 $this->assertCount(1, $conv['messages']); 6799 $this->assertEquals($message2id, $conv['messages'][0]->id); 6800 $this->assertEquals($user2->id, $conv['messages'][0]->useridfrom); 6801 } 6802 6803 /** 6804 * Data provider for test_get_conversation_counts(). 6805 */ 6806 public function get_conversation_counts_test_cases() { 6807 $typeindividual = \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; 6808 $typegroup = \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP; 6809 $typeself = \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF; 6810 list($user1, $user2, $user3, $user4, $user5, $user6, $user7, $user8) = [0, 1, 2, 3, 4, 5, 6, 7]; 6811 $conversations = [ 6812 [ 6813 'type' => $typeindividual, 6814 'users' => [$user1, $user2], 6815 'messages' => [$user1, $user2, $user2], 6816 'favourites' => [$user1], 6817 'enabled' => null // Individual conversations cannot be disabled. 6818 ], 6819 [ 6820 'type' => $typeindividual, 6821 'users' => [$user1, $user3], 6822 'messages' => [$user1, $user3, $user1], 6823 'favourites' => [], 6824 'enabled' => null // Individual conversations cannot be disabled. 6825 ], 6826 [ 6827 'type' => $typegroup, 6828 'users' => [$user1, $user2, $user3, $user4], 6829 'messages' => [$user1, $user2, $user3, $user4], 6830 'favourites' => [], 6831 'enabled' => true 6832 ], 6833 [ 6834 'type' => $typegroup, 6835 'users' => [$user2, $user3, $user4], 6836 'messages' => [$user2, $user3, $user4], 6837 'favourites' => [], 6838 'enabled' => true 6839 ], 6840 [ 6841 'type' => $typegroup, 6842 'users' => [$user6, $user7], 6843 'messages' => [$user6, $user7, $user7], 6844 'favourites' => [$user6], 6845 'enabled' => false 6846 ], 6847 [ 6848 'type' => $typeself, 6849 'users' => [$user8], 6850 'messages' => [$user8], 6851 'favourites' => [], 6852 'enabled' => null // Individual conversations cannot be disabled. 6853 ], 6854 ]; 6855 6856 return [ 6857 'No conversations' => [ 6858 'conversationConfigs' => $conversations, 6859 'deletemessagesuser' => null, 6860 'deletemessages' => [], 6861 'arguments' => [$user5], 6862 'expectedcounts' => ['favourites' => 1, 'types' => [ 6863 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6864 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6865 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6866 ]], 6867 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6868 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6869 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 6870 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6871 ]], 6872 'deletedusers' => [] 6873 ], 6874 'No individual conversations, 2 group conversations' => [ 6875 'conversationConfigs' => $conversations, 6876 'deletemessagesuser' => null, 6877 'deletemessages' => [], 6878 'arguments' => [$user4], 6879 'expectedcounts' => ['favourites' => 1, 'types' => [ 6880 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6881 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6882 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6883 ]], 6884 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6885 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6886 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6887 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6888 ]], 6889 'deletedusers' => [] 6890 ], 6891 '2 individual conversations (one favourited), 1 group conversation' => [ 6892 'conversationConfigs' => $conversations, 6893 'deletemessagesuser' => null, 6894 'deletemessages' => [], 6895 'arguments' => [$user1], 6896 'expectedcounts' => ['favourites' => 2, 'types' => [ 6897 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6898 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6899 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6900 ]], 6901 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6902 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6903 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6904 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6905 ]], 6906 'deletedusers' => [] 6907 ], 6908 '1 individual conversation, 2 group conversations' => [ 6909 'conversationConfigs' => $conversations, 6910 'deletemessagesuser' => null, 6911 'deletemessages' => [], 6912 'arguments' => [$user2], 6913 'expectedcounts' => ['favourites' => 1, 'types' => [ 6914 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6915 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6916 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6917 ]], 6918 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6919 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6920 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6921 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6922 ]], 6923 'deletedusers' => [] 6924 ], 6925 '2 group conversations only' => [ 6926 'conversationConfigs' => $conversations, 6927 'deletemessagesuser' => null, 6928 'deletemessages' => [], 6929 'arguments' => [$user4], 6930 'expectedcounts' => ['favourites' => 1, 'types' => [ 6931 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6932 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6933 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6934 ]], 6935 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6936 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 6937 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 6938 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6939 ]], 6940 'deletedusers' => [] 6941 ], 6942 'All conversation types, delete a message from individual favourited, messages remaining' => [ 6943 'conversationConfigs' => $conversations, 6944 'deletemessagesuser' => $user1, 6945 'deletemessages' => [0], 6946 'arguments' => [$user1], 6947 'expectedcounts' => ['favourites' => 2, 'types' => [ 6948 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6949 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6950 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6951 ]], 6952 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6953 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6954 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6955 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6956 ]], 6957 'deletedusers' => [] 6958 ], 6959 'All conversation types, delete a message from individual non-favourited, messages remaining' => [ 6960 'conversationConfigs' => $conversations, 6961 'deletemessagesuser' => $user1, 6962 'deletemessages' => [3], 6963 'arguments' => [$user1], 6964 'expectedcounts' => ['favourites' => 2, 'types' => [ 6965 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6966 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6967 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6968 ]], 6969 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 6970 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6971 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6972 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6973 ]], 6974 'deletedusers' => [] 6975 ], 6976 'All conversation types, delete all messages from individual favourited, no messages remaining' => [ 6977 'conversationConfigs' => $conversations, 6978 'deletemessagesuser' => $user1, 6979 'deletemessages' => [0, 1, 2], 6980 'arguments' => [$user1], 6981 'expectedcounts' => ['favourites' => 1, 'types' => [ 6982 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6983 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6984 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6985 ]], 6986 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 6987 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 6988 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 6989 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 6990 ]], 6991 'deletedusers' => [] 6992 ], 6993 'All conversation types, delete all messages from individual non-favourited, no messages remaining' => [ 6994 'conversationConfigs' => $conversations, 6995 'deletemessagesuser' => $user1, 6996 'deletemessages' => [3, 4, 5], 6997 'arguments' => [$user1], 6998 'expectedcounts' => ['favourites' => 2, 'types' => [ 6999 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7000 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7001 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7002 ]], 7003 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 7004 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7005 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7006 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7007 ]], 7008 'deletedusers' => [] 7009 ], 7010 'All conversation types, delete all messages from individual favourited, no messages remaining, different user' => [ 7011 'conversationConfigs' => $conversations, 7012 'deletemessagesuser' => $user1, 7013 'deletemessages' => [0, 1, 2], 7014 'arguments' => [$user2], 7015 'expectedcounts' => ['favourites' => 1, 'types' => [ 7016 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7017 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 7018 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7019 ]], 7020 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 7021 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7022 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 7023 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7024 ]], 7025 'deletedusers' => [] 7026 ], 7027 'All conversation types, delete all messages from individual non-favourited, no messages remaining, different user' => [ 7028 'conversationConfigs' => $conversations, 7029 'deletemessagesuser' => $user1, 7030 'deletemessages' => [3, 4, 5], 7031 'arguments' => [$user3], 7032 'expectedcounts' => ['favourites' => 1, 'types' => [ 7033 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7034 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 7035 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7036 ]], 7037 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 7038 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7039 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2, 7040 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7041 ]], 7042 'deletedusers' => [] 7043 ], 7044 'All conversation types, delete some messages from group non-favourited, messages remaining,' => [ 7045 'conversationConfigs' => $conversations, 7046 'deletemessagesuser' => $user1, 7047 'deletemessages' => [6, 7], 7048 'arguments' => [$user1], 7049 'expectedcounts' => ['favourites' => 2, 'types' => [ 7050 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7051 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7052 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7053 ]], 7054 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 7055 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7056 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7057 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7058 ]], 7059 'deletedusers' => [] 7060 ], 7061 'All conversation types, delete all messages from group non-favourited, no messages remaining,' => [ 7062 'conversationConfigs' => $conversations, 7063 'deletemessagesuser' => $user1, 7064 'deletemessages' => [6, 7, 8, 9], 7065 'arguments' => [$user1], 7066 'expectedcounts' => ['favourites' => 2, 'types' => [ 7067 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7068 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7069 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7070 ]], 7071 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 7072 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7073 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7074 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7075 ]], 7076 'deletedusers' => [] 7077 ], 7078 'All conversation types, another user soft deleted' => [ 7079 'conversationConfigs' => $conversations, 7080 'deletemessagesuser' => null, 7081 'deletemessages' => [], 7082 'arguments' => [$user1], 7083 'expectedcounts' => ['favourites' => 2, 'types' => [ 7084 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7085 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7086 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7087 ]], 7088 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 7089 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7090 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7091 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7092 ]], 7093 'deletedusers' => [$user2] 7094 ], 7095 'All conversation types, all group users soft deleted' => [ 7096 'conversationConfigs' => $conversations, 7097 'deletemessagesuser' => null, 7098 'deletemessages' => [], 7099 'arguments' => [$user1], 7100 'expectedcounts' => ['favourites' => 2, 'types' => [ 7101 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7102 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7103 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7104 ]], 7105 'expectedunreadcounts' => ['favourites' => 1, 'types' => [ 7106 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1, 7107 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1, 7108 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7109 ]], 7110 'deletedusers' => [$user2, $user3, $user4] 7111 ], 7112 'Group conversation which is disabled, favourited' => [ 7113 'conversationConfigs' => $conversations, 7114 'deletemessagesuser' => null, 7115 'deletemessages' => [], 7116 'arguments' => [$user6], 7117 'expectedcounts' => ['favourites' => 1, 'types' => [ 7118 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7119 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7120 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7121 ]], 7122 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 7123 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7124 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7125 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7126 ]], 7127 'deletedusers' => [] 7128 ], 7129 'Group conversation which is disabled, non-favourited' => [ 7130 'conversationConfigs' => $conversations, 7131 'deletemessagesuser' => null, 7132 'deletemessages' => [], 7133 'arguments' => [$user7], 7134 'expectedcounts' => ['favourites' => 1, 'types' => [ 7135 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7136 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7137 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7138 ]], 7139 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 7140 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7141 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7142 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7143 ]], 7144 'deletedusers' => [] 7145 ], 7146 'Conversation with self' => [ 7147 'conversationConfigs' => $conversations, 7148 'deletemessagesuser' => null, 7149 'deletemessages' => [], 7150 'arguments' => [$user8], 7151 'expectedcounts' => ['favourites' => 0, 'types' => [ 7152 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7153 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7154 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 1 7155 ]], 7156 'expectedunreadcounts' => ['favourites' => 0, 'types' => [ 7157 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 7158 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0, 7159 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => 0 7160 ]], 7161 'deletedusers' => [] 7162 ], 7163 ]; 7164 } 7165 7166 /** 7167 * Test the get_conversation_counts() function. 7168 * 7169 * @dataProvider get_conversation_counts_test_cases() 7170 * @param array $conversationconfigs Conversations to create 7171 * @param int $deletemessagesuser The user who is deleting the messages 7172 * @param array $deletemessages The list of messages to delete (by index) 7173 * @param array $arguments Arguments for the count conversations function 7174 * @param array $expectedcounts the expected conversation counts 7175 * @param array $expectedunreadcounts the expected unread conversation counts 7176 * @param array $deletedusers the array of users to soft delete. 7177 */ 7178 public function test_get_conversation_counts( 7179 $conversationconfigs, 7180 $deletemessagesuser, 7181 $deletemessages, 7182 $arguments, 7183 $expectedcounts, 7184 $expectedunreadcounts, 7185 $deletedusers 7186 ) { 7187 $this->resetAfterTest(); 7188 $generator = $this->getDataGenerator(); 7189 $users = [ 7190 $generator->create_user(), 7191 $generator->create_user(), 7192 $generator->create_user(), 7193 $generator->create_user(), 7194 $generator->create_user(), 7195 $generator->create_user(), 7196 $generator->create_user(), 7197 $generator->create_user() 7198 ]; 7199 7200 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 7201 $this->setUser($users[$arguments[0]]); 7202 $arguments[0] = $users[$arguments[0]]->id; 7203 $systemcontext = \context_system::instance(); 7204 $conversations = []; 7205 $messageids = []; 7206 7207 foreach ($conversationconfigs as $config) { 7208 $conversation = \core_message\api::create_conversation( 7209 $config['type'], 7210 array_map(function($userindex) use ($users) { 7211 return $users[$userindex]->id; 7212 }, $config['users']), 7213 null, 7214 ($config['enabled'] ?? true) 7215 ); 7216 7217 foreach ($config['messages'] as $userfromindex) { 7218 $userfrom = $users[$userfromindex]; 7219 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 7220 } 7221 7222 // Remove the self conversations created by the generator, 7223 // so we can choose to set that ourself and honour the original intention of the test. 7224 $userids = array_map(function($userindex) use ($users) { 7225 return $users[$userindex]->id; 7226 }, $config['users']); 7227 foreach ($userids as $userid) { 7228 if ($conversation->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) { 7229 \core_message\api::unset_favourite_conversation($conversation->id, $userid); 7230 } 7231 } 7232 7233 foreach ($config['favourites'] as $userfromindex) { 7234 $userfrom = $users[$userfromindex]; 7235 $usercontext = \context_user::instance($userfrom->id); 7236 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 7237 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 7238 } 7239 7240 $conversations[] = $conversation; 7241 } 7242 7243 foreach ($deletemessages as $messageindex) { 7244 \core_message\api::delete_message($deleteuser->id, $messageids[$messageindex]); 7245 } 7246 7247 foreach ($deletedusers as $deleteduser) { 7248 delete_user($users[$deleteduser]); 7249 } 7250 7251 $counts = core_message_external::get_conversation_counts(...$arguments); 7252 $counts = external_api::clean_returnvalue(core_message_external::get_conversation_counts_returns(), $counts); 7253 7254 $this->assertEquals($expectedcounts['favourites'], $counts['favourites']); 7255 $this->assertEquals($expectedcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 7256 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 7257 $this->assertEquals($expectedcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP], 7258 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP]); 7259 $this->assertEquals($expectedcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF], 7260 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF]); 7261 } 7262 7263 /** 7264 * Test the get_unread_conversation_counts() function. 7265 * 7266 * @dataProvider get_conversation_counts_test_cases 7267 * @param array $conversationconfigs Conversations to create 7268 * @param int $deletemessagesuser The user who is deleting the messages 7269 * @param array $deletemessages The list of messages to delete (by index) 7270 * @param array $arguments Arguments for the count conversations function 7271 * @param array $expectedcounts the expected conversation counts 7272 * @param array $expectedunreadcounts the expected unread conversation counts 7273 * @param array $deletedusers the list of users to soft-delete. 7274 */ 7275 public function test_get_unread_conversation_counts( 7276 $conversationconfigs, 7277 $deletemessagesuser, 7278 $deletemessages, 7279 $arguments, 7280 $expectedcounts, 7281 $expectedunreadcounts, 7282 $deletedusers 7283 ) { 7284 $this->resetAfterTest(); 7285 $generator = $this->getDataGenerator(); 7286 $users = [ 7287 $generator->create_user(), 7288 $generator->create_user(), 7289 $generator->create_user(), 7290 $generator->create_user(), 7291 $generator->create_user(), 7292 $generator->create_user(), 7293 $generator->create_user(), 7294 $generator->create_user() 7295 ]; 7296 7297 $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null; 7298 $this->setUser($users[$arguments[0]]); 7299 $arguments[0] = $users[$arguments[0]]->id; 7300 $systemcontext = \context_system::instance(); 7301 $conversations = []; 7302 $messageids = []; 7303 7304 foreach ($conversationconfigs as $config) { 7305 $conversation = \core_message\api::create_conversation( 7306 $config['type'], 7307 array_map(function($userindex) use ($users) { 7308 return $users[$userindex]->id; 7309 }, $config['users']), 7310 null, 7311 ($config['enabled'] ?? true) 7312 ); 7313 7314 foreach ($config['messages'] as $userfromindex) { 7315 $userfrom = $users[$userfromindex]; 7316 $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id); 7317 } 7318 7319 foreach ($config['favourites'] as $userfromindex) { 7320 $userfrom = $users[$userfromindex]; 7321 $usercontext = \context_user::instance($userfrom->id); 7322 $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); 7323 $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext); 7324 } 7325 7326 $conversations[] = $conversation; 7327 } 7328 7329 foreach ($deletemessages as $messageindex) { 7330 \core_message\api::delete_message($deleteuser->id, $messageids[$messageindex]); 7331 } 7332 7333 foreach ($deletedusers as $deleteduser) { 7334 delete_user($users[$deleteduser]); 7335 } 7336 7337 $counts = core_message_external::get_unread_conversation_counts(...$arguments); 7338 $counts = external_api::clean_returnvalue(core_message_external::get_unread_conversation_counts_returns(), $counts); 7339 7340 $this->assertEquals($expectedunreadcounts['favourites'], $counts['favourites']); 7341 $this->assertEquals($expectedunreadcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], 7342 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]); 7343 $this->assertEquals($expectedunreadcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP], 7344 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP]); 7345 $this->assertEquals($expectedunreadcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF], 7346 $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF]); 7347 } 7348 7349 /** 7350 * Test delete_message for all users. 7351 */ 7352 public function test_delete_message_for_all_users() { 7353 global $DB; 7354 7355 $this->resetAfterTest(true); 7356 7357 // Create fake data to test it. 7358 list($user1, $user2, $user3, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 7359 7360 // Send message as user1 to group conversation. 7361 $messageid1 = testhelper::send_fake_message_to_conversation($user1, $convgroup->id); 7362 $messageid2 = testhelper::send_fake_message_to_conversation($user2, $convgroup->id); 7363 7364 // User1 deletes the first message for all users of group conversation. 7365 // First, we have to allow user1 (Teacher) can delete messages for all users. 7366 $editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']); 7367 assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, context_system::instance()); 7368 7369 $this->setUser($user1); 7370 7371 // Now, user1 deletes message for all users. 7372 $return = core_message_external::delete_message_for_all_users($messageid1, $user1->id); 7373 $return = external_api::clean_returnvalue(core_message_external::delete_message_for_all_users_returns(), $return); 7374 // Check if everything is ok. 7375 $this->assertEquals(array(), $return); 7376 7377 // Check we have 3 records on message_user_actions with the mark MESSAGE_ACTION_DELETED. 7378 $muas = $DB->get_records('message_user_actions', array('messageid' => $messageid1), 'userid ASC'); 7379 $this->assertCount(3, $muas); 7380 $mua1 = array_shift($muas); 7381 $mua2 = array_shift($muas); 7382 $mua3 = array_shift($muas); 7383 7384 $this->assertEquals($user1->id, $mua1->userid); 7385 $this->assertEquals($messageid1, $mua1->messageid); 7386 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action); 7387 $this->assertEquals($user2->id, $mua2->userid); 7388 $this->assertEquals($messageid1, $mua2->messageid); 7389 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action); 7390 $this->assertEquals($user3->id, $mua3->userid); 7391 $this->assertEquals($messageid1, $mua3->messageid); 7392 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action); 7393 } 7394 7395 /** 7396 * Test delete_message for all users with messaging disabled. 7397 */ 7398 public function test_delete_message_for_all_users_messaging_disabled() { 7399 global $CFG; 7400 7401 $this->resetAfterTest(); 7402 7403 // Create fake data to test it. 7404 list($user1, $user2, $user3, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 7405 7406 // Send message as user1 to group conversation. 7407 $messageid = testhelper::send_fake_message_to_conversation($user1, $convgroup->id); 7408 7409 $this->setUser($user1); 7410 7411 // Disable messaging. 7412 $CFG->messaging = 0; 7413 7414 // Ensure an exception is thrown. 7415 $this->expectException('moodle_exception'); 7416 core_message_external::delete_message_for_all_users($messageid, $user1->id); 7417 } 7418 7419 /** 7420 * Test delete_message for all users with no permission. 7421 */ 7422 public function test_delete_message_for_all_users_no_permission() { 7423 $this->resetAfterTest(); 7424 7425 // Create fake data to test it. 7426 list($user1, $user2, $user3, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 7427 7428 // Send message as user1 to group conversation. 7429 $messageid = testhelper::send_fake_message_to_conversation($user1, $convgroup->id); 7430 7431 $this->setUser($user2); 7432 7433 // Try as user2 to delete a message for all users without permission to do it. 7434 $this->expectException('moodle_exception'); 7435 $this->expectExceptionMessage('You do not have permission to delete this message for everyone.'); 7436 core_message_external::delete_message_for_all_users($messageid, $user2->id); 7437 } 7438 7439 /** 7440 * Test delete_message for all users in a private conversation. 7441 */ 7442 public function test_delete_message_for_all_users_private_conversation() { 7443 global $DB; 7444 7445 $this->resetAfterTest(); 7446 7447 // Create fake data to test it. 7448 list($user1, $user2, $user3, $convgroup, $convindividual) = $this->create_delete_message_test_data(); 7449 7450 // Send message as user1 to private conversation. 7451 $messageid = testhelper::send_fake_message_to_conversation($user1, $convindividual->id); 7452 7453 // First, we have to allow user1 (Teacher) can delete messages for all users. 7454 $editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']); 7455 assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, context_system::instance()); 7456 7457 $this->setUser($user1); 7458 7459 // Try as user1 to delete a private message for all users on individual conversation. 7460 // User1 should not delete message for all users in a private conversations despite being a teacher. 7461 // Because is a teacher in a course and not in a system context. 7462 $this->expectException('moodle_exception'); 7463 $this->expectExceptionMessage('You do not have permission to delete this message for everyone.'); 7464 core_message_external::delete_message_for_all_users($messageid, $user1->id); 7465 } 7466 7467 /** 7468 * Test retrieving conversation messages by providing a timefrom higher than last message timecreated. It should return no 7469 * messages but keep the return structure to not break when called from the ws. 7470 */ 7471 public function test_get_conversation_messages_timefrom_higher_than_last_timecreated() { 7472 $this->resetAfterTest(true); 7473 7474 // Create some users. 7475 $user1 = self::getDataGenerator()->create_user(); 7476 $user2 = self::getDataGenerator()->create_user(); 7477 $user3 = self::getDataGenerator()->create_user(); 7478 $user4 = self::getDataGenerator()->create_user(); 7479 7480 // Create group conversation. 7481 $conversation = \core_message\api::create_conversation( 7482 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 7483 [$user1->id, $user2->id, $user3->id, $user4->id] 7484 ); 7485 7486 // The person asking for the messages for another user. 7487 $this->setUser($user1); 7488 7489 // Send some messages back and forth. 7490 $time = 1; 7491 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1); 7492 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2); 7493 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3); 7494 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4); 7495 7496 // Retrieve the messages. 7497 $result = core_message_external::get_conversation_messages($user1->id, $conversation->id, 0, 0, '', $time + 5); 7498 7499 // We need to execute the return values cleaning process to simulate the web service server. 7500 $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(), $result); 7501 7502 // Check the results are correct. 7503 $this->assertEquals($conversation->id, $result['id']); 7504 7505 // Confirm the message data is correct. 7506 $messages = $result['messages']; 7507 $this->assertEquals(0, count($messages)); 7508 7509 // Confirm that members key is present. 7510 $this->assertArrayHasKey('members', $result); 7511 } 7512 7513 /** 7514 * Helper to seed the database with initial state with data. 7515 */ 7516 protected function create_delete_message_test_data() { 7517 // Create some users. 7518 $user1 = self::getDataGenerator()->create_user(); 7519 $user2 = self::getDataGenerator()->create_user(); 7520 $user3 = self::getDataGenerator()->create_user(); 7521 7522 // Create a course and enrol the users. 7523 $course = $this->getDataGenerator()->create_course(); 7524 $coursecontext = context_course::instance($course->id); 7525 $this->getDataGenerator()->enrol_user($user1->id, $course->id, 'editingteacher'); 7526 $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student'); 7527 $this->getDataGenerator()->enrol_user($user3->id, $course->id, 'student'); 7528 7529 // Create a group and added the users into. 7530 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); 7531 groups_add_member($group1->id, $user1->id); 7532 groups_add_member($group1->id, $user2->id); 7533 groups_add_member($group1->id, $user3->id); 7534 7535 // Create a group conversation linked with the course. 7536 $convgroup = \core_message\api::create_conversation( 7537 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, 7538 [$user1->id, $user2->id, $user3->id], 7539 'Group test delete for everyone', \core_message\api::MESSAGE_CONVERSATION_ENABLED, 7540 'core_group', 7541 'groups', 7542 $group1->id, 7543 context_course::instance($course->id)->id 7544 ); 7545 7546 // Create and individual conversation. 7547 $convindividual = \core_message\api::create_conversation( 7548 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 7549 [$user1->id, $user2->id] 7550 ); 7551 7552 return [$user1, $user2, $user3, $convgroup, $convindividual]; 7553 } 7554 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body