2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
20 * @package core_message
22 * @copyright 2016 Mark Nelson <markn@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
30 require_once($CFG->dirroot . '/message/tests/messagelib_test.php');
32 use \core_message\tests\helper as testhelper;
37 * @package core_message
39 * @copyright 2016 Mark Nelson <markn@moodle.com>
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 class core_message_api_testcase extends core_message_messagelib_testcase {
44 public function test_mark_all_read_for_user_touser() {
45 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
46 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
48 $this->send_fake_message($sender, $recipient, 'Notification', 1);
49 $this->send_fake_message($sender, $recipient, 'Notification', 1);
50 $this->send_fake_message($sender, $recipient, 'Notification', 1);
51 $this->send_fake_message($sender, $recipient);
52 $this->send_fake_message($sender, $recipient);
53 $this->send_fake_message($sender, $recipient);
55 \core_message\api::mark_all_notifications_as_read($recipient->id);
56 \core_message\api::mark_all_messages_as_read($recipient->id);
58 $this->assertEquals(message_count_unread_messages($recipient), 0);
59 $this->assertDebuggingCalled();
62 public function test_mark_all_read_for_user_touser_with_fromuser() {
63 $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
64 $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
65 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
67 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
68 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
69 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
70 $this->send_fake_message($sender1, $recipient);
71 $this->send_fake_message($sender1, $recipient);
72 $this->send_fake_message($sender1, $recipient);
73 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
74 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
75 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
76 $this->send_fake_message($sender2, $recipient);
77 $this->send_fake_message($sender2, $recipient);
78 $this->send_fake_message($sender2, $recipient);
80 \core_message\api::mark_all_notifications_as_read($recipient->id, $sender1->id);
81 $conversationid = \core_message\api::get_conversation_between_users([$recipient->id, $sender1->id]);
82 \core_message\api::mark_all_messages_as_read($recipient->id, $conversationid);
84 $this->assertEquals(message_count_unread_messages($recipient), 3);
85 $this->assertDebuggingCalled();
88 public function test_mark_all_read_for_user_touser_with_type() {
89 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
90 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
92 $this->send_fake_message($sender, $recipient, 'Notification', 1);
93 $this->send_fake_message($sender, $recipient, 'Notification', 1);
94 $this->send_fake_message($sender, $recipient, 'Notification', 1);
95 $this->send_fake_message($sender, $recipient);
96 $this->send_fake_message($sender, $recipient);
97 $this->send_fake_message($sender, $recipient);
99 \core_message\api::mark_all_notifications_as_read($recipient->id);
100 $this->assertEquals(message_count_unread_messages($recipient), 3);
101 $this->assertDebuggingCalled();
103 \core_message\api::mark_all_messages_as_read($recipient->id);
104 $this->assertEquals(message_count_unread_messages($recipient), 0);
105 $this->assertDebuggingCalled();
109 * Test count_blocked_users.
111 public function test_count_blocked_users() {
114 // Set this user as the admin.
115 $this->setAdminUser();
117 // Create user to add to the admin's block list.
118 $user1 = $this->getDataGenerator()->create_user();
119 $user2 = $this->getDataGenerator()->create_user();
121 $this->assertEquals(0, \core_message\api::count_blocked_users());
123 // Add 1 blocked user to admin's blocked user list.
124 \core_message\api::block_user($USER->id, $user1->id);
126 $this->assertEquals(0, \core_message\api::count_blocked_users($user1));
127 $this->assertEquals(1, \core_message\api::count_blocked_users());
131 * Tests searching for users when site-wide messaging is disabled.
133 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
134 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
137 public function test_message_search_users_messagingallusers_disabled() {
139 $this->resetAfterTest();
141 // Create some users.
143 foreach (range(1, 8) as $i) {
144 $user = new stdClass();
145 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
146 $user->lastname = $i;
147 $user = $this->getDataGenerator()->create_user($user);
151 // Enrol a few users in the same course, but leave them as non-contacts.
152 $course1 = $this->getDataGenerator()->create_course();
153 $course2 = $this->getDataGenerator()->create_course();
155 $this->setAdminUser();
156 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
157 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
158 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
160 // Add some other users as contacts.
161 \core_message\api::add_contact($users[1]->id, $users[2]->id);
162 \core_message\api::add_contact($users[3]->id, $users[1]->id);
163 \core_message\api::add_contact($users[1]->id, $users[4]->id);
165 // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
166 $this->getDataGenerator()->enrol_user($users[8]->id, $course2->id, 'editingteacher');
167 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
168 set_config('coursecontact', $teacherrole->id);
170 // Create individual conversations between some users, one contact and one non-contact.
171 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
172 [$users[1]->id, $users[2]->id]);
173 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
174 [$users[6]->id, $users[1]->id]);
176 // Create a group conversation between 4 users, including a contact and a non-contact.
177 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
178 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
180 // Set as the user performing the search.
181 $this->setUser($users[1]);
183 // Perform a search with $CFG->messagingallusers disabled.
184 set_config('messagingallusers', 0);
185 $result = \core_message\api::message_search_users($users[1]->id, 'search');
187 // Confirm that we returns contacts and non-contacts.
188 $this->assertArrayHasKey(0, $result);
189 $this->assertArrayHasKey(1, $result);
190 $contacts = $result[0];
191 $noncontacts = $result[1];
193 // Check that we retrieved the correct contacts.
194 $this->assertCount(2, $contacts);
195 $this->assertEquals($users[2]->id, $contacts[0]->id);
196 $this->assertEquals($users[3]->id, $contacts[1]->id);
198 // Verify the correct conversations were returned for the contacts.
199 $this->assertCount(2, $contacts[0]->conversations);
200 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
201 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
203 $this->assertCount(0, $contacts[1]->conversations);
205 // Check that we retrieved the correct non-contacts.
206 // When site wide messaging is disabled, we expect to see only those users who we share a course with and whose profiles
207 // are visible in that course. This excludes users like course contacts.
208 $this->assertCount(3, $noncontacts);
209 // Self-conversation first.
210 $this->assertEquals($users[1]->id, $noncontacts[0]->id);
211 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
212 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
214 // Verify the correct conversations were returned for the non-contacts.
215 $this->assertCount(1, $noncontacts[1]->conversations);
216 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
217 $noncontacts[1]->conversations[$ic2->id]->type);
219 $this->assertCount(1, $noncontacts[2]->conversations);
220 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
224 * Tests searching for users when site-wide messaging is enabled.
226 * This test verifies that any contacts are returned, as well as any non-contacts,
227 * provided the searching user can view their profile.
229 public function test_message_search_users_messagingallusers_enabled() {
231 $this->resetAfterTest();
233 // Create some users.
235 foreach (range(1, 9) as $i) {
236 $user = new stdClass();
237 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
238 $user->lastname = $i;
239 $user = $this->getDataGenerator()->create_user($user);
243 $course1 = $this->getDataGenerator()->create_course();
244 $coursecontext = \context_course::instance($course1->id);
246 // Enrol a few users in the same course, but leave them as non-contacts.
247 $this->setAdminUser();
248 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id, 'student');
249 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id, 'student');
250 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id, 'student');
252 // Add some other users as contacts.
253 \core_message\api::add_contact($users[1]->id, $users[2]->id);
254 \core_message\api::add_contact($users[3]->id, $users[1]->id);
255 \core_message\api::add_contact($users[1]->id, $users[4]->id);
257 // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
258 $this->getDataGenerator()->enrol_user($users[9]->id, $course1->id, 'editingteacher');
259 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
260 set_config('coursecontact', $teacherrole->id);
262 // Get self-conversation.
263 $selfconversation = \core_message\api::get_self_conversation($users[1]->id);
265 // Create individual conversations between some users, one contact and one non-contact.
266 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
267 [$users[1]->id, $users[2]->id]);
268 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
269 [$users[6]->id, $users[1]->id]);
271 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
272 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
273 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
275 // Set as the user performing the search.
276 $this->setUser($users[1]);
278 // Perform a search with $CFG->messagingallusers enabled.
279 set_config('messagingallusers', 1);
280 $result = \core_message\api::message_search_users($users[1]->id, 'search');
282 // Confirm that we returns contacts and non-contacts.
283 $this->assertArrayHasKey(0, $result);
284 $this->assertArrayHasKey(1, $result);
285 $contacts = $result[0];
286 $noncontacts = $result[1];
288 // Check that we retrieved the correct contacts.
289 $this->assertCount(2, $contacts);
290 $this->assertEquals($users[2]->id, $contacts[0]->id);
291 $this->assertEquals($users[3]->id, $contacts[1]->id);
293 // Verify the correct conversations were returned for the contacts.
294 $this->assertCount(2, $contacts[0]->conversations);
295 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
296 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
298 $this->assertCount(0, $contacts[1]->conversations);
300 // Check that we retrieved the correct non-contacts.
301 // If site wide messaging is enabled, we expect to only be able to search for users whose profiles we can view.
302 // In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1.
303 // Consider first conversations is self-conversation.
304 $this->assertCount(4, $noncontacts);
305 $this->assertEquals($users[1]->id, $noncontacts[0]->id);
306 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
307 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
308 $this->assertEquals($users[9]->id, $noncontacts[3]->id);
310 $this->assertCount(1, $noncontacts[1]->conversations);
311 $this->assertCount(1, $noncontacts[2]->conversations);
312 $this->assertCount(0, $noncontacts[3]->conversations);
314 // Verify the correct conversations were returned for the non-contacts.
315 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
316 $noncontacts[0]->conversations[$selfconversation->id]->type);
318 $this->assertCount(1, $noncontacts[1]->conversations);
319 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
320 $noncontacts[1]->conversations[$ic2->id]->type);
322 $this->assertCount(1, $noncontacts[2]->conversations);
323 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
325 $this->assertCount(0, $noncontacts[3]->conversations);
329 * Verify searching for users find themselves when they have self-conversations.
331 public function test_message_search_users_self_conversations() {
332 $this->resetAfterTest();
334 // Create some users.
335 $user1 = new stdClass();
336 $user1->firstname = 'User';
337 $user1->lastname = 'One';
338 $user1 = $this->getDataGenerator()->create_user($user1);
339 $user2 = new stdClass();
340 $user2->firstname = 'User';
341 $user2->lastname = 'Two';
342 $user2 = $this->getDataGenerator()->create_user($user2);
344 // Get self-conversation for user1.
345 $sc1 = \core_message\api::get_self_conversation($user1->id);
346 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi myself!');
348 // Perform a search as user1.
349 $this->setUser($user1);
350 $result = \core_message\api::message_search_users($user1->id, 'One');
352 // Check user1 is found as non-contacts.
353 $this->assertCount(0, $result[0]);
354 $this->assertCount(1, $result[1]);
358 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
360 public function test_message_search_users_with_empty_result() {
361 $this->resetAfterTest();
363 // Create some users, but make sure neither will match the search term.
364 $user1 = new stdClass();
365 $user1->firstname = 'User';
366 $user1->lastname = 'One';
367 $user1 = $this->getDataGenerator()->create_user($user1);
368 $user2 = new stdClass();
369 $user2->firstname = 'User';
370 $user2->lastname = 'Two';
371 $user2 = $this->getDataGenerator()->create_user($user2);
373 // Perform a search as user1.
374 $this->setUser($user1);
375 $result = \core_message\api::message_search_users($user1->id, 'search');
377 // Check results are empty.
378 $this->assertCount(0, $result[0]);
379 $this->assertCount(0, $result[1]);
383 * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
385 public function test_message_search_users_limit_offset() {
386 $this->resetAfterTest();
390 foreach (range(1, 20) as $i) {
391 $user = new stdClass();
392 $user->firstname = "User search";
393 $user->lastname = $i;
394 $user = $this->getDataGenerator()->create_user($user);
398 // Enrol the first 9 users in the same course, but leave them as non-contacts.
399 $this->setAdminUser();
400 $course1 = $this->getDataGenerator()->create_course();
401 foreach (range(1, 8) as $i) {
402 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
405 // Add 5 users, starting at the 11th user, as contacts for user1.
406 foreach (range(11, 15) as $i) {
407 \core_message\api::add_contact($users[1]->id, $users[$i]->id);
410 // Set as the user performing the search.
411 $this->setUser($users[1]);
413 // Search using a limit of 3.
414 // This tests the case where we have more results than the limit for both contacts and non-contacts.
415 $result = \core_message\api::message_search_users($users[1]->id, 'search', 0, 3);
416 $contacts = $result[0];
417 $noncontacts = $result[1];
419 // Check that we retrieved the correct contacts.
420 $this->assertCount(3, $contacts);
421 $this->assertEquals($users[11]->id, $contacts[0]->id);
422 $this->assertEquals($users[12]->id, $contacts[1]->id);
423 $this->assertEquals($users[13]->id, $contacts[2]->id);
425 // Check that we retrieved the correct non-contacts.
426 // Consider first conversations is self-conversation.
427 $this->assertCount(3, $noncontacts);
428 $this->assertEquals($users[1]->id, $noncontacts[0]->id);
429 $this->assertEquals($users[2]->id, $noncontacts[1]->id);
430 $this->assertEquals($users[3]->id, $noncontacts[2]->id);
432 // Now, offset to get the next batch of results.
433 // We expect to see 2 contacts, and 3 non-contacts.
434 $result = \core_message\api::message_search_users($users[1]->id, 'search', 3, 3);
435 $contacts = $result[0];
436 $noncontacts = $result[1];
437 $this->assertCount(2, $contacts);
438 $this->assertEquals($users[14]->id, $contacts[0]->id);
439 $this->assertEquals($users[15]->id, $contacts[1]->id);
441 $this->assertCount(3, $noncontacts);
442 $this->assertEquals($users[4]->id, $noncontacts[0]->id);
443 $this->assertEquals($users[5]->id, $noncontacts[1]->id);
444 $this->assertEquals($users[6]->id, $noncontacts[2]->id);
446 // Now, offset to get the next batch of results.
447 // We expect to see 0 contacts, and 2 non-contacts.
448 $result = \core_message\api::message_search_users($users[1]->id, 'search', 6, 3);
449 $contacts = $result[0];
450 $noncontacts = $result[1];
451 $this->assertCount(0, $contacts);
453 $this->assertCount(2, $noncontacts);
454 $this->assertEquals($users[7]->id, $noncontacts[0]->id);
455 $this->assertEquals($users[8]->id, $noncontacts[1]->id);
459 * Tests searching users as a user having the 'moodle/user:viewdetails' capability.
461 public function test_message_search_users_with_cap() {
462 $this->resetAfterTest();
465 // Create some users.
467 foreach (range(1, 8) as $i) {
468 $user = new stdClass();
469 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
470 $user->lastname = $i;
471 $user = $this->getDataGenerator()->create_user($user);
475 // Enrol a few users in the same course, but leave them as non-contacts.
476 $course1 = $this->getDataGenerator()->create_course();
477 $this->setAdminUser();
478 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
479 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
480 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
482 // Add some other users as contacts.
483 \core_message\api::add_contact($users[1]->id, $users[2]->id);
484 \core_message\api::add_contact($users[3]->id, $users[1]->id);
485 \core_message\api::add_contact($users[1]->id, $users[4]->id);
487 // Set as the user performing the search.
488 $this->setUser($users[1]);
490 // Grant the authenticated user role the capability 'user:viewdetails' at site context.
491 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
492 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance());
494 // Perform a search with $CFG->messagingallusers disabled.
495 set_config('messagingallusers', 0);
496 $result = \core_message\api::message_search_users($users[1]->id, 'search');
497 $contacts = $result[0];
498 $noncontacts = $result[1];
500 // Check that we retrieved the correct contacts.
501 $this->assertCount(2, $contacts);
502 $this->assertEquals($users[2]->id, $contacts[0]->id);
503 $this->assertEquals($users[3]->id, $contacts[1]->id);
505 // Check that we retrieved the correct non-contacts.
506 // Site-wide messaging is disabled, so we expect to be able to search for any users whose profiles we can view.
507 // Consider first conversations is self-conversation.
508 $this->assertCount(3, $noncontacts);
509 $this->assertEquals($users[1]->id, $noncontacts[0]->id);
510 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
511 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
515 * Tests searching users with messaging disabled.
517 public function test_message_search_users_messaging_disabled() {
518 $this->resetAfterTest();
521 $user = $this->getDataGenerator()->create_user();
523 // Disable messaging.
524 set_config('messaging', 0);
526 // Ensure an exception is thrown.
527 $this->expectException('moodle_exception');
528 \core_message\api::message_search_users($user->id, 'User');
532 * Tests getting conversations between 2 users.
534 public function test_get_conversations_between_users() {
535 // Create some users.
536 $user1 = new stdClass();
537 $user1->firstname = 'User';
538 $user1->lastname = 'One';
539 $user1 = self::getDataGenerator()->create_user($user1);
541 $user2 = new stdClass();
542 $user2->firstname = 'User';
543 $user2->lastname = 'Two';
544 $user2 = self::getDataGenerator()->create_user($user2);
546 $user3 = new stdClass();
547 $user3->firstname = 'User search';
548 $user3->lastname = 'Three';
549 $user3 = self::getDataGenerator()->create_user($user3);
551 $user4 = new stdClass();
552 $user4->firstname = 'User';
553 $user4->lastname = 'Four';
554 $user4 = self::getDataGenerator()->create_user($user4);
556 $user5 = new stdClass();
557 $user5->firstname = 'User';
558 $user5->lastname = 'Five';
559 $user5 = self::getDataGenerator()->create_user($user5);
561 $user6 = new stdClass();
562 $user6->firstname = 'User search';
563 $user6->lastname = 'Six';
564 $user6 = self::getDataGenerator()->create_user($user6);
566 // Add some users as contacts.
567 \core_message\api::add_contact($user1->id, $user2->id);
568 \core_message\api::add_contact($user6->id, $user1->id);
570 // Create private conversations with some users.
571 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
572 array($user1->id, $user2->id));
573 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
574 array($user3->id, $user1->id));
576 // Create a group conversation with users.
577 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
578 array($user1->id, $user2->id, $user3->id, $user4->id),
581 // Check that we retrieved the correct conversations.
582 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user2->id));
583 $this->assertCount(2, \core_message\api::get_conversations_between_users($user2->id, $user1->id));
584 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user3->id));
585 $this->assertCount(2, \core_message\api::get_conversations_between_users($user3->id, $user1->id));
586 $this->assertCount(1, \core_message\api::get_conversations_between_users($user1->id, $user4->id));
587 $this->assertCount(1, \core_message\api::get_conversations_between_users($user4->id, $user1->id));
588 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user5->id));
589 $this->assertCount(0, \core_message\api::get_conversations_between_users($user5->id, $user1->id));
590 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user6->id));
591 $this->assertCount(0, \core_message\api::get_conversations_between_users($user6->id, $user1->id));
595 * Tests getting self-conversations.
597 public function test_get_self_conversation() {
598 // Create some users.
599 $user1 = new stdClass();
600 $user1->firstname = 'User';
601 $user1->lastname = 'One';
602 $user1 = self::getDataGenerator()->create_user($user1);
604 $user2 = new stdClass();
605 $user2->firstname = 'User';
606 $user2->lastname = 'Two';
607 $user2 = self::getDataGenerator()->create_user($user2);
609 $user3 = new stdClass();
610 $user3->firstname = 'User search';
611 $user3->lastname = 'Three';
612 $user3 = self::getDataGenerator()->create_user($user3);
614 // Add some users as contacts.
615 \core_message\api::add_contact($user1->id, $user2->id);
616 \core_message\api::add_contact($user3->id, $user1->id);
618 // Create private conversations with some users.
619 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
620 array($user1->id, $user2->id));
621 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
622 array($user3->id, $user1->id));
624 // Create a group conversation with users.
625 $gc = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
626 array($user1->id, $user2->id, $user3->id),
629 // Get self-conversations.
630 $rsc1 = \core_message\api::get_self_conversation($user1->id);
631 $rsc2 = \core_message\api::get_self_conversation($user2->id);
632 $rsc3 = \core_message\api::get_self_conversation($user3->id);
634 // Send message to self-conversation.
635 testhelper::send_fake_message_to_conversation($user1, $rsc1->id, 'Message to myself!');
637 // Check that we retrieved the correct conversations.
638 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc1->type);
639 $members = \core_message\api::get_conversation_members($user1->id, $rsc1->id);
640 $this->assertCount(1, $members);
641 $member = reset($members);
642 $this->assertEquals($user1->id, $member->id);
644 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc2->type);
645 $members = \core_message\api::get_conversation_members($user2->id, $rsc2->id);
646 $this->assertCount(1, $members);
647 $member = reset($members);
648 $this->assertEquals($user2->id, $member->id);
650 \core_message\api::delete_all_conversation_data($rsc3->id);
651 $selfconversation = \core_message\api::get_self_conversation($user3->id);
652 $members = \core_message\api::get_conversation_members($user1->id, $selfconversation->id);
653 $this->assertCount(1, $members);
657 * Tests searching messages.
659 public function test_search_messages() {
660 $this->resetAfterTest();
662 // Create some users.
663 $user1 = self::getDataGenerator()->create_user();
664 $user2 = self::getDataGenerator()->create_user();
665 $user3 = self::getDataGenerator()->create_user();
667 // The person doing the search.
668 $this->setUser($user1);
670 // Get self-conversation.
671 $sc = \core_message\api::get_self_conversation($user1->id);
673 // Create group conversation.
674 $gc = \core_message\api::create_conversation(
675 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
676 [$user1->id, $user2->id, $user3->id]
679 // Send some messages back and forth.
681 testhelper::send_fake_message_to_conversation($user1, $sc->id, 'Test message to self!', $time);
682 testhelper::send_fake_message_to_conversation($user1, $gc->id, 'My hero!', $time + 1);
683 $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time + 2);
684 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 3);
685 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 4);
686 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 5);
687 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 6);
689 $convid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
690 $conv2id = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
693 \core_message\api::block_user($user1->id, $user3->id);
696 $messages = \core_message\api::search_messages($user1->id, 'o');
698 // Confirm the data is correct.
699 $this->assertEquals(5, count($messages));
700 $message1 = $messages[0];
701 $message2 = $messages[1];
702 $message3 = $messages[2];
703 $message4 = $messages[3];
704 $message5 = $messages[4];
706 $this->assertEquals($user2->id, $message1->userid);
707 $this->assertEquals($user2->id, $message1->useridfrom);
708 $this->assertEquals(fullname($user2), $message1->fullname);
709 $this->assertTrue($message1->ismessaging);
710 $this->assertEquals('Word.', $message1->lastmessage);
711 $this->assertNotEmpty($message1->messageid);
712 $this->assertNull($message1->isonline);
713 $this->assertFalse($message1->isread);
714 $this->assertFalse($message1->isblocked);
715 $this->assertNull($message1->unreadcount);
716 $this->assertEquals($convid, $message1->conversationid);
718 $this->assertEquals($user2->id, $message2->userid);
719 $this->assertEquals($user1->id, $message2->useridfrom);
720 $this->assertEquals(fullname($user2), $message2->fullname);
721 $this->assertTrue($message2->ismessaging);
722 $this->assertEquals('Yo!', $message2->lastmessage);
723 $this->assertNotEmpty($message2->messageid);
724 $this->assertNull($message2->isonline);
725 $this->assertTrue($message2->isread);
726 $this->assertFalse($message2->isblocked);
727 $this->assertNull($message2->unreadcount);
728 $this->assertEquals($convid, $message2->conversationid);
730 $this->assertEquals($user3->id, $message3->userid);
731 $this->assertEquals($user3->id, $message3->useridfrom);
732 $this->assertEquals(fullname($user3), $message3->fullname);
733 $this->assertTrue($message3->ismessaging);
734 $this->assertEquals('Don\'t block me.', $message3->lastmessage);
735 $this->assertNotEmpty($message3->messageid);
736 $this->assertNull($message3->isonline);
737 $this->assertFalse($message3->isread);
738 $this->assertTrue($message3->isblocked);
739 $this->assertNull($message3->unreadcount);
740 $this->assertEquals($conv2id, $message3->conversationid);
742 // This is a group conversation. For now, search_messages returns only one of the other users on the conversation. It can't
743 // be guaranteed who will be returned in the first place, so we need to use the in_array to check all the possibilities.
744 $this->assertTrue(in_array($message4->userid, [$user2->id, $user3->id]));
745 $this->assertEquals($user1->id, $message4->useridfrom);
746 $this->assertTrue($message4->ismessaging);
747 $this->assertEquals('My hero!', $message4->lastmessage);
748 $this->assertNotEmpty($message4->messageid);
749 $this->assertNull($message4->isonline);
750 $this->assertTrue($message4->isread);
751 $this->assertNull($message4->unreadcount);
752 $this->assertEquals($gc->id, $message4->conversationid);
754 $this->assertEquals($user1->id, $message5->userid);
755 $this->assertEquals($user1->id, $message5->useridfrom);
756 $this->assertEquals(fullname($user1), $message5->fullname);
757 $this->assertTrue($message5->ismessaging);
758 $this->assertEquals('Test message to self!', $message5->lastmessage);
759 $this->assertNotEmpty($message5->messageid);
760 $this->assertFalse($message5->isonline);
761 $this->assertTrue($message5->isread);
762 $this->assertFalse($message5->isblocked);
763 $this->assertNull($message5->unreadcount);
764 $this->assertEquals($sc->id, $message5->conversationid);
768 * Test verifying that favourited conversations can be retrieved.
770 public function test_get_favourite_conversations() {
771 // Create some users.
772 $user1 = self::getDataGenerator()->create_user();
773 $user2 = self::getDataGenerator()->create_user();
774 $user3 = self::getDataGenerator()->create_user();
775 $user4 = self::getDataGenerator()->create_user();
777 // The person doing the search.
778 $this->setUser($user1);
780 // Only self-conversation created.
781 $this->assertCount(1, \core_message\api::get_conversations($user1->id));
783 // Create some conversations for user1.
785 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
786 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
787 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
788 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
790 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
791 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
792 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
793 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
795 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
796 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
797 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
799 // Favourite the first 2 conversations for user1.
801 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
802 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
803 $user1context = context_user::instance($user1->id);
804 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
805 foreach ($convoids as $convoid) {
806 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
809 // We should have 4 conversations.
810 // Consider first conversations is self-conversation.
811 $this->assertCount(4, \core_message\api::get_conversations($user1->id));
813 // And 3 favourited conversations (self-conversation included).
814 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
815 $this->assertCount(3, $conversations);
816 $conversations = \core_message\api::get_conversations(
820 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
823 $this->assertCount(1, $conversations);
827 * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
829 public function test_get_favourite_conversations_limit_offset() {
830 // Create some users.
831 $user1 = self::getDataGenerator()->create_user();
832 $user2 = self::getDataGenerator()->create_user();
833 $user3 = self::getDataGenerator()->create_user();
834 $user4 = self::getDataGenerator()->create_user();
836 // The person doing the search.
837 $this->setUser($user1);
839 // Only self-conversation created.
840 $this->assertCount(1, \core_message\api::get_conversations($user1->id));
842 // Create some conversations for user1.
844 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
845 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
846 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
847 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
849 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
850 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
851 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
852 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
854 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
855 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
856 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
858 // Favourite the all conversations for user1.
860 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
861 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
862 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
863 $user1context = context_user::instance($user1->id);
864 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
865 foreach ($convoids as $convoid) {
866 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
869 // Consider first conversations is self-conversation.
870 // Get all records, using offset 0 and large limit.
871 $this->assertCount(4, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
873 // Now, get 10 conversations starting at the second record. We should see 2 conversations.
874 $this->assertCount(3, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
876 // Now, try to get favourited conversations using an invalid offset.
877 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 5, 10, null, true));
881 * Tests retrieving favourite conversations when a conversation contains a deleted user.
883 public function test_get_favourite_conversations_with_deleted_user() {
884 // Create some users.
885 $user1 = self::getDataGenerator()->create_user();
886 $user2 = self::getDataGenerator()->create_user();
887 $user3 = self::getDataGenerator()->create_user();
889 // Send some messages back and forth, have some different conversations with different users.
891 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
892 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
893 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
894 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
896 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
897 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
898 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
899 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
901 // Favourite the all conversations for user1.
903 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
904 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
905 $user1context = context_user::instance($user1->id);
906 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
907 foreach ($convoids as $convoid) {
908 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
911 // Delete the second user.
914 // Retrieve the conversations.
915 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
917 // We should have both conversations, despite the other user being soft-deleted.
918 // Consider first conversations is self-conversation.
919 $this->assertCount(3, $conversations);
921 // Confirm the conversation is from the non-deleted user.
922 $conversation = reset($conversations);
923 $this->assertEquals($convoids[1], $conversation->id);
927 * Test confirming that conversations can be marked as favourites.
929 public function test_set_favourite_conversation() {
930 // Create some users.
931 $user1 = self::getDataGenerator()->create_user();
932 $user2 = self::getDataGenerator()->create_user();
933 $user3 = self::getDataGenerator()->create_user();
935 // Send some messages back and forth, have some different conversations with different users.
937 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
938 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
939 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
940 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
942 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
943 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
944 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
945 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
947 // Favourite the first conversation as user 1.
948 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
949 $favourite = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
951 // Verify we have two favourite conversations a user 1.
952 // Consider first conversations is self-conversation.
953 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
955 // Verify we have only one favourite as user2, despite being a member in that conversation.
956 // Consider first conversations is self-conversation.
957 $this->assertCount(1, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
959 // Try to favourite the same conversation again should just return the existing favourite.
960 $repeatresult = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
961 $this->assertEquals($favourite->id, $repeatresult->id);
965 * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
967 public function test_set_favourite_conversation_nonexistent_conversation() {
968 // Create some users.
969 $user1 = self::getDataGenerator()->create_user();
970 // Try to favourite a non-existent conversation.
971 $this->expectException(\moodle_exception::class);
972 \core_message\api::set_favourite_conversation(0, $user1->id);
976 * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
978 public function test_set_favourite_conversation_non_member() {
979 // Create some users.
980 $user1 = self::getDataGenerator()->create_user();
981 $user2 = self::getDataGenerator()->create_user();
982 $user3 = self::getDataGenerator()->create_user();
984 // Send some messages back and forth, have some different conversations with different users.
986 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
987 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
988 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
989 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
991 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
992 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
993 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
994 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
996 // Try to favourite the first conversation as user 3, who is not a member.
997 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
998 $this->expectException(\moodle_exception::class);
999 \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
1003 * Test confirming that those conversations marked as favourites can be unfavourited.
1005 public function test_unset_favourite_conversation() {
1006 // Create some users.
1007 $user1 = self::getDataGenerator()->create_user();
1008 $user2 = self::getDataGenerator()->create_user();
1009 $user3 = self::getDataGenerator()->create_user();
1011 // Send some messages back and forth, have some different conversations with different users.
1013 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1014 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1015 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1016 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1018 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
1019 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
1020 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
1021 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1023 // Favourite the first conversation as user 1 and the second as user 3.
1024 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1025 $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
1026 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
1027 \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
1029 // Verify we have two favourite conversations for both user 1 and user 3, counting self conversations.
1030 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1031 $this->assertCount(2, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1033 // Now unfavourite the conversation as user 1.
1034 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1036 // Verify we have two favourite conversations user 3 only, and one for user1, counting self conversations.
1037 $this->assertCount(2, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1038 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1040 // Try to favourite the same conversation again as user 1.
1041 $this->expectException(\moodle_exception::class);
1042 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1046 * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
1048 public function test_unset_favourite_conversation_not_favourite() {
1049 // Create some users.
1050 $user1 = self::getDataGenerator()->create_user();
1051 $user2 = self::getDataGenerator()->create_user();
1053 // Send some messages back and forth, have some different conversations with different users.
1055 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1056 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1057 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1058 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1060 // Now try to unfavourite the conversation as user 1.
1061 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1062 $this->expectException(\moodle_exception::class);
1063 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1067 * Test verifying that a non-existent conversation cannot be unset as a favourite.
1069 public function test_unset_favourite_conversation_non_existent_conversation() {
1070 // Create some users.
1071 $user1 = self::getDataGenerator()->create_user();
1073 // Now try to unfavourite the conversation as user 1.
1074 $this->expectException(\moodle_exception::class);
1075 \core_message\api::unset_favourite_conversation(0, $user1->id);
1079 * Helper to seed the database with initial state.
1081 protected function create_conversation_test_data() {
1082 // Create some users.
1083 $user1 = self::getDataGenerator()->create_user();
1084 $user2 = self::getDataGenerator()->create_user();
1085 $user3 = self::getDataGenerator()->create_user();
1086 $user4 = self::getDataGenerator()->create_user();
1090 // Create some conversations. We want:
1091 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
1092 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
1093 // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
1094 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
1095 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
1097 // Individual conversation, user1 is a member, last message from other user.
1098 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1099 [$user1->id, $user2->id]);
1100 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
1101 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
1103 // Individual conversation, user1 is a member, last message from user1.
1104 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1105 [$user1->id, $user3->id]);
1106 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
1107 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
1109 // Individual conversation, user1 is not a member.
1110 $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1111 [$user2->id, $user3->id]);
1112 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
1113 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
1115 // Group conversation, user1 is not a member.
1116 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1117 [$user2->id, $user3->id, $user4->id], 'Project discussions');
1118 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
1119 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
1121 // Group conversation, user1 is a member, last message from another user.
1122 $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1123 [$user1->id, $user3->id, $user4->id], 'Group chat');
1124 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
1125 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
1126 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
1128 // Group conversation, user1 is a member, last message from user1.
1129 $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1130 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
1131 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
1132 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
1133 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
1135 // Empty group conversations (x2), user1 is a member.
1136 $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1137 [$user1->id, $user2->id, $user3->id], 'Empty group');
1138 $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1139 [$user1->id, $user2->id, $user4->id], 'Another empty group');
1141 // Empty group conversation, user1 is NOT a member.
1142 $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1143 [$user2->id, $user3->id, $user4->id], 'Empty group 3');
1145 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
1149 * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
1151 public function test_get_conversations_no_restrictions() {
1154 $user1 = self::getDataGenerator()->create_user();
1155 // Self-conversation should exists.
1156 $this->assertCount(1, \core_message\api::get_conversations($user1->id));
1158 // Get a bunch of conversations, some group, some individual and in different states.
1159 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1160 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1162 // Get all conversations for user1.
1163 $conversations = core_message\api::get_conversations($user1->id);
1165 // Verify there are 2 individual conversation, 2 group conversations, 2 empty group conversations,
1166 // and a self-conversation.
1167 // The conversations with the most recent messages should be listed first, followed by the empty
1168 // conversations, with the most recently created first.
1169 $this->assertCount(7, $conversations);
1170 $typecounts = array_count_values(array_column($conversations, 'type'));
1171 $this->assertEquals(2, $typecounts[1]);
1172 $this->assertEquals(4, $typecounts[2]);
1173 $this->assertEquals(1, $typecounts[3]);
1175 // Those conversations having messages should be listed after self-conversation, ordered by most recent message time.
1176 $this->assertEquals($gc3->id, $conversations[0]->id);
1177 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
1178 $this->assertFalse($conversations[1]->isfavourite);
1179 $this->assertCount(1, $conversations[0]->members);
1180 $this->assertEquals(4, $conversations[0]->membercount);
1181 $this->assertCount(1, $conversations[0]->messages);
1182 $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]);
1183 $expectedmessagetext = message_format_message_text($message);
1184 $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text);
1185 $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
1187 $this->assertEquals($gc2->id, $conversations[1]->id);
1188 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
1189 $this->assertFalse($conversations[1]->isfavourite);
1190 $this->assertCount(1, $conversations[1]->members);
1191 $this->assertEquals(3, $conversations[1]->membercount);
1192 $this->assertCount(1, $conversations[1]->messages);
1193 $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]);
1194 $expectedmessagetext = message_format_message_text($message);
1195 $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text);
1196 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1198 $this->assertEquals($ic2->id, $conversations[2]->id);
1199 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
1200 $this->assertFalse($conversations[2]->isfavourite);
1201 $this->assertCount(1, $conversations[2]->members);
1202 $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
1203 $this->assertEquals(2, $conversations[2]->membercount);
1204 $this->assertCount(1, $conversations[2]->messages);
1205 $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]);
1206 $expectedmessagetext = message_format_message_text($message);
1207 $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text);
1208 $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
1210 $this->assertEquals($ic1->id, $conversations[3]->id);
1211 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
1212 $this->assertFalse($conversations[3]->isfavourite);
1213 $this->assertCount(1, $conversations[3]->members);
1214 $this->assertEquals(2, $conversations[3]->membercount);
1215 $this->assertCount(1, $conversations[3]->messages);
1216 $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]);
1217 $expectedmessagetext = message_format_message_text($message);
1218 $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text);
1219 $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
1221 // Of the groups without messages, we expect to see the most recently created first.
1222 $this->assertEquals($gc5->id, $conversations[4]->id);
1223 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
1224 $this->assertFalse($conversations[4]->isfavourite);
1225 $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
1226 $this->assertEquals(3, $conversations[4]->membercount);
1227 $this->assertEmpty($conversations[4]->messages);
1229 $this->assertEquals($gc4->id, $conversations[5]->id);
1230 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
1231 $this->assertFalse($conversations[5]->isfavourite);
1232 $this->assertCount(0, $conversations[5]->members);
1233 $this->assertEquals(3, $conversations[5]->membercount);
1234 $this->assertEmpty($conversations[5]->messages);
1236 // Verify format of the return structure.
1237 foreach ($conversations as $conv) {
1238 $this->assertObjectHasAttribute('id', $conv);
1239 $this->assertObjectHasAttribute('name', $conv);
1240 $this->assertObjectHasAttribute('subname', $conv);
1241 $this->assertObjectHasAttribute('imageurl', $conv);
1242 $this->assertObjectHasAttribute('type', $conv);
1243 $this->assertObjectHasAttribute('isfavourite', $conv);
1244 $this->assertObjectHasAttribute('membercount', $conv);
1245 $this->assertObjectHasAttribute('isread', $conv);
1246 $this->assertObjectHasAttribute('unreadcount', $conv);
1247 $this->assertObjectHasAttribute('members', $conv);
1248 foreach ($conv->members as $member) {
1249 $this->assertObjectHasAttribute('id', $member);
1250 $this->assertObjectHasAttribute('fullname', $member);
1251 $this->assertObjectHasAttribute('profileimageurl', $member);
1252 $this->assertObjectHasAttribute('profileimageurlsmall', $member);
1253 $this->assertObjectHasAttribute('isonline', $member);
1254 $this->assertObjectHasAttribute('showonlinestatus', $member);
1255 $this->assertObjectHasAttribute('isblocked', $member);
1256 $this->assertObjectHasAttribute('iscontact', $member);
1257 $this->assertObjectHasAttribute('isdeleted', $member);
1258 $this->assertObjectHasAttribute('canmessage', $member);
1259 $this->assertObjectHasAttribute('requirescontact', $member);
1260 $this->assertObjectHasAttribute('contactrequests', $member);
1262 $this->assertObjectHasAttribute('messages', $conv);
1263 foreach ($conv->messages as $message) {
1264 $this->assertObjectHasAttribute('id', $message);
1265 $this->assertObjectHasAttribute('useridfrom', $message);
1266 $this->assertObjectHasAttribute('text', $message);
1267 $this->assertObjectHasAttribute('timecreated', $message);
1273 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately.
1275 public function test_get_conversations_message_format() {
1277 // Create some users.
1278 $user1 = self::getDataGenerator()->create_user();
1279 $user2 = self::getDataGenerator()->create_user();
1281 // Create conversation.
1282 $conversation = \core_message\api::create_conversation(
1283 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1284 [$user1->id, $user2->id]
1287 // Send some messages back and forth.
1289 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1);
1290 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2);
1292 // Verify the format of the html message.
1293 $message = $DB->get_record('messages', ['id' => $mid]);
1294 $expectedmessagetext = message_format_message_text($message);
1295 $conversations = \core_message\api::get_conversations($user1->id);
1296 $messages = $conversations[0]->messages;
1297 $this->assertEquals($expectedmessagetext, $messages[0]->text);
1301 * Test verifying get_conversations identifies if a conversation is muted or not.
1303 public function test_get_conversations_some_muted() {
1304 // Create some users.
1305 $user1 = self::getDataGenerator()->create_user();
1306 $user2 = self::getDataGenerator()->create_user();
1307 $user3 = self::getDataGenerator()->create_user();
1309 $conversation1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1310 [$user1->id, $user2->id]);
1311 testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1');
1312 testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2');
1313 \core_message\api::mute_conversation($user1->id, $conversation1->id);
1315 $conversation2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1316 [$user1->id, $user3->id]);
1317 testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 1');
1318 testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2');
1320 $conversation3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1321 [$user1->id, $user2->id]);
1322 \core_message\api::mute_conversation($user1->id, $conversation3->id);
1324 $conversation4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1325 [$user1->id, $user3->id]);
1327 $conversations = \core_message\api::get_conversations($user1->id);
1329 usort($conversations, function($first, $second){
1330 return $first->id > $second->id;
1333 // Consider first conversations is self-conversation.
1334 $selfconversation = array_shift($conversations);
1335 $conv1 = array_shift($conversations);
1336 $conv2 = array_shift($conversations);
1337 $conv3 = array_shift($conversations);
1338 $conv4 = array_shift($conversations);
1340 $this->assertTrue($conv1->ismuted);
1341 $this->assertFalse($conv2->ismuted);
1342 $this->assertTrue($conv3->ismuted);
1343 $this->assertFalse($conv4->ismuted);
1347 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
1349 public function test_get_conversations_limit_offset() {
1350 // Get a bunch of conversations, some group, some individual and in different states.
1351 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1352 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1354 // Get all conversations for user1, limited to 1 result.
1355 $conversations = core_message\api::get_conversations($user1->id, 0, 1);
1357 // Verify the first conversation.
1358 $this->assertCount(1, $conversations);
1359 $conversation = array_shift($conversations);
1360 $this->assertEquals($conversation->id, $gc3->id);
1362 // Verify the next conversation.
1363 $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
1364 $this->assertCount(1, $conversations);
1365 $this->assertEquals($gc2->id, $conversations[0]->id);
1367 // Verify the next conversation.
1368 $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
1369 $this->assertCount(1, $conversations);
1370 $this->assertEquals($ic2->id, $conversations[0]->id);
1372 // Skip one and get both empty conversations.
1373 $conversations = \core_message\api::get_conversations($user1->id, 4, 2);
1374 $this->assertCount(2, $conversations);
1375 $this->assertEquals($gc5->id, $conversations[0]->id);
1376 $this->assertEmpty($conversations[0]->messages);
1377 $this->assertEquals($gc4->id, $conversations[1]->id);
1378 $this->assertEmpty($conversations[1]->messages);
1380 // Ask for an offset that doesn't exist and verify no conversations are returned.
1381 $conversations = \core_message\api::get_conversations($user1->id, 10, 1);
1382 $this->assertCount(0, $conversations);
1386 * Test verifying the type filtering behaviour of the
1388 public function test_get_conversations_type_filter() {
1389 // Get a bunch of conversations, some group, some individual and in different states.
1390 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1391 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1393 // Verify we can ask for only individual conversations.
1394 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1395 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1396 $this->assertCount(2, $conversations);
1398 // Verify we can ask for only group conversations.
1399 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1400 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP);
1401 $this->assertCount(4, $conversations);
1403 // Verify an exception is thrown if an unrecognized type is specified.
1404 $this->expectException(\moodle_exception::class);
1405 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 0);
1409 * Tests retrieving conversations when a 'self' conversation exists.
1411 public function test_get_conversations_self_conversations() {
1414 // Create a conversation between one user and themself.
1415 $user1 = self::getDataGenerator()->create_user();
1416 $user2 = self::getDataGenerator()->create_user();
1417 $user3 = self::getDataGenerator()->create_user();
1418 $user4 = self::getDataGenerator()->create_user();
1420 // Create some individual conversations.
1421 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1422 [$user1->id, $user2->id]);
1423 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1424 [$user1->id, $user3->id]);
1425 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message from user1 to user2');
1427 // Get some self-conversations.
1428 $sc1 = \core_message\api::get_self_conversation($user1->id);
1429 $sc4 = \core_message\api::get_self_conversation($user4->id);
1430 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Test message to self 1!');
1432 // Verify we are in a 'self' conversation state.
1433 $members = $DB->get_records('message_conversation_members', ['conversationid' => $sc1->id]);
1434 $this->assertCount(1, $members);
1435 $member = array_pop($members);
1436 $this->assertEquals($user1->id, $member->userid);
1438 // Verify the self-conversations are returned by the method.
1439 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF);
1440 $this->assertCount(1, $conversations);
1441 $conversation = array_pop($conversations);
1442 $this->assertEquals($conversation->id, $sc1->id);
1444 $conversations = \core_message\api::get_conversations($user4->id);
1445 // The self-conversation.
1446 $this->assertCount(1, $conversations);
1448 // Get only private conversations for user1 (empty conversations, like $ic2, are not returned).
1449 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1450 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1451 $this->assertCount(1, $conversations);
1453 // Merge self with private conversations for user1.
1454 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1455 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true);
1456 $this->assertCount(2, $conversations);
1458 // Get only private conversations for user2.
1459 $conversations = \core_message\api::get_conversations($user2->id, 0, 20,
1460 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1461 $this->assertCount(1, $conversations);
1463 // Merge self with private conversations for user2.
1464 $conversations = \core_message\api::get_conversations($user2->id, 0, 20,
1465 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true);
1466 $this->assertCount(2, $conversations);
1470 * Tests retrieving conversations when a conversation contains a deleted user.
1472 public function test_get_conversations_with_deleted_user() {
1473 // Get a bunch of conversations, some group, some individual and in different states.
1474 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1475 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1477 // Delete the second user and retrieve the conversations.
1478 // We should have 6 still, as conversations with soft-deleted users are still returned.
1479 // Group conversations are also present, albeit with less members.
1480 delete_user($user2);
1481 // This is to confirm an exception is not thrown when a user AND the user context is deleted.
1482 // We no longer delete the user context, but historically we did.
1483 context_helper::delete_instance(CONTEXT_USER, $user2->id);
1484 $conversations = \core_message\api::get_conversations($user1->id);
1485 // Consider there's a self-conversation (the last one).
1486 $this->assertCount(7, $conversations);
1487 $this->assertEquals($gc3->id, $conversations[0]->id);
1488 $this->assertcount(1, $conversations[0]->members);
1489 $this->assertEquals($gc2->id, $conversations[1]->id);
1490 $this->assertcount(1, $conversations[1]->members);
1491 $this->assertEquals($ic2->id, $conversations[2]->id);
1492 $this->assertEquals($ic1->id, $conversations[3]->id);
1493 $this->assertEquals($gc5->id, $conversations[4]->id);
1494 $this->assertEquals($gc4->id, $conversations[5]->id);
1496 // Delete a user from a group conversation where that user had sent the most recent message.
1497 // This user will still be present in the members array, as will the message in the messages array.
1498 delete_user($user4);
1499 $conversations = \core_message\api::get_conversations($user1->id);
1501 // Consider there's a self-conversation (the last one).
1502 $this->assertCount(7, $conversations);
1503 $this->assertEquals($gc2->id, $conversations[1]->id);
1504 $this->assertcount(1, $conversations[1]->members);
1505 $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
1506 $this->assertcount(1, $conversations[1]->messages);
1507 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1509 // Delete the third user and retrieve the conversations.
1510 // We should have 6 still, as conversations with soft-deleted users are still returned.
1511 // Group conversations are also present, albeit with less members.
1512 delete_user($user3);
1513 $conversations = \core_message\api::get_conversations($user1->id);
1514 // Consider there's a self-conversation (the last one).
1515 $this->assertCount(7, $conversations);
1516 $this->assertEquals($gc3->id, $conversations[0]->id);
1517 $this->assertcount(1, $conversations[0]->members);
1518 $this->assertEquals($gc2->id, $conversations[1]->id);
1519 $this->assertcount(1, $conversations[1]->members);
1520 $this->assertEquals($ic2->id, $conversations[2]->id);
1521 $this->assertEquals($ic1->id, $conversations[3]->id);
1522 $this->assertEquals($gc5->id, $conversations[4]->id);
1523 $this->assertEquals($gc4->id, $conversations[5]->id);
1527 * Test confirming the behaviour of get_conversations() when users delete all messages.
1529 public function test_get_conversations_deleted_messages() {
1530 // Get a bunch of conversations, some group, some individual and in different states.
1531 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1532 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1534 $conversations = \core_message\api::get_conversations($user1->id);
1535 // Consider first conversations is self-conversation.
1536 $this->assertCount(7, $conversations);
1538 // Delete all messages from a group conversation the user is in - it should be returned.
1539 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $gc2->id));
1540 $convmessages = \core_message\api::get_conversation_messages($user1->id, $gc2->id);
1541 $messages = $convmessages['messages'];
1542 foreach ($messages as $message) {
1543 \core_message\api::delete_message($user1->id, $message->id);
1545 $conversations = \core_message\api::get_conversations($user1->id);
1546 // Consider first conversations is self-conversation.
1547 $this->assertCount(7, $conversations);
1548 $this->assertContains($gc2->id, array_column($conversations, 'id'));
1550 // Delete all messages from an individual conversation the user is in - it should not be returned.
1551 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $ic1->id));
1552 $convmessages = \core_message\api::get_conversation_messages($user1->id, $ic1->id);
1553 $messages = $convmessages['messages'];
1554 foreach ($messages as $message) {
1555 \core_message\api::delete_message($user1->id, $message->id);
1557 $conversations = \core_message\api::get_conversations($user1->id);
1558 // Consider first conversations is self-conversation.
1559 $this->assertCount(6, $conversations);
1560 $this->assertNotContains($ic1->id, array_column($conversations, 'id'));
1564 * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single
1567 public function test_get_conversations_favourite_conversations_single() {
1568 // Get a bunch of conversations, some group, some individual and in different states.
1569 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1570 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1572 // Mark a single conversation as favourites.
1573 \core_message\api::set_favourite_conversation($ic2->id, $user1->id);
1575 // Get the conversation, first with no restrictions, confirming the favourite status of the conversations.
1576 $conversations = \core_message\api::get_conversations($user1->id);
1577 // Consider there is a self-conversation.
1578 $selfconversation = \core_message\api::get_self_conversation($user1->id);
1579 $this->assertCount(7, $conversations);
1580 foreach ($conversations as $conv) {
1581 if (in_array($conv->id, [$ic2->id, $selfconversation->id])) {
1582 $this->assertTrue($conv->isfavourite);
1584 $this->assertFalse($conv->isfavourite);
1588 // Now, get ONLY favourite conversations (including self-conversation).
1589 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1590 $this->assertCount(2, $conversations);
1591 foreach ($conversations as $conv) {
1592 if ($conv->type != \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) {
1593 $this->assertTrue($conv->isfavourite);
1594 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conv->type);
1595 $this->assertEquals($ic2->id, $conv->id);
1599 // Now, try ONLY favourites of type 'group'.
1600 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1601 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1602 $this->assertEmpty($conversations);
1604 // And NO favourite conversations.
1605 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1606 $this->assertCount(5, $conversations);
1607 foreach ($conversations as $conv) {
1608 $this->assertFalse($conv->isfavourite);
1609 $this->assertNotEquals($ic2, $conv->id);
1614 * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
1616 public function test_get_conversations_favourite_conversations() {
1617 // Get a bunch of conversations, some group, some individual and in different states.
1618 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1619 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1621 // Try to get ONLY favourite conversations, when only self-conversation exist.
1622 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1624 // Unstar self-conversation.
1625 $selfconversation = \core_message\api::get_self_conversation($user1->id);
1626 \core_message\api::unset_favourite_conversation($selfconversation->id, $user1->id);
1628 // Try to get ONLY favourite conversations, when no favourites exist.
1629 $this->assertEquals([], \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1631 // Try to get NO favourite conversations, when no favourites exist.
1632 $this->assertCount(7, \core_message\api::get_conversations($user1->id, 0, 20, null, false));
1634 // Mark a few conversations as favourites.
1635 \core_message\api::set_favourite_conversation($ic1->id, $user1->id);
1636 \core_message\api::set_favourite_conversation($gc2->id, $user1->id);
1637 \core_message\api::set_favourite_conversation($gc5->id, $user1->id);
1638 $favouriteids = [$ic1->id, $gc2->id, $gc5->id];
1640 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
1641 $conversations = \core_message\api::get_conversations($user1->id);
1642 $this->assertCount(7, $conversations);
1643 foreach ($conversations as $conv) {
1644 if (in_array($conv->id, $favouriteids)) {
1645 $this->assertTrue($conv->isfavourite);
1647 $this->assertFalse($conv->isfavourite);
1651 // Now, get ONLY favourite conversations.
1652 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1653 $this->assertCount(3, $conversations);
1654 foreach ($conversations as $conv) {
1655 $this->assertTrue($conv->isfavourite);
1656 $this->assertNotFalse(array_search($conv->id, $favouriteids));
1659 // Now, try ONLY favourites of type 'group'.
1660 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1661 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1662 $this->assertCount(2, $conversations);
1663 foreach ($conversations as $conv) {
1664 $this->assertTrue($conv->isfavourite);
1665 $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id]));
1668 // And NO favourite conversations.
1669 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1670 $this->assertCount(4, $conversations);
1671 foreach ($conversations as $conv) {
1672 $this->assertFalse($conv->isfavourite);
1673 $this->assertFalse(array_search($conv->id, $favouriteids));
1678 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this
1679 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want
1680 * to confirm this happens.
1682 public function test_get_conversations_user_in_group_and_individual_chat() {
1683 $this->resetAfterTest();
1685 $user1 = self::getDataGenerator()->create_user();
1686 $user2 = self::getDataGenerator()->create_user();
1687 $user3 = self::getDataGenerator()->create_user();
1689 $conversation = \core_message\api::create_conversation(
1690 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1695 'Individual conversation'
1698 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1700 $conversation = \core_message\api::create_conversation(
1701 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1706 'Group conversation'
1709 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1711 \core_message\api::create_contact_request($user1->id, $user2->id);
1712 \core_message\api::create_contact_request($user1->id, $user3->id);
1714 $conversations = \core_message\api::get_conversations($user2->id);
1716 $groupconversation = array_shift($conversations);
1717 $individualconversation = array_shift($conversations);
1719 $this->assertEquals('Group conversation', $groupconversation->name);
1720 $this->assertEquals('Individual conversation', $individualconversation->name);
1722 $this->assertCount(1, $groupconversation->members);
1723 $this->assertCount(1, $individualconversation->members);
1725 $groupmember = reset($groupconversation->members);
1726 $this->assertNull($groupmember->requirescontact);
1727 $this->assertNull($groupmember->canmessage);
1728 $this->assertEmpty($groupmember->contactrequests);
1730 $individualmember = reset($individualconversation->members);
1731 $this->assertNotNull($individualmember->requirescontact);
1732 $this->assertNotNull($individualmember->canmessage);
1733 $this->assertNotEmpty($individualmember->contactrequests);
1737 * Test verifying that group linked conversations are returned and contain a subname matching the course name.
1739 public function test_get_conversations_group_linked() {
1742 // Create some users.
1743 $user1 = self::getDataGenerator()->create_user();
1744 $user2 = self::getDataGenerator()->create_user();
1745 $user3 = self::getDataGenerator()->create_user();
1747 $course1 = $this->getDataGenerator()->create_course();
1749 // Create a group with a linked conversation and a valid image.
1750 $this->setAdminUser();
1751 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1752 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1753 $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1754 $group1 = $this->getDataGenerator()->create_group([
1755 'courseid' => $course1->id,
1756 'enablemessaging' => 1,
1757 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
1760 // Add users to group1.
1761 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1762 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
1764 // Verify the group with the image works as expected.
1765 $conversations = \core_message\api::get_conversations($user1->id);
1766 $this->assertEquals(2, $conversations[0]->membercount);
1767 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1768 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true);
1769 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1771 // Create a group with a linked conversation and without any image.
1772 $group2 = $this->getDataGenerator()->create_group([
1773 'courseid' => $course1->id,
1774 'enablemessaging' => 1,
1777 // Add users to group2.
1778 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1779 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
1781 // Verify the group without any image works as expected too.
1782 $conversations = \core_message\api::get_conversations($user3->id);
1783 // Consider first conversations is self-conversation.
1784 $this->assertEquals(2, $conversations[0]->membercount);
1785 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1786 $this->assertEquals('https://www.example.com/moodle/theme/image.php/_s/boost/core/1/g/g1', $conversations[0]->imageurl);
1788 // Now, disable the conversation linked to the group and verify it's no longer returned.
1789 $DB->set_field('message_conversations', 'enabled', 0, ['id' => $conversations[0]->id]);
1790 $conversations = \core_message\api::get_conversations($user3->id);
1791 $this->assertCount(1, $conversations);
1795 * The data provider for get_conversations_mixed.
1797 * This provides sets of data to for testing.
1800 public function get_conversations_mixed_provider() {
1802 'Test that conversations with messages contacts is correctly ordered.' => array(
1808 'contacts' => array(
1810 'messages' => array(
1814 'state' => 'unread',
1820 'state' => 'unread',
1826 'state' => 'unread',
1834 'timemodifier' => 1,
1841 'timemodifier' => 1,
1852 'expectations' => array(
1854 // User1 has conversed most recently with user3. The most recent message is M5.
1856 'messageposition' => 0,
1858 'subject' => '<p>S5</p>',
1861 // User1 has also conversed with user2. The most recent message is S2.
1863 'messageposition' => 1,
1865 'subject' => '<p>S2</p>',
1870 // User2 has only conversed with user1. Their most recent shared message was S2.
1872 'messageposition' => 0,
1874 'subject' => '<p>S2</p>',
1879 // User3 has only conversed with user1. Their most recent shared message was S5.
1881 'messageposition' => 0,
1883 'subject' => '<p>S5</p>',
1889 'Test conversations with a single user, where some messages are read and some are not.' => array(
1894 'contacts' => array(
1896 'messages' => array(
1912 'state' => 'unread',
1913 'timemodifier' => 1,
1919 'state' => 'unread',
1920 'timemodifier' => 1,
1924 'expectations' => array(
1925 // The most recent message between user1 and user2 was S4.
1928 'messageposition' => 0,
1930 'subject' => '<p>S4</p>',
1935 // The most recent message between user1 and user2 was S4.
1937 'messageposition' => 0,
1939 'subject' => '<p>S4</p>',
1945 'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1946 'are out of order' => array(
1947 // This can happen through a combination of factors including multi-master DB replication with messages
1948 // read somehow (e.g. API).
1953 'contacts' => array(
1955 'messages' => array(
1961 'timemodifier' => 1,
1968 'timemodifier' => 2,
1973 'state' => 'unread',
1979 'state' => 'unread',
1983 'expectations' => array(
1984 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1987 'messageposition' => 0,
1989 'subject' => '<p>S2</p>',
1995 'messageposition' => 0,
1997 'subject' => '<p>S2</p>',
2003 'Test unread message count is correct for both users' => array(
2008 'contacts' => array(
2010 'messages' => array(
2016 'timemodifier' => 1,
2023 'timemodifier' => 2,
2030 'timemodifier' => 3,
2037 'timemodifier' => 4,
2042 'state' => 'unread',
2044 'timemodifier' => 5,
2049 'state' => 'unread',
2051 'timemodifier' => 6,
2056 'state' => 'unread',
2058 'timemodifier' => 7,
2063 'state' => 'unread',
2065 'timemodifier' => 8,
2068 'expectations' => array(
2069 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
2072 'messageposition' => 0,
2074 'subject' => '<p>S8</p>',
2080 'messageposition' => 0,
2082 'subject' => '<p>S8</p>',
2092 * Test that creation can't create the same conversation twice for 1:1 conversations.
2094 public function test_create_conversation_duplicate_conversations() {
2096 $user1 = $this::getDataGenerator()->create_user();
2098 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]);
2099 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]);
2101 $convhash = \core_message\helper::get_conversation_hash([$user1->id]);
2102 $countconversations = $DB->count_records('message_conversations', ['convhash' => $convhash]);
2103 $this->assertEquals(1, $countconversations);
2104 $this->assertNotEmpty($conversation = \core_message\api::get_self_conversation($user1->id));
2108 * Test get_conversations with a mixture of messages.
2110 * @dataProvider get_conversations_mixed_provider
2111 * @param array $usersdata The list of users to create for this test.
2112 * @param array $messagesdata The list of messages to create.
2113 * @param array $expectations The list of expected outcomes.
2115 public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
2118 // Create all of the users.
2120 foreach ($usersdata as $username) {
2121 $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
2124 foreach ($contacts as $username => $contact) {
2125 foreach ($contact as $contactname => $blocked) {
2126 $record = new stdClass();
2127 $record->userid = $users[$username]->id;
2128 $record->contactid = $users[$contactname]->id;
2129 $record->blocked = $blocked;
2130 $record->id = $DB->insert_record('message_contacts', $record);
2134 $defaulttimecreated = time();
2135 foreach ($messagesdata as $messagedata) {
2136 $from = $users[$messagedata['from']];
2137 $to = $users[$messagedata['to']];
2138 $subject = $messagedata['subject'];
2140 if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
2141 $messageid = $this->send_fake_message($from, $to, $subject);
2143 // If there is no state, or the state is not 'unread', assume the message is read.
2144 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
2147 $updatemessage = new stdClass();
2148 $updatemessage->id = $messageid;
2149 if (isset($messagedata['timecreated'])) {
2150 $updatemessage->timecreated = $messagedata['timecreated'];
2151 } else if (isset($messagedata['timemodifier'])) {
2152 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
2154 $updatemessage->timecreated = $defaulttimecreated;
2157 $DB->update_record('messages', $updatemessage);
2160 foreach ($expectations as $username => $data) {
2161 // Get the recent conversations for the specified user.
2162 $user = $users[$username];
2163 $conversations = array_values(\core_message\api::get_conversations($user->id));
2164 foreach ($data as $expectation) {
2165 $otheruser = $users[$expectation['with']];
2166 $conversation = $conversations[$expectation['messageposition']];
2167 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
2168 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
2169 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
2175 * Tests retrieving user contacts.
2177 public function test_get_user_contacts() {
2178 // Create some users.
2179 $user1 = self::getDataGenerator()->create_user();
2182 $this->setUser($user1);
2184 $user2 = new stdClass();
2185 $user2->firstname = 'User';
2186 $user2->lastname = 'A';
2187 $user2 = self::getDataGenerator()->create_user($user2);
2189 $user3 = new stdClass();
2190 $user3->firstname = 'User';
2191 $user3->lastname = 'B';
2192 $user3 = self::getDataGenerator()->create_user($user3);
2194 $user4 = new stdClass();
2195 $user4->firstname = 'User';
2196 $user4->lastname = 'C';
2197 $user4 = self::getDataGenerator()->create_user($user4);
2199 $user5 = new stdClass();
2200 $user5->firstname = 'User';
2201 $user5->lastname = 'D';
2202 $user5 = self::getDataGenerator()->create_user($user5);
2204 // Add some users as contacts.
2205 \core_message\api::add_contact($user1->id, $user2->id);
2206 \core_message\api::add_contact($user1->id, $user3->id);
2207 \core_message\api::add_contact($user1->id, $user4->id);
2209 // Retrieve the contacts.
2210 $contacts = \core_message\api::get_user_contacts($user1->id);
2212 // Confirm the data is correct.
2213 $this->assertEquals(3, count($contacts));
2217 $contact1 = array_shift($contacts);
2218 $contact2 = array_shift($contacts);
2219 $contact3 = array_shift($contacts);
2221 $this->assertEquals($user2->id, $contact1->id);
2222 $this->assertEquals(fullname($user2), $contact1->fullname);
2223 $this->assertTrue($contact1->iscontact);
2225 $this->assertEquals($user3->id, $contact2->id);
2226 $this->assertEquals(fullname($user3), $contact2->fullname);
2227 $this->assertTrue($contact2->iscontact);
2229 $this->assertEquals($user4->id, $contact3->id);
2230 $this->assertEquals(fullname($user4), $contact3->fullname);
2231 $this->assertTrue($contact3->iscontact);
2235 * Tests retrieving conversation messages.
2237 public function test_get_conversation_messages() {
2238 // Create some users.
2239 $user1 = self::getDataGenerator()->create_user();
2240 $user2 = self::getDataGenerator()->create_user();
2242 // Create conversation.
2243 $conversation = \core_message\api::create_conversation(
2244 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2245 [$user1->id, $user2->id]
2248 // The person doing the search.
2249 $this->setUser($user1);
2251 // Send some messages back and forth.
2253 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2254 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2255 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2256 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2258 // Retrieve the messages.
2259 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2261 // Confirm the conversation id is correct.
2262 $this->assertEquals($conversation->id, $convmessages['id']);
2264 // Confirm the message data is correct.
2265 $messages = $convmessages['messages'];
2266 $this->assertEquals(4, count($messages));
2267 $message1 = $messages[0];
2268 $message2 = $messages[1];
2269 $message3 = $messages[2];
2270 $message4 = $messages[3];
2272 $this->assertEquals($user1->id, $message1->useridfrom);
2273 $this->assertStringContainsString('Yo!', $message1->text);
2275 $this->assertEquals($user2->id, $message2->useridfrom);
2276 $this->assertStringContainsString('Sup mang?', $message2->text);
2278 $this->assertEquals($user1->id, $message3->useridfrom);
2279 $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text);
2281 $this->assertEquals($user1->id, $message4->useridfrom);
2282 $this->assertStringContainsString('Word.', $message4->text);
2284 // Confirm the members data is correct.
2285 $members = $convmessages['members'];
2286 $this->assertEquals(2, count($members));
2290 * Tests retrieving group conversation messages.
2292 public function test_get_group_conversation_messages() {
2293 // Create some users.
2294 $user1 = self::getDataGenerator()->create_user();
2295 $user2 = self::getDataGenerator()->create_user();
2296 $user3 = self::getDataGenerator()->create_user();
2297 $user4 = self::getDataGenerator()->create_user();
2299 // Create group conversation.
2300 $conversation = \core_message\api::create_conversation(
2301 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2302 [$user1->id, $user2->id, $user3->id, $user4->id]
2305 // The person doing the search.
2306 $this->setUser($user1);
2308 // Send some messages back and forth.
2310 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2311 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2312 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2313 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2314 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
2316 // Retrieve the messages.
2317 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2319 // Confirm the conversation id is correct.
2320 $this->assertEquals($conversation->id, $convmessages['id']);
2322 // Confirm the message data is correct.
2323 $messages = $convmessages['messages'];
2324 $this->assertEquals(5, count($messages));
2326 $message1 = $messages[0];
2327 $message2 = $messages[1];
2328 $message3 = $messages[2];
2329 $message4 = $messages[3];
2330 $message5 = $messages[4];
2332 $this->assertEquals($user1->id, $message1->useridfrom);
2333 $this->assertStringContainsString('Yo!', $message1->text);
2335 $this->assertEquals($user2->id, $message2->useridfrom);
2336 $this->assertStringContainsString('Sup mang?', $message2->text);
2338 $this->assertEquals($user3->id, $message3->useridfrom);
2339 $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text);
2341 $this->assertEquals($user1->id, $message4->useridfrom);
2342 $this->assertStringContainsString('Word.', $message4->text);
2344 $this->assertEquals($user2->id, $message5->useridfrom);
2345 $this->assertStringContainsString('Yeah!', $message5->text);
2347 // Confirm the members data is correct.
2348 $members = $convmessages['members'];
2349 $this->assertEquals(3, count($members));
2353 * Test verifying the sorting param for get_conversation_messages is respected().
2355 public function test_get_conversation_messages_sorting() {
2356 // Create some users.
2357 $user1 = self::getDataGenerator()->create_user();
2358 $user2 = self::getDataGenerator()->create_user();
2359 $user3 = self::getDataGenerator()->create_user();
2361 // Create conversations - 1 group and 1 individual.
2362 $conversation = \core_message\api::create_conversation(
2363 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2364 [$user1->id, $user2->id]
2366 $conversation2 = \core_message\api::create_conversation(
2367 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2368 [$user1->id, $user2->id, $user3->id]
2371 // Send some messages back and forth.
2373 $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2374 $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2375 $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2376 $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2378 $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
2379 $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
2380 $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
2381 $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
2383 // The person doing the search.
2384 $this->setUser($user1);
2386 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2387 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2388 $messages = $convmessages['messages'];
2389 $this->assertEquals($m1id, $messages[0]->id);
2390 $this->assertEquals($m2id, $messages[1]->id);
2391 $this->assertEquals($m3id, $messages[2]->id);
2392 $this->assertEquals($m4id, $messages[3]->id);
2394 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2395 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
2396 $messages = $convmessages['messages'];
2397 $this->assertEquals($m1id, $messages[3]->id);
2398 $this->assertEquals($m2id, $messages[2]->id);
2399 $this->assertEquals($m3id, $messages[1]->id);
2400 $this->assertEquals($m4id, $messages[0]->id);
2402 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2403 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
2404 $messages = $convmessages['messages'];
2405 $this->assertEquals($gm1id, $messages[0]->id);
2406 $this->assertEquals($gm2id, $messages[1]->id);
2407 $this->assertEquals($gm3id, $messages[2]->id);
2408 $this->assertEquals($gm4id, $messages[3]->id);
2410 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2411 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
2412 $messages = $convmessages['messages'];
2413 $this->assertEquals($gm1id, $messages[3]->id);
2414 $this->assertEquals($gm2id, $messages[2]->id);
2415 $this->assertEquals($gm3id, $messages[1]->id);
2416 $this->assertEquals($gm4id, $messages[0]->id);
2420 * Test retrieving conversation messages by providing a minimum timecreated value.
2422 public function test_get_conversation_messages_time_from_only() {
2423 // Create some users.
2424 $user1 = self::getDataGenerator()->create_user();
2425 $user2 = self::getDataGenerator()->create_user();
2426 $user3 = self::getDataGenerator()->create_user();
2427 $user4 = self::getDataGenerator()->create_user();
2429 // Create group conversation.
2430 $conversation = \core_message\api::create_conversation(
2431 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2432 [$user1->id, $user2->id, $user3->id, $user4->id]
2435 // The person doing the search.
2436 $this->setUser($user1);
2438 // Send some messages back and forth.
2440 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2441 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2442 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2443 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2445 // Retrieve the messages from $time, which should be all of them.
2446 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
2448 // Confirm the conversation id is correct.
2449 $this->assertEquals($conversation->id, $convmessages['id']);
2451 // Confirm the message data is correct.
2452 $messages = $convmessages['messages'];
2453 $this->assertEquals(4, count($messages));
2455 $message1 = $messages[0];
2456 $message2 = $messages[1];
2457 $message3 = $messages[2];
2458 $message4 = $messages[3];
2460 $this->assertStringContainsString('Message 1', $message1->text);
2461 $this->assertStringContainsString('Message 2', $message2->text);
2462 $this->assertStringContainsString('Message 3', $message3->text);
2463 $this->assertStringContainsString('Message 4', $message4->text);
2465 // Confirm the members data is correct.
2466 $members = $convmessages['members'];
2467 $this->assertEquals(3, count($members));
2469 // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2470 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2471 'timecreated ASC', $time + 3);
2473 // Confirm the conversation id is correct.
2474 $this->assertEquals($conversation->id, $convmessages['id']);
2476 // Confirm the message data is correct.
2477 $messages = $convmessages['messages'];
2478 $this->assertEquals(2, count($messages));
2480 $message1 = $messages[0];
2481 $message2 = $messages[1];
2483 $this->assertStringContainsString('Message 3', $message1->text);
2484 $this->assertStringContainsString('Message 4', $message2->text);
2486 // Confirm the members data is correct.
2487 $members = $convmessages['members'];
2488 $this->assertEquals(2, count($members));
2492 * Test retrieving conversation messages by providing a maximum timecreated value.
2494 public function test_get_conversation_messages_time_to_only() {
2495 // Create some users.
2496 $user1 = self::getDataGenerator()->create_user();
2497 $user2 = self::getDataGenerator()->create_user();
2498 $user3 = self::getDataGenerator()->create_user();
2499 $user4 = self::getDataGenerator()->create_user();
2501 // Create group conversation.
2502 $conversation = \core_message\api::create_conversation(
2503 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2504 [$user1->id, $user2->id, $user3->id, $user4->id]
2507 // The person doing the search.
2508 $this->setUser($user1);
2510 // Send some messages back and forth.
2512 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2513 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2514 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2515 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2517 // Retrieve the messages up until $time + 4, which should be all of them.
2518 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2521 // Confirm the conversation id is correct.
2522 $this->assertEquals($conversation->id, $convmessages['id']);
2524 // Confirm the message data is correct.
2525 $messages = $convmessages['messages'];
2526 $this->assertEquals(4, count($messages));
2528 $message1 = $messages[0];
2529 $message2 = $messages[1];
2530 $message3 = $messages[2];
2531 $message4 = $messages[3];
2533 $this->assertStringContainsString('Message 1', $message1->text);
2534 $this->assertStringContainsString('Message 2', $message2->text);
2535 $this->assertStringContainsString('Message 3', $message3->text);
2536 $this->assertStringContainsString('Message 4', $message4->text);
2538 // Confirm the members data is correct.
2539 $members = $convmessages['members'];
2540 $this->assertEquals(3, count($members));
2542 // Retrieve the messages up until $time + 2, which should be the first two.
2543 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2546 // Confirm the conversation id is correct.
2547 $this->assertEquals($conversation->id, $convmessages['id']);
2549 // Confirm the message data is correct.
2550 $messages = $convmessages['messages'];
2551 $this->assertEquals(2, count($messages));
2553 $message1 = $messages[0];
2554 $message2 = $messages[1];
2556 $this->assertStringContainsString('Message 1', $message1->text);
2557 $this->assertStringContainsString('Message 2', $message2->text);
2559 // Confirm the members data is correct.
2560 $members = $convmessages['members'];
2561 $this->assertEquals(2, count($members));
2565 * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
2567 public function test_get_conversation_messages_time_from_and_to() {
2568 // Create some users.
2569 $user1 = self::getDataGenerator()->create_user();
2570 $user2 = self::getDataGenerator()->create_user();
2571 $user3 = self::getDataGenerator()->create_user();
2572 $user4 = self::getDataGenerator()->create_user();
2574 // Create group conversation.
2575 $conversation = \core_message\api::create_conversation(
2576 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2577 [$user1->id, $user2->id, $user3->id, $user4->id]
2580 // The person doing the search.
2581 $this->setUser($user1);
2583 // Send some messages back and forth.
2585 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2586 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2587 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2588 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2590 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2591 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2592 'timecreated ASC', $time + 2, $time + 3);
2594 // Confirm the conversation id is correct.
2595 $this->assertEquals($conversation->id, $convmessages['id']);
2597 // Confirm the message data is correct.
2598 $messages = $convmessages['messages'];
2599 $this->assertEquals(2, count($messages));
2601 $message1 = $messages[0];
2602 $message2 = $messages[1];
2604 $this->assertStringContainsString('Message 2', $message1->text);
2605 $this->assertStringContainsString('Message 3', $message2->text);
2607 // Confirm the members data is correct.
2608 $members = $convmessages['members'];
2609 $this->assertEquals(2, count($members));
2614 * Test retrieving conversation messages by providing a limitfrom value.
2616 public function test_get_conversation_messages_limitfrom_only() {
2617 // Create some users.
2618 $user1 = self::getDataGenerator()->create_user();
2619 $user2 = self::getDataGenerator()->create_user();
2620 $user3 = self::getDataGenerator()->create_user();
2621 $user4 = self::getDataGenerator()->create_user();
2623 // Create group conversation.
2624 $conversation = \core_message\api::create_conversation(
2625 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2626 [$user1->id, $user2->id, $user3->id, $user4->id]
2629 // The person doing the search.
2630 $this->setUser($user1);
2632 // Send some messages back and forth.
2634 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2635 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2636 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2637 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2639 // Retrieve the messages from $time, which should be all of them.
2640 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
2642 // Confirm the conversation id is correct.
2643 $messages = $convmessages['messages'];
2644 $this->assertEquals($conversation->id, $convmessages['id']);
2646 // Confirm the message data is correct.
2647 $this->assertEquals(2, count($messages));
2649 $message1 = $messages[0];
2650 $message2 = $messages[1];
2652 $this->assertStringContainsString('Message 3', $message1->text);
2653 $this->assertStringContainsString('Message 4', $message2->text);
2655 // Confirm the members data is correct.
2656 $members = $convmessages['members'];
2657 $this->assertEquals(2, count($members));
2661 * Test retrieving conversation messages by providing a limitnum value.
2663 public function test_get_conversation_messages_limitnum() {
2664 // Create some users.
2665 $user1 = self::getDataGenerator()->create_user();
2666 $user2 = self::getDataGenerator()->create_user();
2667 $user3 = self::getDataGenerator()->create_user();
2668 $user4 = self::getDataGenerator()->create_user();
2670 // Create group conversation.
2671 $conversation = \core_message\api::create_conversation(
2672 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2673 [$user1->id, $user2->id, $user3->id, $user4->id]
2676 // The person doing the search.
2677 $this->setUser($user1);
2679 // Send some messages back and forth.
2681 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2682 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2683 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2684 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2686 // Retrieve the messages from $time, which should be all of them.
2687 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
2689 // Confirm the conversation id is correct.
2690 $messages = $convmessages['messages'];
2691 $this->assertEquals($conversation->id, $convmessages['id']);
2693 // Confirm the message data is correct.
2694 $messages = $convmessages['messages'];
2695 $this->assertEquals(1, count($messages));
2697 $message1 = $messages[0];
2699 $this->assertStringContainsString('Message 3', $message1->text);
2701 // Confirm the members data is correct.
2702 $members = $convmessages['members'];
2703 $this->assertEquals(1, count($members));
2707 * Tests retrieving most recent conversation message.
2709 public function test_get_most_recent_conversation_message() {
2710 // Create some users.
2711 $user1 = self::getDataGenerator()->create_user();
2712 $user2 = self::getDataGenerator()->create_user();
2713 $user3 = self::getDataGenerator()->create_user();
2715 // Create group conversation.
2716 $conversation = \core_message\api::create_conversation(
2717 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2718 [$user1->id, $user2->id, $user3->id]
2721 // The person getting the most recent conversation message.
2722 $this->setUser($user1);
2724 // Send some messages back and forth.
2726 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2727 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2728 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2729 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2731 // Retrieve the most recent messages.
2732 $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
2734 // Check the results are correct.
2735 $this->assertEquals($user2->id, $message->useridfrom);
2736 $this->assertStringContainsString('Word.', $message->text);
2740 * Tests checking if a user can mark all messages as read.
2742 public function test_can_mark_all_messages_as_read() {
2743 // Set as the admin.
2744 $this->setAdminUser();
2746 // Create some users.
2747 $user1 = self::getDataGenerator()->create_user();
2748 $user2 = self::getDataGenerator()->create_user();
2749 $user3 = self::getDataGenerator()->create_user();
2751 // Send some messages back and forth.
2753 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2754 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2755 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2756 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2758 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2760 // The admin can do anything.
2761 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2763 // Set as the user 1.
2764 $this->setUser($user1);
2766 // The user can mark the messages as he is in the conversation.
2767 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2769 // User 1 can not mark the messages read for user 2.
2770 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
2772 // This user is not a part of the conversation.
2773 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
2777 * Tests checking if a user can delete a conversation.
2779 public function test_can_delete_conversation() {
2780 // Set as the admin.
2781 $this->setAdminUser();
2783 // Create some users.
2784 $user1 = self::getDataGenerator()->create_user();
2785 $user2 = self::getDataGenerator()->create_user();
2787 // Send some messages back and forth.
2789 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2790 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2791 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2792 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2794 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2796 // The admin can do anything.
2797 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2799 // Set as the user 1.
2800 $this->setUser($user1);
2802 // They can delete their own messages.
2803 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2805 // They can't delete someone elses.
2806 $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
2810 * Tests deleting a conversation by conversation id.
2812 public function test_delete_conversation_by_id() {
2815 // Create some users.
2816 $user1 = self::getDataGenerator()->create_user();
2817 $user2 = self::getDataGenerator()->create_user();
2819 // The person doing the search.
2820 $this->setUser($user1);
2822 // Get self-conversation.
2823 $sc1 = \core_message\api::get_self_conversation($user1->id);
2824 $sc2 = \core_message\api::get_self_conversation($user2->id);
2826 // Send some messages back and forth.
2828 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2829 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2830 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2831 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2832 $m5id = testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi to myself!', $time + 5);
2833 $m6id = testhelper::send_fake_message_to_conversation($user2, $sc2->id, 'I am talking with myself', $time + 6);
2835 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2837 // Delete the individual conversation between user1 and user2 (only for user1).
2838 \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2840 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2841 $this->assertCount(4, $muas);
2845 $mua1 = array_shift($muas);
2846 $mua2 = array_shift($muas);
2847 $mua3 = array_shift($muas);
2848 $mua4 = array_shift($muas);
2850 $this->assertEquals($user1->id, $mua1->userid);
2851 $this->assertEquals($m1id, $mua1->messageid);
2852 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2854 $this->assertEquals($user1->id, $mua2->userid);
2855 $this->assertEquals($m2id, $mua2->messageid);
2856 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2858 $this->assertEquals($user1->id, $mua3->userid);
2859 $this->assertEquals($m3id, $mua3->messageid);
2860 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2862 $this->assertEquals($user1->id, $mua4->userid);
2863 $this->assertEquals($m4id, $mua4->messageid);
2864 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2866 // Delete the self-conversation as user 1.
2867 \core_message\api::delete_conversation_by_id($user1->id, $sc1->id);
2869 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2870 $this->assertCount(5, $muas);
2875 $mua1 = array_shift($muas);
2876 $mua2 = array_shift($muas);
2877 $mua3 = array_shift($muas);
2878 $mua4 = array_shift($muas);
2879 $mua5 = array_shift($muas);
2881 // Check only messages in self-conversion for user1 are deleted (self-conversation for user2 shouldn't be removed).
2882 $this->assertEquals($user1->id, $mua5->userid);
2883 $this->assertEquals($m5id, $mua5->messageid);
2884 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua5->action);
2888 * Tests counting unread conversations.
2890 public function test_count_unread_conversations() {
2891 $this->resetAfterTest(true);
2893 // Create some users.
2894 $user1 = self::getDataGenerator()->create_user();
2895 $user2 = self::getDataGenerator()->create_user();
2896 $user3 = self::getDataGenerator()->create_user();
2897 $user4 = self::getDataGenerator()->create_user();
2899 // The person wanting the conversation count.
2900 $this->setUser($user1);
2902 // Send some messages back and forth, have some different conversations with different users.
2903 $this->send_fake_message($user1, $user2, 'Yo!');
2904 $this->send_fake_message($user2, $user1, 'Sup mang?');
2905 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2906 $this->send_fake_message($user2, $user1, 'Word.');
2908 $this->send_fake_message($user1, $user3, 'Booyah');
2909 $this->send_fake_message($user3, $user1, 'Whaaat?');
2910 $this->send_fake_message($user1, $user3, 'Nothing.');
2911 $this->send_fake_message($user3, $user1, 'Cool.');
2913 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2914 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2915 $this->send_fake_message($user1, $user4, 'Dope.');
2917 // Check the amount for the current user.
2918 $this->assertEquals(3, core_message\api::count_unread_conversations());
2920 // Check the amount for the second user.
2921 $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2925 * Tests counting unread conversations where one conversation is disabled.
2927 public function test_count_unread_conversations_disabled() {
2928 $this->resetAfterTest(true);
2930 // Create some users.
2931 $user1 = self::getDataGenerator()->create_user();
2932 $user2 = self::getDataGenerator()->create_user();
2933 $user3 = self::getDataGenerator()->create_user();
2934 $user4 = self::getDataGenerator()->create_user();
2936 // The person wanting the conversation count.
2937 $this->setUser($user1);
2939 // Send some messages back and forth, have some different conversations with different users.
2940 $this->send_fake_message($user1, $user2, 'Yo!');
2941 $this->send_fake_message($user2, $user1, 'Sup mang?');
2942 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2943 $this->send_fake_message($user2, $user1, 'Word.');
2945 $this->send_fake_message($user1, $user3, 'Booyah');
2946 $this->send_fake_message($user3, $user1, 'Whaaat?');
2947 $this->send_fake_message($user1, $user3, 'Nothing.');
2948 $this->send_fake_message($user3, $user1, 'Cool.');
2950 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2951 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2952 $this->send_fake_message($user1, $user4, 'Dope.');
2954 // Let's disable the last conversation.
2955 $conversationid = core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
2956 core_message\api::disable_conversation($conversationid);
2958 // Check that the disabled conversation was not included.
2959 $this->assertEquals(2, core_message\api::count_unread_conversations());
2963 * Tests deleting a conversation.
2965 public function test_get_all_message_preferences() {
2966 $user = self::getDataGenerator()->create_user();
2967 $this->setUser($user);
2969 // Set a couple of preferences to test.
2970 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2971 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2973 $processors = get_message_processors();
2974 $providers = message_get_providers_for_user($user->id);
2975 $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2977 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2978 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2982 * Tests the user can send a message.
2984 public function test_can_send_message() {
2985 // Create some users.
2986 $user1 = self::getDataGenerator()->create_user();
2987 $user2 = self::getDataGenerator()->create_user();
2989 // Set as the first user.
2990 $this->setUser($user1);
2992 // With the default privacy setting, users can't message them.
2993 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
2995 // Enrol users to the same course.
2996 $course = $this->getDataGenerator()->create_course();
2997 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2998 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2999 // After enrolling users to the course, they should be able to message them with the default privacy setting.
3000 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id));
3004 * Tests the user can't send a message without proper capability.
3006 public function test_can_send_message_without_sendmessage_cap() {
3009 // Create some users.
3010 $user1 = self::getDataGenerator()->create_user();
3011 $user2 = self::getDataGenerator()->create_user();
3013 // Set as the user 1.
3014 $this->setUser($user1);
3016 // Remove the capability to send a message.
3017 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3018 unassign_capability('moodle/site:sendmessage', $roleids['user'],
3019 context_system::instance());
3021 // Check that we can not post a message without the capability.
3022 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3026 * Tests the user can send a message when they are contact.
3028 public function test_can_send_message_when_contact() {
3029 // Create some users.
3030 $user1 = self::getDataGenerator()->create_user();
3031 $user2 = self::getDataGenerator()->create_user();
3033 // Set as the first user.
3034 $this->setUser($user1);
3036 // Check that we can not send user2 a message.
3037 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3039 // Add users as contacts.
3040 \core_message\api::add_contact($user1->id, $user2->id);
3042 // Check that the return result is now true.
3043 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id));
3047 * Tests the user can't send a message if they are not a contact and the user
3048 * has requested messages only from contacts.
3050 public function test_can_send_message_when_not_contact() {
3051 // Create some users.
3052 $user1 = self::getDataGenerator()->create_user();
3053 $user2 = self::getDataGenerator()->create_user();
3055 // Set as the first user.
3056 $this->setUser($user1);
3058 // Set the second user's preference to not receive messages from non-contacts.
3059 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3061 // Check that we can not send user 2 a message.
3062 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3066 * Tests the user can't send a message if they are blocked.
3068 public function test_can_send_message_when_blocked() {
3069 // Create some users.
3070 $user1 = self::getDataGenerator()->create_user();
3071 $user2 = self::getDataGenerator()->create_user();
3074 $this->setUser($user1);
3076 // Block the second user.
3077 \core_message\api::block_user($user1->id, $user2->id);
3079 // Check that the second user can no longer send the first user a message.
3080 $this->assertFalse(\core_message\api::can_send_message($user1->id, $user2->id));
3084 * Tests the user can send a message when site-wide messaging setting is enabled,
3085 * even if they are not a contact and are not members of the same course.
3087 public function test_can_send_message_site_messaging_setting() {
3088 // Create some users.
3089 $user1 = self::getDataGenerator()->create_user();
3090 $user2 = self::getDataGenerator()->create_user();
3092 // Set as the first user.
3093 $this->setUser($user1);
3095 // By default, user only can be messaged by contacts and members of any of his/her courses.
3096 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3098 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3099 set_config('messagingallusers', true);
3101 // Set the second user's preference to receive messages from everybody.
3102 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
3104 // Check that we can send user2 a message.
3105 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id));
3107 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3108 // and members sharing a course with her.
3109 set_config('messagingallusers', false);
3111 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3112 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3114 // Enrol users to the same course.
3115 $course = $this->getDataGenerator()->create_course();
3116 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3117 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3118 // Check that we can send user2 a message because they are sharing a course.
3119 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id));
3121 // Set the second user's preference to receive messages only from contacts.
3122 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3123 // Check that now the user2 can't be contacted because user1 is not their contact.
3124 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id));
3126 // Make contacts user1 and user2.
3127 \core_message\api::add_contact($user2->id, $user1->id);
3128 // Check that we can send user2 a message because they are contacts.
3129 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id));
3133 * Tests the user with the messageanyuser capability can send a message.
3135 public function test_can_send_message_with_messageanyuser_cap() {
3138 // Create some users.
3139 $teacher1 = self::getDataGenerator()->create_user();
3140 $student1 = self::getDataGenerator()->create_user();
3141 $student2 = self::getDataGenerator()->create_user();
3143 // Create users not enrolled in any course.
3144 $user1 = self::getDataGenerator()->create_user();
3147 $course1 = $this->getDataGenerator()->create_course();
3149 // Enrol the users in the course.
3150 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
3151 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
3152 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
3154 // Set some student preferences to not receive messages from non-contacts.
3155 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
3157 // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
3158 $this->assertTrue(\core_message\api::can_send_message($student1->id, $teacher1->id));
3160 // Check that the teacher can't contact user1 because it's not his teacher.
3161 $this->assertFalse(\core_message\api::can_send_message($user1->id, $teacher1->id));
3163 // Remove the messageanyuser capability from the course1 for teachers.
3164 $coursecontext = context_course::instance($course1->id);
3165 $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
3166 assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
3167 $coursecontext->mark_dirty();
3169 // Check that we can't send user1 a message because they are not contacts.
3170 $this->assertFalse(\core_message\api::can_send_message($student1->id, $teacher1->id));
3172 // However, teacher can message student2 because they are sharing a course.
3173 $this->assertTrue(\core_message\api::can_send_message($student2->id, $teacher1->id));
3177 * Tests the user when blocked will not be able to send messages if they are blocked.
3179 public function test_can_send_message_even_if_blocked() {
3180 $this->resetAfterTest();
3182 $user1 = self::getDataGenerator()->create_user();
3183 $user2 = self::getDataGenerator()->create_user();
3185 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id, true));
3189 * Tests the user will be able to send a message even if they are blocked as the user
3190 * has the capability 'moodle/site:messageanyuser'.
3192 public function test_can_send_message_even_if_blocked_with_message_any_user_cap() {
3195 $this->resetAfterTest();
3197 $user1 = self::getDataGenerator()->create_user();
3198 $user2 = self::getDataGenerator()->create_user();
3200 $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user'));
3201 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduserrole->id, context_system::instance(), true);
3203 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id, true));
3207 * Tests the user will be able to send a message even if they are blocked as the user
3208 * has the capability 'moodle/site:readallmessages'.
3210 public function test_can_send_message_even_if_blocked_with_read_all_message_cap() {
3213 $this->resetAfterTest();
3215 $user1 = self::getDataGenerator()->create_user();
3216 $user2 = self::getDataGenerator()->create_user();
3218 $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user'));
3219 assign_capability('moodle/site:readallmessages', CAP_ALLOW, $authenticateduserrole->id, context_system::instance(), true);
3221 $this->assertTrue(\core_message\api::can_send_message($user2->id, $user1->id, true));
3225 * Tests the user can not always send a message if they are blocked just because they share a course.
3227 public function test_can_send_message_even_if_blocked_shared_course() {
3228 $this->resetAfterTest();
3230 // Create some users.
3231 $user1 = self::getDataGenerator()->create_user();
3232 $user2 = self::getDataGenerator()->create_user();
3234 $course = self::getDataGenerator()->create_course();
3236 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3237 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3239 $this->assertFalse(\core_message\api::can_send_message($user2->id, $user1->id, true));
3243 * Tests the user can always send a message even if they are blocked because they share a course and
3244 * have the capability 'moodle/site:messageanyuser' at the course context.
3246 public function test_can_send_message_even_if_blocked_shared_course_with_message_any_user_cap() {
3249 $this->resetAfterTest();
3251 $editingteacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
3253 $teacher = self::getDataGenerator()->create_user();
3254 $student = self::getDataGenerator()->create_user();
3256 $course = self::getDataGenerator()->create_course();
3258 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $editingteacherrole->id);
3259 $this->getDataGenerator()->enrol_user($student->id, $course->id);
3261 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $editingteacherrole->id,
3262 context_course::instance($course->id), true);
3264 // Check that the second user can no longer send the first user a message.
3265 $this->assertTrue(\core_message\api::can_send_message($student->id, $teacher->id, true));
3269 * Test that calling to can_post_message() now shows debugging. MDL-65093.
3271 * @deprecated since 3.8
3272 * @todo Final deprecation in MDL-66266
3274 public function test_can_post_emits_debugging() {
3275 // Create some users.