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_read_for_user($recipient->id);
56 $this->assertDebuggingCalled();
57 $this->assertEquals(message_count_unread_messages($recipient), 0);
60 public function test_mark_all_read_for_user_touser_with_fromuser() {
61 $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
62 $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
63 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
65 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
66 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
67 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
68 $this->send_fake_message($sender1, $recipient);
69 $this->send_fake_message($sender1, $recipient);
70 $this->send_fake_message($sender1, $recipient);
71 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
72 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
73 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
74 $this->send_fake_message($sender2, $recipient);
75 $this->send_fake_message($sender2, $recipient);
76 $this->send_fake_message($sender2, $recipient);
78 \core_message\api::mark_all_read_for_user($recipient->id, $sender1->id);
79 $this->assertDebuggingCalled();
80 $this->assertEquals(message_count_unread_messages($recipient), 3);
83 public function test_mark_all_read_for_user_touser_with_type() {
84 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
85 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
87 $this->send_fake_message($sender, $recipient, 'Notification', 1);
88 $this->send_fake_message($sender, $recipient, 'Notification', 1);
89 $this->send_fake_message($sender, $recipient, 'Notification', 1);
90 $this->send_fake_message($sender, $recipient);
91 $this->send_fake_message($sender, $recipient);
92 $this->send_fake_message($sender, $recipient);
94 \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_NOTIFICATION);
95 $this->assertDebuggingCalled();
96 $this->assertEquals(message_count_unread_messages($recipient), 3);
98 \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_MESSAGE);
99 $this->assertDebuggingCalled();
100 $this->assertEquals(message_count_unread_messages($recipient), 0);
104 * Test count_blocked_users.
106 public function test_count_blocked_users() {
109 // Set this user as the admin.
110 $this->setAdminUser();
112 // Create user to add to the admin's block list.
113 $user1 = $this->getDataGenerator()->create_user();
114 $user2 = $this->getDataGenerator()->create_user();
116 $this->assertEquals(0, \core_message\api::count_blocked_users());
118 // Add 1 blocked user to admin's blocked user list.
119 \core_message\api::block_user($USER->id, $user1->id);
121 $this->assertEquals(0, \core_message\api::count_blocked_users($user1));
122 $this->assertEquals(1, \core_message\api::count_blocked_users());
126 * Tests searching users in a course.
128 public function test_search_users_in_course() {
129 // Create some users.
130 $user1 = new stdClass();
131 $user1->firstname = 'User';
132 $user1->lastname = 'One';
133 $user1 = self::getDataGenerator()->create_user($user1);
135 // The person doing the search.
136 $this->setUser($user1);
138 // Second user is going to have their last access set to now, so they are online.
139 $user2 = new stdClass();
140 $user2->firstname = 'User';
141 $user2->lastname = 'Two';
142 $user2->lastaccess = time();
143 $user2 = self::getDataGenerator()->create_user($user2);
145 // Block the second user.
146 \core_message\api::block_user($user1->id, $user2->id);
148 $user3 = new stdClass();
149 $user3->firstname = 'User';
150 $user3->lastname = 'Three';
151 $user3 = self::getDataGenerator()->create_user($user3);
154 $course1 = new stdClass();
155 $course1->fullname = 'Course';
156 $course1->shortname = 'One';
157 $course1 = $this->getDataGenerator()->create_course($course1);
159 // Enrol the searcher and one user in the course.
160 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
161 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
164 $results = \core_message\api::search_users_in_course($user1->id, $course1->id, 'User');
166 $this->assertEquals(1, count($results));
169 $this->assertEquals($user2->id, $user->userid);
170 $this->assertEquals(fullname($user2), $user->fullname);
171 $this->assertFalse($user->ismessaging);
172 $this->assertNull($user->lastmessage);
173 $this->assertNull($user->messageid);
174 $this->assertNull($user->isonline);
175 $this->assertFalse($user->isread);
176 $this->assertTrue($user->isblocked);
177 $this->assertNull($user->unreadcount);
181 * Tests searching users.
183 public function test_search_users() {
186 // Create some users.
187 $user1 = new stdClass();
188 $user1->firstname = 'User';
189 $user1->lastname = 'One';
190 $user1 = self::getDataGenerator()->create_user($user1);
192 // Set as the user performing the search.
193 $this->setUser($user1);
195 $user2 = new stdClass();
196 $user2->firstname = 'User search';
197 $user2->lastname = 'Two';
198 $user2 = self::getDataGenerator()->create_user($user2);
200 $user3 = new stdClass();
201 $user3->firstname = 'User search';
202 $user3->lastname = 'Three';
203 $user3 = self::getDataGenerator()->create_user($user3);
205 $user4 = new stdClass();
206 $user4->firstname = 'User';
207 $user4->lastname = 'Four';
208 $user4 = self::getDataGenerator()->create_user($user4);
210 $user5 = new stdClass();
211 $user5->firstname = 'User search';
212 $user5->lastname = 'Five';
213 $user5 = self::getDataGenerator()->create_user($user5);
215 $user6 = new stdClass();
216 $user6->firstname = 'User';
217 $user6->lastname = 'Six';
218 $user6 = self::getDataGenerator()->create_user($user6);
220 // Create some courses.
221 $course1 = new stdClass();
222 $course1->fullname = 'Course search';
223 $course1->shortname = 'One';
224 $course1 = $this->getDataGenerator()->create_course($course1);
226 $course2 = new stdClass();
227 $course2->fullname = 'Course';
228 $course2->shortname = 'Two';
229 $course2 = $this->getDataGenerator()->create_course($course2);
231 $course3 = new stdClass();
232 $course3->fullname = 'Course';
233 $course3->shortname = 'Three search';
234 $course3 = $this->getDataGenerator()->create_course($course3);
236 $course4 = new stdClass();
237 $course4->fullname = 'Course Four';
238 $course4->shortname = 'CF100';
239 $course4 = $this->getDataGenerator()->create_course($course4);
241 $course5 = new stdClass();
242 $course5->fullname = 'Course';
243 $course5->shortname = 'Five search';
244 $course5 = $this->getDataGenerator()->create_course($course5);
246 $role = $DB->get_record('role', ['shortname' => 'student']);
247 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $role->id);
248 $this->getDataGenerator()->enrol_user($user1->id, $course2->id, $role->id);
249 $this->getDataGenerator()->enrol_user($user1->id, $course3->id, $role->id);
250 $this->getDataGenerator()->enrol_user($user1->id, $course5->id, $role->id);
252 // Add some users as contacts.
253 \core_message\api::add_contact($user1->id, $user2->id);
254 \core_message\api::add_contact($user1->id, $user3->id);
255 \core_message\api::add_contact($user1->id, $user4->id);
257 // Remove the viewparticipants capability from one of the courses.
258 $course5context = context_course::instance($course5->id);
259 assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $role->id, $course5context->id);
261 // Perform a search $CFG->messagingallusers setting enabled.
262 set_config('messagingallusers', 1);
263 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
265 // Check that we retrieved the correct contacts.
266 $this->assertEquals(2, count($contacts));
267 $this->assertEquals($user3->id, $contacts[0]->userid);
268 $this->assertEquals($user2->id, $contacts[1]->userid);
270 // Check that we retrieved the correct courses.
271 $this->assertEquals(2, count($courses));
272 $this->assertEquals($course3->id, $courses[0]->id);
273 $this->assertEquals($course1->id, $courses[1]->id);
275 // Check that we retrieved the correct non-contacts.
276 $this->assertEquals(1, count($noncontacts));
277 $this->assertEquals($user5->id, $noncontacts[0]->userid);
281 * Tests searching users with empty result.
283 public function test_search_users_with_empty_result() {
285 // Create some users.
286 $user1 = new stdClass();
287 $user1->firstname = 'User';
288 $user1->lastname = 'One';
289 $user1 = self::getDataGenerator()->create_user($user1);
291 // Set as the user performing the search.
292 $this->setUser($user1);
294 $user2 = new stdClass();
295 $user2->firstname = 'User';
296 $user2->lastname = 'Two';
297 $user2 = self::getDataGenerator()->create_user($user2);
299 // Perform a search $CFG->messagingallusers setting enabled.
300 set_config('messagingallusers', 1);
301 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
303 // Check results are empty.
304 $this->assertEquals(0, count($contacts));
305 $this->assertEquals(0, count($courses));
306 $this->assertEquals(0, count($noncontacts));
310 * Tests searching for users when site-wide messaging is disabled.
312 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
313 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
316 public function test_message_search_users_messagingallusers_disabled() {
317 $this->resetAfterTest();
319 // Create some users.
321 foreach (range(1, 7) as $i) {
322 $user = new stdClass();
323 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
324 $user->lastname = $i;
325 $user = $this->getDataGenerator()->create_user($user);
329 // Enrol a few users in the same course, but leave them as non-contacts.
330 $course1 = $this->getDataGenerator()->create_course();
331 $this->setAdminUser();
332 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
333 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
334 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
336 // Add some other users as contacts.
337 \core_message\api::add_contact($users[1]->id, $users[2]->id);
338 \core_message\api::add_contact($users[3]->id, $users[1]->id);
339 \core_message\api::add_contact($users[1]->id, $users[4]->id);
341 // Create individual conversations between some users, one contact and one non-contact.
342 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
343 [$users[1]->id, $users[2]->id]);
344 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
345 [$users[6]->id, $users[1]->id]);
347 // Create a group conversation between 4 users, including a contact and a non-contact.
348 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
349 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
351 // Set as the user performing the search.
352 $this->setUser($users[1]);
354 // Perform a search with $CFG->messagingallusers disabled.
355 set_config('messagingallusers', 0);
356 $result = \core_message\api::message_search_users($users[1]->id, 'search');
358 // Confirm that we returns contacts and non-contacts.
359 $this->assertArrayHasKey(0, $result);
360 $this->assertArrayHasKey(1, $result);
361 $contacts = $result[0];
362 $noncontacts = $result[1];
364 // Check that we retrieved the correct contacts.
365 $this->assertCount(2, $contacts);
366 $this->assertEquals($users[2]->id, $contacts[0]->id);
367 $this->assertEquals($users[3]->id, $contacts[1]->id);
369 // Verify the correct conversations were returned for the contacts.
370 $this->assertCount(2, $contacts[0]->conversations);
371 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
372 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
374 $this->assertCount(0, $contacts[1]->conversations);
376 // Check that we retrieved the correct non-contacts.
377 // When site wide messaging is disabled, we expect to see only those users whose profiles we can view.
378 $this->assertCount(2, $noncontacts);
379 $this->assertEquals($users[6]->id, $noncontacts[0]->id);
380 $this->assertEquals($users[7]->id, $noncontacts[1]->id);
382 // Verify the correct conversations were returned for the non-contacts.
383 $this->assertCount(1, $noncontacts[0]->conversations);
384 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
385 $noncontacts[0]->conversations[$ic2->id]->type);
387 $this->assertCount(1, $noncontacts[1]->conversations);
388 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[1]->conversations[$gc1->id]->type);
392 * Tests searching for users when site-wide messaging is enabled.
394 * This test verifies that any contacts are returned, as well as any non-contacts, regardless of whether the searching user
395 * can view their respective profile.
397 public function test_message_search_users_messagingallusers_enabled() {
398 $this->resetAfterTest();
400 // Create some users.
402 foreach (range(1, 8) as $i) {
403 $user = new stdClass();
404 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
405 $user->lastname = $i;
406 $user = $this->getDataGenerator()->create_user($user);
410 // Enrol a few users in the same course, but leave them as non-contacts.
411 $course1 = $this->getDataGenerator()->create_course();
412 $this->setAdminUser();
413 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
414 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
415 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
417 // Add some other users as contacts.
418 \core_message\api::add_contact($users[1]->id, $users[2]->id);
419 \core_message\api::add_contact($users[3]->id, $users[1]->id);
420 \core_message\api::add_contact($users[1]->id, $users[4]->id);
422 // Create individual conversations between some users, one contact and one non-contact.
423 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
424 [$users[1]->id, $users[2]->id]);
425 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
426 [$users[6]->id, $users[1]->id]);
428 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
429 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
430 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
432 // Set as the user performing the search.
433 $this->setUser($users[1]);
435 // Perform a search with $CFG->messagingallusers enabled.
436 set_config('messagingallusers', 1);
437 $result = \core_message\api::message_search_users($users[1]->id, 'search');
439 // Confirm that we returns contacts and non-contacts.
440 $this->assertArrayHasKey(0, $result);
441 $this->assertArrayHasKey(1, $result);
442 $contacts = $result[0];
443 $noncontacts = $result[1];
445 // Check that we retrieved the correct contacts.
446 $this->assertCount(2, $contacts);
447 $this->assertEquals($users[2]->id, $contacts[0]->id);
448 $this->assertEquals($users[3]->id, $contacts[1]->id);
450 // Verify the correct conversations were returned for the contacts.
451 $this->assertCount(2, $contacts[0]->conversations);
452 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
453 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
455 $this->assertCount(0, $contacts[1]->conversations);
457 // Check that we retrieved the correct non-contacts.
458 // If site wide messaging is enabled, we expect to be able to search for any users.
459 $this->assertCount(4, $noncontacts);
460 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
461 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
462 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
463 $this->assertEquals($users[8]->id, $noncontacts[3]->id);
465 // Verify the correct conversations were returned for the non-contacts.
466 $this->assertCount(0, $noncontacts[0]->conversations);
468 $this->assertCount(1, $noncontacts[1]->conversations);
469 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
470 $noncontacts[1]->conversations[$ic2->id]->type);
472 $this->assertCount(1, $noncontacts[2]->conversations);
473 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
475 $this->assertCount(1, $noncontacts[3]->conversations);
476 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[3]->conversations[$gc1->id]->type);
480 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
482 public function test_message_search_users_with_empty_result() {
483 $this->resetAfterTest();
485 // Create some users, but make sure neither will match the search term.
486 $user1 = new stdClass();
487 $user1->firstname = 'User';
488 $user1->lastname = 'One';
489 $user1 = $this->getDataGenerator()->create_user($user1);
490 $user2 = new stdClass();
491 $user2->firstname = 'User';
492 $user2->lastname = 'Two';
493 $user2 = $this->getDataGenerator()->create_user($user2);
495 // Perform a search as user1.
496 $this->setUser($user1);
497 $result = \core_message\api::message_search_users($user1->id, 'search');
499 // Check results are empty.
500 $this->assertCount(0, $result[0]);
501 $this->assertCount(0, $result[1]);
505 * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
507 public function test_message_search_users_limit_offset() {
508 $this->resetAfterTest();
512 foreach (range(1, 20) as $i) {
513 $user = new stdClass();
514 $user->firstname = "User search";
515 $user->lastname = $i;
516 $user = $this->getDataGenerator()->create_user($user);
520 // Enrol the first 9 users in the same course, but leave them as non-contacts.
521 $this->setAdminUser();
522 $course1 = $this->getDataGenerator()->create_course();
523 foreach (range(1, 9) as $i) {
524 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
527 // Add 5 users, starting at the 11th user, as contacts for user1.
528 foreach (range(11, 15) as $i) {
529 \core_message\api::add_contact($users[1]->id, $users[$i]->id);
532 // Set as the user performing the search.
533 $this->setUser($users[1]);
535 // Search using a limit of 3.
536 // This tests the case where we have more results than the limit for both contacts and non-contacts.
537 $result = \core_message\api::message_search_users($users[1]->id, 'search', 0, 3);
538 $contacts = $result[0];
539 $noncontacts = $result[1];
541 // Check that we retrieved the correct contacts.
542 $this->assertCount(3, $contacts);
543 $this->assertEquals($users[11]->id, $contacts[0]->id);
544 $this->assertEquals($users[12]->id, $contacts[1]->id);
545 $this->assertEquals($users[13]->id, $contacts[2]->id);
547 // Check that we retrieved the correct non-contacts.
548 $this->assertCount(3, $noncontacts);
549 $this->assertEquals($users[2]->id, $noncontacts[0]->id);
550 $this->assertEquals($users[3]->id, $noncontacts[1]->id);
551 $this->assertEquals($users[4]->id, $noncontacts[2]->id);
553 // Now, offset to get the next batch of results.
554 // We expect to see 2 contacts, and 3 non-contacts.
555 $result = \core_message\api::message_search_users($users[1]->id, 'search', 3, 3);
556 $contacts = $result[0];
557 $noncontacts = $result[1];
558 $this->assertCount(2, $contacts);
559 $this->assertEquals($users[14]->id, $contacts[0]->id);
560 $this->assertEquals($users[15]->id, $contacts[1]->id);
562 $this->assertCount(3, $noncontacts);
563 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
564 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
565 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
567 // Now, offset to get the next batch of results.
568 // We expect to see 0 contacts, and 2 non-contacts.
569 $result = \core_message\api::message_search_users($users[1]->id, 'search', 6, 3);
570 $contacts = $result[0];
571 $noncontacts = $result[1];
572 $this->assertCount(0, $contacts);
574 $this->assertCount(2, $noncontacts);
575 $this->assertEquals($users[8]->id, $noncontacts[0]->id);
576 $this->assertEquals($users[9]->id, $noncontacts[1]->id);
580 * Tests searching users as a user having the 'moodle/user:viewdetails' capability.
582 public function test_message_search_users_with_cap() {
583 $this->resetAfterTest();
586 // Create some users.
588 foreach (range(1, 8) as $i) {
589 $user = new stdClass();
590 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
591 $user->lastname = $i;
592 $user = $this->getDataGenerator()->create_user($user);
596 // Enrol a few users in the same course, but leave them as non-contacts.
597 $course1 = $this->getDataGenerator()->create_course();
598 $this->setAdminUser();
599 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
600 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
601 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
603 // Add some other users as contacts.
604 \core_message\api::add_contact($users[1]->id, $users[2]->id);
605 \core_message\api::add_contact($users[3]->id, $users[1]->id);
606 \core_message\api::add_contact($users[1]->id, $users[4]->id);
608 // Set as the user performing the search.
609 $this->setUser($users[1]);
611 // Grant the authenticated user role the capability 'user:viewdetails' at site context.
612 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
613 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance());
615 // Perform a search with $CFG->messagingallusers disabled.
616 set_config('messagingallusers', 0);
617 $result = \core_message\api::message_search_users($users[1]->id, 'search');
618 $contacts = $result[0];
619 $noncontacts = $result[1];
621 // Check that we retrieved the correct contacts.
622 $this->assertCount(2, $contacts);
623 $this->assertEquals($users[2]->id, $contacts[0]->id);
624 $this->assertEquals($users[3]->id, $contacts[1]->id);
626 // Check that we retrieved the correct non-contacts.
627 // Site-wide messaging is disabled, but since we can see all users, we expect to be able to search for any users.
628 $this->assertCount(4, $noncontacts);
629 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
630 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
631 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
632 $this->assertEquals($users[8]->id, $noncontacts[3]->id);
636 * Tests searching users with messaging disabled.
638 public function test_message_search_users_messaging_disabled() {
639 $this->resetAfterTest();
642 $user = $this->getDataGenerator()->create_user();
644 // Disable messaging.
645 set_config('messaging', 0);
647 // Ensure an exception is thrown.
648 $this->expectException('moodle_exception');
649 \core_message\api::message_search_users($user->id, 'User');
653 * Tests getting conversations between 2 users.
655 public function test_get_conversations_between_users() {
656 // Create some users.
657 $user1 = new stdClass();
658 $user1->firstname = 'User';
659 $user1->lastname = 'One';
660 $user1 = self::getDataGenerator()->create_user($user1);
662 $user2 = new stdClass();
663 $user2->firstname = 'User';
664 $user2->lastname = 'Two';
665 $user2 = self::getDataGenerator()->create_user($user2);
667 $user3 = new stdClass();
668 $user3->firstname = 'User search';
669 $user3->lastname = 'Three';
670 $user3 = self::getDataGenerator()->create_user($user3);
672 $user4 = new stdClass();
673 $user4->firstname = 'User';
674 $user4->lastname = 'Four';
675 $user4 = self::getDataGenerator()->create_user($user4);
677 $user5 = new stdClass();
678 $user5->firstname = 'User';
679 $user5->lastname = 'Five';
680 $user5 = self::getDataGenerator()->create_user($user5);
682 $user6 = new stdClass();
683 $user6->firstname = 'User search';
684 $user6->lastname = 'Six';
685 $user6 = self::getDataGenerator()->create_user($user6);
687 // Add some users as contacts.
688 \core_message\api::add_contact($user1->id, $user2->id);
689 \core_message\api::add_contact($user6->id, $user1->id);
691 // Create private conversations with some users.
692 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
693 array($user1->id, $user2->id));
694 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
695 array($user3->id, $user1->id));
697 // Create a group conversation with users.
698 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
699 array($user1->id, $user2->id, $user3->id, $user4->id),
702 // Check that we retrieved the correct conversations.
703 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user2->id));
704 $this->assertCount(2, \core_message\api::get_conversations_between_users($user2->id, $user1->id));
705 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user3->id));
706 $this->assertCount(2, \core_message\api::get_conversations_between_users($user3->id, $user1->id));
707 $this->assertCount(1, \core_message\api::get_conversations_between_users($user1->id, $user4->id));
708 $this->assertCount(1, \core_message\api::get_conversations_between_users($user4->id, $user1->id));
709 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user5->id));
710 $this->assertCount(0, \core_message\api::get_conversations_between_users($user5->id, $user1->id));
711 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user6->id));
712 $this->assertCount(0, \core_message\api::get_conversations_between_users($user6->id, $user1->id));
716 * Tests searching messages.
718 public function test_search_messages() {
719 // Create some users.
720 $user1 = self::getDataGenerator()->create_user();
721 $user2 = self::getDataGenerator()->create_user();
722 $user3 = self::getDataGenerator()->create_user();
724 // The person doing the search.
725 $this->setUser($user1);
727 // Send some messages back and forth.
729 $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
730 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
731 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
732 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
733 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
735 $convid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
736 $conv2id = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
739 \core_message\api::block_user($user1->id, $user3->id);
742 $messages = \core_message\api::search_messages($user1->id, 'o');
744 // Confirm the data is correct.
745 $this->assertEquals(3, count($messages));
747 $message1 = $messages[0];
748 $message2 = $messages[1];
749 $message3 = $messages[2];
751 $this->assertEquals($user2->id, $message1->userid);
752 $this->assertEquals($user2->id, $message1->useridfrom);
753 $this->assertEquals(fullname($user2), $message1->fullname);
754 $this->assertTrue($message1->ismessaging);
755 $this->assertEquals('Word.', $message1->lastmessage);
756 $this->assertNotEmpty($message1->messageid);
757 $this->assertNull($message1->isonline);
758 $this->assertFalse($message1->isread);
759 $this->assertFalse($message1->isblocked);
760 $this->assertNull($message1->unreadcount);
761 $this->assertEquals($convid, $message1->conversationid);
763 $this->assertEquals($user2->id, $message2->userid);
764 $this->assertEquals($user1->id, $message2->useridfrom);
765 $this->assertEquals(fullname($user2), $message2->fullname);
766 $this->assertTrue($message2->ismessaging);
767 $this->assertEquals('Yo!', $message2->lastmessage);
768 $this->assertNotEmpty($message2->messageid);
769 $this->assertNull($message2->isonline);
770 $this->assertTrue($message2->isread);
771 $this->assertFalse($message2->isblocked);
772 $this->assertNull($message2->unreadcount);
773 $this->assertEquals($convid, $message2->conversationid);
775 $this->assertEquals($user3->id, $message3->userid);
776 $this->assertEquals($user3->id, $message3->useridfrom);
777 $this->assertEquals(fullname($user3), $message3->fullname);
778 $this->assertTrue($message3->ismessaging);
779 $this->assertEquals('Don\'t block me.', $message3->lastmessage);
780 $this->assertNotEmpty($message3->messageid);
781 $this->assertNull($message3->isonline);
782 $this->assertFalse($message3->isread);
783 $this->assertTrue($message3->isblocked);
784 $this->assertNull($message3->unreadcount);
785 $this->assertEquals($conv2id, $message3->conversationid);
789 * Test verifying that favourited conversations can be retrieved.
791 public function test_get_favourite_conversations() {
792 // Create some users.
793 $user1 = self::getDataGenerator()->create_user();
794 $user2 = self::getDataGenerator()->create_user();
795 $user3 = self::getDataGenerator()->create_user();
796 $user4 = self::getDataGenerator()->create_user();
798 // The person doing the search.
799 $this->setUser($user1);
801 // No conversations yet.
802 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
804 // Create some conversations for user1.
806 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
807 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
808 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
809 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
811 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
812 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
813 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
814 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
816 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
817 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
818 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
820 // Favourite the first 2 conversations for user1.
822 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
823 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
824 $user1context = context_user::instance($user1->id);
825 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
826 foreach ($convoids as $convoid) {
827 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
830 // We should have 3 conversations.
831 $this->assertCount(3, \core_message\api::get_conversations($user1->id));
833 // And 2 favourited conversations.
834 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
835 $this->assertCount(2, $conversations);
839 * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
841 public function test_get_favourite_conversations_limit_offset() {
842 // Create some users.
843 $user1 = self::getDataGenerator()->create_user();
844 $user2 = self::getDataGenerator()->create_user();
845 $user3 = self::getDataGenerator()->create_user();
846 $user4 = self::getDataGenerator()->create_user();
848 // The person doing the search.
849 $this->setUser($user1);
851 // No conversations yet.
852 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
854 // Create some conversations for user1.
856 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
857 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
858 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
859 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
861 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
862 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
863 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
864 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
866 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
867 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
868 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
870 // Favourite the all conversations for user1.
872 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
873 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
874 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
875 $user1context = context_user::instance($user1->id);
876 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
877 foreach ($convoids as $convoid) {
878 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
881 // Get all records, using offset 0 and large limit.
882 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
884 // Now, get 10 conversations starting at the second record. We should see 2 conversations.
885 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
887 // Now, try to get favourited conversations using an invalid offset.
888 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 4, 10, null, true));
892 * Tests retrieving favourite conversations when a conversation contains a deleted user.
894 public function test_get_favourite_conversations_with_deleted_user() {
895 // Create some users.
896 $user1 = self::getDataGenerator()->create_user();
897 $user2 = self::getDataGenerator()->create_user();
898 $user3 = self::getDataGenerator()->create_user();
900 // Send some messages back and forth, have some different conversations with different users.
902 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
903 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
904 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
905 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
907 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
908 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
909 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
910 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
912 // Favourite the all conversations for user1.
914 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
915 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
916 $user1context = context_user::instance($user1->id);
917 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
918 foreach ($convoids as $convoid) {
919 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
922 // Delete the second user.
925 // Retrieve the conversations.
926 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
928 // We should only have one conversation because the other user was deleted.
929 $this->assertCount(1, $conversations);
931 // Confirm the conversation is from the non-deleted user.
932 $conversation = reset($conversations);
933 $this->assertEquals($convoids[1], $conversation->id);
937 * Test confirming that conversations can be marked as favourites.
939 public function test_set_favourite_conversation() {
940 // Create some users.
941 $user1 = self::getDataGenerator()->create_user();
942 $user2 = self::getDataGenerator()->create_user();
943 $user3 = self::getDataGenerator()->create_user();
945 // Send some messages back and forth, have some different conversations with different users.
947 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
948 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
949 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
950 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
952 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
953 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
954 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
955 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
957 // Favourite the first conversation as user 1.
958 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
959 $favourite = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
961 // Verify we have a single favourite conversation a user 1.
962 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
964 // Verify we have no favourites as user2, despite being a member in that conversation.
965 $this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
967 // Try to favourite the same conversation again should just return the existing favourite.
968 $repeatresult = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
969 $this->assertEquals($favourite->id, $repeatresult->id);
973 * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
975 public function test_set_favourite_conversation_nonexistent_conversation() {
976 // Create some users.
977 $user1 = self::getDataGenerator()->create_user();
978 // Try to favourite a non-existent conversation.
979 $this->expectException(\moodle_exception::class);
980 \core_message\api::set_favourite_conversation(0, $user1->id);
984 * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
986 public function test_set_favourite_conversation_non_member() {
987 // Create some users.
988 $user1 = self::getDataGenerator()->create_user();
989 $user2 = self::getDataGenerator()->create_user();
990 $user3 = self::getDataGenerator()->create_user();
992 // Send some messages back and forth, have some different conversations with different users.
994 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
995 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
996 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
997 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
999 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
1000 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
1001 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
1002 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1004 // Try to favourite the first conversation as user 3, who is not a member.
1005 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1006 $this->expectException(\moodle_exception::class);
1007 \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
1011 * Test confirming that those conversations marked as favourites can be unfavourited.
1013 public function test_unset_favourite_conversation() {
1014 // Create some users.
1015 $user1 = self::getDataGenerator()->create_user();
1016 $user2 = self::getDataGenerator()->create_user();
1017 $user3 = self::getDataGenerator()->create_user();
1019 // Send some messages back and forth, have some different conversations with different users.
1021 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1022 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1023 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1024 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1026 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
1027 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
1028 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
1029 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1031 // Favourite the first conversation as user 1 and the second as user 3.
1032 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1033 $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
1034 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
1035 \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
1037 // Verify we have a single favourite conversation for both user 1 and user 3.
1038 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1039 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1041 // Now unfavourite the conversation as user 1.
1042 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1044 // Verify we have a single favourite conversation user 3 only, and none for user1.
1045 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1046 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1048 // Try to favourite the same conversation again as user 1.
1049 $this->expectException(\moodle_exception::class);
1050 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1054 * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
1056 public function test_unset_favourite_conversation_not_favourite() {
1057 // Create some users.
1058 $user1 = self::getDataGenerator()->create_user();
1059 $user2 = self::getDataGenerator()->create_user();
1061 // Send some messages back and forth, have some different conversations with different users.
1063 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1064 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1065 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1066 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1068 // Now try to unfavourite the conversation as user 1.
1069 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1070 $this->expectException(\moodle_exception::class);
1071 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1075 * Test verifying that a non-existent conversation cannot be unset as a favourite.
1077 public function test_unset_favourite_conversation_non_existent_conversation() {
1078 // Create some users.
1079 $user1 = self::getDataGenerator()->create_user();
1081 // Now try to unfavourite the conversation as user 1.
1082 $this->expectException(\moodle_exception::class);
1083 \core_message\api::unset_favourite_conversation(0, $user1->id);
1087 * Helper to seed the database with initial state.
1089 protected function create_conversation_test_data() {
1090 // Create some users.
1091 $user1 = self::getDataGenerator()->create_user();
1092 $user2 = self::getDataGenerator()->create_user();
1093 $user3 = self::getDataGenerator()->create_user();
1094 $user4 = self::getDataGenerator()->create_user();
1098 // Create some conversations. We want:
1099 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
1100 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
1101 // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
1102 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
1103 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
1105 // Individual conversation, user1 is a member, last message from other user.
1106 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1107 [$user1->id, $user2->id]);
1108 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
1109 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
1111 // Individual conversation, user1 is a member, last message from user1.
1112 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1113 [$user1->id, $user3->id]);
1114 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
1115 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
1117 // Individual conversation, user1 is not a member.
1118 $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1119 [$user2->id, $user3->id]);
1120 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
1121 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
1123 // Group conversation, user1 is not a member.
1124 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1125 [$user2->id, $user3->id, $user4->id], 'Project discussions');
1126 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
1127 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
1129 // Group conversation, user1 is a member, last message from another user.
1130 $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1131 [$user1->id, $user3->id, $user4->id], 'Group chat');
1132 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
1133 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
1134 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
1136 // Group conversation, user1 is a member, last message from user1.
1137 $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1138 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
1139 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
1140 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
1141 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
1143 // Empty group conversations (x2), user1 is a member.
1144 $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1145 [$user1->id, $user2->id, $user3->id], 'Empty group');
1146 $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1147 [$user1->id, $user2->id, $user4->id], 'Another empty group');
1149 // Empty group conversation, user1 is NOT a member.
1150 $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1151 [$user2->id, $user3->id, $user4->id], 'Empty group 3');
1153 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
1157 * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
1159 public function test_get_conversations_no_restrictions() {
1161 // No conversations should exist yet.
1162 $user1 = self::getDataGenerator()->create_user();
1163 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
1165 // Get a bunch of conversations, some group, some individual and in different states.
1166 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1167 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1169 // Get all conversations for user1.
1170 $conversations = core_message\api::get_conversations($user1->id);
1172 // Verify there are 2 individual conversation, 2 group conversations, and 2 empty group conversations.
1173 // The conversations with the most recent messages should be listed first, followed by the empty
1174 // conversations, with the most recently created first.
1175 $this->assertCount(6, $conversations);
1176 $typecounts = array_count_values(array_column($conversations, 'type'));
1177 $this->assertEquals(2, $typecounts[1]);
1178 $this->assertEquals(4, $typecounts[2]);
1180 // Those conversations having messages should be listed first, ordered by most recent message time.
1181 $this->assertEquals($gc3->id, $conversations[0]->id);
1182 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
1183 $this->assertFalse($conversations[0]->isfavourite);
1184 $this->assertCount(1, $conversations[0]->members);
1185 $this->assertEquals(4, $conversations[0]->membercount);
1186 $this->assertCount(1, $conversations[0]->messages);
1187 $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]);
1188 $expectedmessagetext = message_format_message_text($message);
1189 $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text);
1190 $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
1192 $this->assertEquals($gc2->id, $conversations[1]->id);
1193 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
1194 $this->assertFalse($conversations[1]->isfavourite);
1195 $this->assertCount(1, $conversations[1]->members);
1196 $this->assertEquals(3, $conversations[1]->membercount);
1197 $this->assertCount(1, $conversations[1]->messages);
1198 $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]);
1199 $expectedmessagetext = message_format_message_text($message);
1200 $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text);
1201 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1203 $this->assertEquals($ic2->id, $conversations[2]->id);
1204 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
1205 $this->assertFalse($conversations[2]->isfavourite);
1206 $this->assertCount(1, $conversations[2]->members);
1207 $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
1208 $this->assertEquals(2, $conversations[2]->membercount);
1209 $this->assertCount(1, $conversations[2]->messages);
1210 $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]);
1211 $expectedmessagetext = message_format_message_text($message);
1212 $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text);
1213 $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
1215 $this->assertEquals($ic1->id, $conversations[3]->id);
1216 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
1217 $this->assertFalse($conversations[3]->isfavourite);
1218 $this->assertCount(1, $conversations[3]->members);
1219 $this->assertEquals(2, $conversations[3]->membercount);
1220 $this->assertCount(1, $conversations[3]->messages);
1221 $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]);
1222 $expectedmessagetext = message_format_message_text($message);
1223 $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text);
1224 $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
1226 // Of the groups without messages, we expect to see the most recently created first.
1227 $this->assertEquals($gc5->id, $conversations[4]->id);
1228 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
1229 $this->assertFalse($conversations[4]->isfavourite);
1230 $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
1231 $this->assertEquals(3, $conversations[4]->membercount);
1232 $this->assertEmpty($conversations[4]->messages);
1234 $this->assertEquals($gc4->id, $conversations[5]->id);
1235 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
1236 $this->assertFalse($conversations[5]->isfavourite);
1237 $this->assertCount(0, $conversations[5]->members);
1238 $this->assertEquals(3, $conversations[5]->membercount);
1239 $this->assertEmpty($conversations[5]->messages);
1241 // Verify format of the return structure.
1242 foreach ($conversations as $conv) {
1243 $this->assertObjectHasAttribute('id', $conv);
1244 $this->assertObjectHasAttribute('name', $conv);
1245 $this->assertObjectHasAttribute('subname', $conv);
1246 $this->assertObjectHasAttribute('imageurl', $conv);
1247 $this->assertObjectHasAttribute('type', $conv);
1248 $this->assertObjectHasAttribute('isfavourite', $conv);
1249 $this->assertObjectHasAttribute('membercount', $conv);
1250 $this->assertObjectHasAttribute('isread', $conv);
1251 $this->assertObjectHasAttribute('unreadcount', $conv);
1252 $this->assertObjectHasAttribute('members', $conv);
1253 foreach ($conv->members as $member) {
1254 $this->assertObjectHasAttribute('id', $member);
1255 $this->assertObjectHasAttribute('fullname', $member);
1256 $this->assertObjectHasAttribute('profileimageurl', $member);
1257 $this->assertObjectHasAttribute('profileimageurlsmall', $member);
1258 $this->assertObjectHasAttribute('isonline', $member);
1259 $this->assertObjectHasAttribute('showonlinestatus', $member);
1260 $this->assertObjectHasAttribute('isblocked', $member);
1261 $this->assertObjectHasAttribute('iscontact', $member);
1262 $this->assertObjectHasAttribute('isdeleted', $member);
1263 $this->assertObjectHasAttribute('canmessage', $member);
1264 $this->assertObjectHasAttribute('requirescontact', $member);
1265 $this->assertObjectHasAttribute('contactrequests', $member);
1267 $this->assertObjectHasAttribute('messages', $conv);
1268 foreach ($conv->messages as $message) {
1269 $this->assertObjectHasAttribute('id', $message);
1270 $this->assertObjectHasAttribute('useridfrom', $message);
1271 $this->assertObjectHasAttribute('text', $message);
1272 $this->assertObjectHasAttribute('timecreated', $message);
1278 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately.
1280 public function test_get_conversations_message_format() {
1282 // Create some users.
1283 $user1 = self::getDataGenerator()->create_user();
1284 $user2 = self::getDataGenerator()->create_user();
1286 // Create conversation.
1287 $conversation = \core_message\api::create_conversation(
1288 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1289 [$user1->id, $user2->id]
1292 // Send some messages back and forth.
1294 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1);
1295 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2);
1297 // Verify the format of the html message.
1298 $message = $DB->get_record('messages', ['id' => $mid]);
1299 $expectedmessagetext = message_format_message_text($message);
1300 $conversations = \core_message\api::get_conversations($user1->id);
1301 $messages = $conversations[0]->messages;
1302 $this->assertEquals($expectedmessagetext, $messages[0]->text);
1306 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
1308 public function test_get_conversations_limit_offset() {
1309 // Get a bunch of conversations, some group, some individual and in different states.
1310 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1311 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1313 // Get all conversations for user1, limited to 1 result.
1314 $conversations = core_message\api::get_conversations($user1->id, 0, 1);
1316 // Verify the first conversation.
1317 $this->assertCount(1, $conversations);
1318 $conversation = array_shift($conversations);
1319 $this->assertEquals($conversation->id, $gc3->id);
1321 // Verify the next conversation.
1322 $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
1323 $this->assertCount(1, $conversations);
1324 $this->assertEquals($gc2->id, $conversations[0]->id);
1326 // Verify the next conversation.
1327 $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
1328 $this->assertCount(1, $conversations);
1329 $this->assertEquals($ic2->id, $conversations[0]->id);
1331 // Skip one and get both empty conversations.
1332 $conversations = \core_message\api::get_conversations($user1->id, 4, 2);
1333 $this->assertCount(2, $conversations);
1334 $this->assertEquals($gc5->id, $conversations[0]->id);
1335 $this->assertEmpty($conversations[0]->messages);
1336 $this->assertEquals($gc4->id, $conversations[1]->id);
1337 $this->assertEmpty($conversations[1]->messages);
1339 // Ask for an offset that doesn't exist and verify no conversations are returned.
1340 $conversations = \core_message\api::get_conversations($user1->id, 10, 1);
1341 $this->assertCount(0, $conversations);
1345 * Test verifying the type filtering behaviour of the
1347 public function test_get_conversations_type_filter() {
1348 // Get a bunch of conversations, some group, some individual and in different states.
1349 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1350 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1352 // Verify we can ask for only individual conversations.
1353 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1354 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1355 $this->assertCount(2, $conversations);
1357 // Verify we can ask for only group conversations.
1358 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1359 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP);
1360 $this->assertCount(4, $conversations);
1362 // Verify an exception is thrown if an unrecognized type is specified.
1363 $this->expectException(\moodle_exception::class);
1364 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 0);
1368 * Tests retrieving conversations when a conversation contains a deleted user.
1370 public function test_get_conversations_with_deleted_user() {
1371 // Get a bunch of conversations, some group, some individual and in different states.
1372 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1373 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1375 // Delete the second user and retrieve the conversations.
1376 // We should have 5, as $ic1 drops off the list.
1377 // Group conversations remain albeit with less members.
1378 delete_user($user2);
1379 // This is to confirm an exception is not thrown when a user AND the user context is deleted.
1380 // We no longer delete the user context, but historically we did.
1381 context_helper::delete_instance(CONTEXT_USER, $user2->id);
1382 $conversations = \core_message\api::get_conversations($user1->id);
1383 $this->assertCount(5, $conversations);
1384 $this->assertEquals($gc3->id, $conversations[0]->id);
1385 $this->assertcount(1, $conversations[0]->members);
1386 $this->assertEquals($gc2->id, $conversations[1]->id);
1387 $this->assertcount(1, $conversations[1]->members);
1388 $this->assertEquals($ic2->id, $conversations[2]->id);
1389 $this->assertEquals($gc5->id, $conversations[3]->id);
1390 $this->assertEquals($gc4->id, $conversations[4]->id);
1392 // Delete a user from a group conversation where that user had sent the most recent message.
1393 // This user will still be present in the members array, as will the message in the messages array.
1394 delete_user($user4);
1395 $conversations = \core_message\api::get_conversations($user1->id);
1396 $this->assertCount(5, $conversations);
1397 $this->assertEquals($gc2->id, $conversations[1]->id);
1398 $this->assertcount(1, $conversations[1]->members);
1399 $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
1400 $this->assertcount(1, $conversations[1]->messages);
1401 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1403 // Delete the third user and retrieve the conversations.
1404 // We should have 4, as $ic1, $ic2 drop off the list.
1405 // Group conversations remain albeit with less members.
1406 delete_user($user3);
1407 $conversations = \core_message\api::get_conversations($user1->id);
1408 $this->assertCount(4, $conversations);
1409 $this->assertEquals($gc3->id, $conversations[0]->id);
1410 $this->assertcount(1, $conversations[0]->members);
1411 $this->assertEquals($gc2->id, $conversations[1]->id);
1412 $this->assertcount(1, $conversations[1]->members);
1413 $this->assertEquals($gc5->id, $conversations[2]->id);
1414 $this->assertEquals($gc4->id, $conversations[3]->id);
1418 * Test confirming the behaviour of get_conversations() when users delete all messages.
1420 public function test_get_conversations_deleted_messages() {
1421 // Get a bunch of conversations, some group, some individual and in different states.
1422 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1423 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1425 $conversations = \core_message\api::get_conversations($user1->id);
1426 $this->assertCount(6, $conversations);
1428 // Delete all messages from a group conversation the user is in - it should be returned.
1429 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $gc2->id));
1430 $convmessages = \core_message\api::get_conversation_messages($user1->id, $gc2->id);
1431 $messages = $convmessages['messages'];
1432 foreach ($messages as $message) {
1433 \core_message\api::delete_message($user1->id, $message->id);
1435 $conversations = \core_message\api::get_conversations($user1->id);
1436 $this->assertCount(6, $conversations);
1437 $this->assertContains($gc2->id, array_column($conversations, 'id'));
1439 // Delete all messages from an individual conversation the user is in - it should not be returned.
1440 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $ic1->id));
1441 $convmessages = \core_message\api::get_conversation_messages($user1->id, $ic1->id);
1442 $messages = $convmessages['messages'];
1443 foreach ($messages as $message) {
1444 \core_message\api::delete_message($user1->id, $message->id);
1446 $conversations = \core_message\api::get_conversations($user1->id);
1447 $this->assertCount(5, $conversations);
1448 $this->assertNotContains($ic1->id, array_column($conversations, 'id'));
1452 * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single
1455 public function test_get_conversations_favourite_conversations_single() {
1456 // Get a bunch of conversations, some group, some individual and in different states.
1457 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1458 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1460 // Mark a single conversation as favourites.
1461 \core_message\api::set_favourite_conversation($ic2->id, $user1->id);
1463 // Get the conversation, first with no restrictions, confirming the favourite status of the conversations.
1464 $conversations = \core_message\api::get_conversations($user1->id);
1465 $this->assertCount(6, $conversations);
1466 foreach ($conversations as $conv) {
1467 if (in_array($conv->id, [$ic2->id])) {
1468 $this->assertTrue($conv->isfavourite);
1470 $this->assertFalse($conv->isfavourite);
1474 // Now, get ONLY favourite conversations.
1475 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1476 $this->assertCount(1, $conversations);
1477 foreach ($conversations as $conv) {
1478 $this->assertTrue($conv->isfavourite);
1479 $this->assertEquals($ic2->id, $conv->id);
1482 // Now, try ONLY favourites of type 'group'.
1483 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1484 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1485 $this->assertEmpty($conversations);
1487 // And NO favourite conversations.
1488 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1489 $this->assertCount(5, $conversations);
1490 foreach ($conversations as $conv) {
1491 $this->assertFalse($conv->isfavourite);
1492 $this->assertNotEquals($ic2, $conv->id);
1497 * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
1499 public function test_get_conversations_favourite_conversations() {
1500 // Get a bunch of conversations, some group, some individual and in different states.
1501 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1502 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1504 // Try to get ONLY favourite conversations, when no favourites exist.
1505 $this->assertEquals([], \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1507 // Try to get NO favourite conversations, when no favourites exist.
1508 $this->assertCount(6, \core_message\api::get_conversations($user1->id, 0, 20, null, false));
1510 // Mark a few conversations as favourites.
1511 \core_message\api::set_favourite_conversation($ic1->id, $user1->id);
1512 \core_message\api::set_favourite_conversation($gc2->id, $user1->id);
1513 \core_message\api::set_favourite_conversation($gc5->id, $user1->id);
1514 $favouriteids = [$ic1->id, $gc2->id, $gc5->id];
1516 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
1517 $conversations = \core_message\api::get_conversations($user1->id);
1518 $this->assertCount(6, $conversations);
1519 foreach ($conversations as $conv) {
1520 if (in_array($conv->id, $favouriteids)) {
1521 $this->assertTrue($conv->isfavourite);
1523 $this->assertFalse($conv->isfavourite);
1527 // Now, get ONLY favourite conversations.
1528 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1529 $this->assertCount(3, $conversations);
1530 foreach ($conversations as $conv) {
1531 $this->assertTrue($conv->isfavourite);
1532 $this->assertNotFalse(array_search($conv->id, $favouriteids));
1535 // Now, try ONLY favourites of type 'group'.
1536 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1537 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1538 $this->assertCount(2, $conversations);
1539 foreach ($conversations as $conv) {
1540 $this->assertTrue($conv->isfavourite);
1541 $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id]));
1544 // And NO favourite conversations.
1545 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1546 $this->assertCount(3, $conversations);
1547 foreach ($conversations as $conv) {
1548 $this->assertFalse($conv->isfavourite);
1549 $this->assertFalse(array_search($conv->id, $favouriteids));
1554 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this
1555 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want
1556 * to confirm this happens.
1558 public function test_get_conversations_user_in_group_and_individual_chat() {
1559 $this->resetAfterTest();
1561 $user1 = self::getDataGenerator()->create_user();
1562 $user2 = self::getDataGenerator()->create_user();
1563 $user3 = self::getDataGenerator()->create_user();
1565 $conversation = \core_message\api::create_conversation(
1566 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1571 'Individual conversation'
1574 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1576 $conversation = \core_message\api::create_conversation(
1577 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1582 'Group conversation'
1585 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1587 \core_message\api::create_contact_request($user1->id, $user2->id);
1588 \core_message\api::create_contact_request($user1->id, $user3->id);
1590 $conversations = \core_message\api::get_conversations($user2->id);
1592 $groupconversation = array_shift($conversations);
1593 $individualconversation = array_shift($conversations);
1595 $this->assertEquals('Group conversation', $groupconversation->name);
1596 $this->assertEquals('Individual conversation', $individualconversation->name);
1598 $this->assertCount(1, $groupconversation->members);
1599 $this->assertCount(1, $individualconversation->members);
1601 $groupmember = reset($groupconversation->members);
1602 $this->assertNull($groupmember->requirescontact);
1603 $this->assertNull($groupmember->canmessage);
1604 $this->assertEmpty($groupmember->contactrequests);
1606 $individualmember = reset($individualconversation->members);
1607 $this->assertNotNull($individualmember->requirescontact);
1608 $this->assertNotNull($individualmember->canmessage);
1609 $this->assertNotEmpty($individualmember->contactrequests);
1613 * Test verifying that group linked conversations are returned and contain a subname matching the course name.
1615 public function test_get_conversations_group_linked() {
1618 // Create some users.
1619 $user1 = self::getDataGenerator()->create_user();
1620 $user2 = self::getDataGenerator()->create_user();
1621 $user3 = self::getDataGenerator()->create_user();
1623 $course1 = $this->getDataGenerator()->create_course();
1625 // Create a group with a linked conversation and a valid image.
1626 $this->setAdminUser();
1627 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1628 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1629 $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1630 $group1 = $this->getDataGenerator()->create_group([
1631 'courseid' => $course1->id,
1632 'enablemessaging' => 1,
1633 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
1636 // Add users to group1.
1637 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1638 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
1640 // Verify the group with the image works as expected.
1641 $conversations = \core_message\api::get_conversations($user1->id);
1642 $this->assertEquals(2, $conversations[0]->membercount);
1643 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1644 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true);
1645 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1647 // Create a group with a linked conversation and without any image.
1648 $group2 = $this->getDataGenerator()->create_group([
1649 'courseid' => $course1->id,
1650 'enablemessaging' => 1,
1653 // Add users to group2.
1654 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1655 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
1657 // Verify the group without any image works as expected too.
1658 $conversations = \core_message\api::get_conversations($user3->id);
1659 $this->assertEquals(2, $conversations[0]->membercount);
1660 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1661 $groupimageurl = get_group_picture_url($group2, $group2->courseid, true);
1662 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1664 // Now, disable the conversation linked to the group and verify it's no longer returned.
1665 $DB->set_field('message_conversations', 'enabled', 0, ['id' => $conversations[0]->id]);
1666 $conversations = \core_message\api::get_conversations($user3->id);
1667 $this->assertCount(0, $conversations);
1671 * The data provider for get_conversations_mixed.
1673 * This provides sets of data to for testing.
1676 public function get_conversations_mixed_provider() {
1678 'Test that conversations with messages contacts is correctly ordered.' => array(
1684 'contacts' => array(
1686 'messages' => array(
1690 'state' => 'unread',
1696 'state' => 'unread',
1702 'state' => 'unread',
1710 'timemodifier' => 1,
1717 'timemodifier' => 1,
1728 'expectations' => array(
1730 // User1 has conversed most recently with user3. The most recent message is M5.
1732 'messageposition' => 0,
1734 'subject' => '<p>S5</p>',
1737 // User1 has also conversed with user2. The most recent message is S2.
1739 'messageposition' => 1,
1741 'subject' => '<p>S2</p>',
1746 // User2 has only conversed with user1. Their most recent shared message was S2.
1748 'messageposition' => 0,
1750 'subject' => '<p>S2</p>',
1755 // User3 has only conversed with user1. Their most recent shared message was S5.
1757 'messageposition' => 0,
1759 'subject' => '<p>S5</p>',
1765 'Test conversations with a single user, where some messages are read and some are not.' => array(
1770 'contacts' => array(
1772 'messages' => array(
1788 'state' => 'unread',
1789 'timemodifier' => 1,
1795 'state' => 'unread',
1796 'timemodifier' => 1,
1800 'expectations' => array(
1801 // The most recent message between user1 and user2 was S4.
1804 'messageposition' => 0,
1806 'subject' => '<p>S4</p>',
1811 // The most recent message between user1 and user2 was S4.
1813 'messageposition' => 0,
1815 'subject' => '<p>S4</p>',
1821 'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1822 'are out of order' => array(
1823 // This can happen through a combination of factors including multi-master DB replication with messages
1824 // read somehow (e.g. API).
1829 'contacts' => array(
1831 'messages' => array(
1837 'timemodifier' => 1,
1844 'timemodifier' => 2,
1849 'state' => 'unread',
1855 'state' => 'unread',
1859 'expectations' => array(
1860 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1863 'messageposition' => 0,
1865 'subject' => '<p>S2</p>',
1871 'messageposition' => 0,
1873 'subject' => '<p>S2</p>',
1879 'Test unread message count is correct for both users' => array(
1884 'contacts' => array(
1886 'messages' => array(
1892 'timemodifier' => 1,
1899 'timemodifier' => 2,
1906 'timemodifier' => 3,
1913 'timemodifier' => 4,
1918 'state' => 'unread',
1920 'timemodifier' => 5,
1925 'state' => 'unread',
1927 'timemodifier' => 6,
1932 'state' => 'unread',
1934 'timemodifier' => 7,
1939 'state' => 'unread',
1941 'timemodifier' => 8,
1944 'expectations' => array(
1945 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1948 'messageposition' => 0,
1950 'subject' => '<p>S8</p>',
1956 'messageposition' => 0,
1958 'subject' => '<p>S8</p>',
1968 * Test get_conversations with a mixture of messages.
1970 * @dataProvider get_conversations_mixed_provider
1971 * @param array $usersdata The list of users to create for this test.
1972 * @param array $messagesdata The list of messages to create.
1973 * @param array $expectations The list of expected outcomes.
1975 public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1978 // Create all of the users.
1980 foreach ($usersdata as $username) {
1981 $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1984 foreach ($contacts as $username => $contact) {
1985 foreach ($contact as $contactname => $blocked) {
1986 $record = new stdClass();
1987 $record->userid = $users[$username]->id;
1988 $record->contactid = $users[$contactname]->id;
1989 $record->blocked = $blocked;
1990 $record->id = $DB->insert_record('message_contacts', $record);
1994 $defaulttimecreated = time();
1995 foreach ($messagesdata as $messagedata) {
1996 $from = $users[$messagedata['from']];
1997 $to = $users[$messagedata['to']];
1998 $subject = $messagedata['subject'];
2000 if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
2001 $messageid = $this->send_fake_message($from, $to, $subject);
2003 // If there is no state, or the state is not 'unread', assume the message is read.
2004 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
2007 $updatemessage = new stdClass();
2008 $updatemessage->id = $messageid;
2009 if (isset($messagedata['timecreated'])) {
2010 $updatemessage->timecreated = $messagedata['timecreated'];
2011 } else if (isset($messagedata['timemodifier'])) {
2012 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
2014 $updatemessage->timecreated = $defaulttimecreated;
2017 $DB->update_record('messages', $updatemessage);
2020 foreach ($expectations as $username => $data) {
2021 // Get the recent conversations for the specified user.
2022 $user = $users[$username];
2023 $conversations = array_values(\core_message\api::get_conversations($user->id));
2024 foreach ($data as $expectation) {
2025 $otheruser = $users[$expectation['with']];
2026 $conversation = $conversations[$expectation['messageposition']];
2027 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
2028 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
2029 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
2035 * Tests retrieving contacts.
2037 public function test_get_contacts() {
2038 // Create some users.
2039 $user1 = self::getDataGenerator()->create_user();
2042 $this->setUser($user1);
2044 $user2 = new stdClass();
2045 $user2->firstname = 'User';
2046 $user2->lastname = 'A';
2047 $user2 = self::getDataGenerator()->create_user($user2);
2049 $user3 = new stdClass();
2050 $user3->firstname = 'User';
2051 $user3->lastname = 'B';
2052 $user3 = self::getDataGenerator()->create_user($user3);
2054 $user4 = new stdClass();
2055 $user4->firstname = 'User';
2056 $user4->lastname = 'C';
2057 $user4 = self::getDataGenerator()->create_user($user4);
2059 $user5 = new stdClass();
2060 $user5->firstname = 'User';
2061 $user5->lastname = 'D';
2062 $user5 = self::getDataGenerator()->create_user($user5);
2064 // Add some users as contacts.
2065 \core_message\api::add_contact($user1->id, $user2->id);
2066 \core_message\api::add_contact($user1->id, $user3->id);
2067 \core_message\api::add_contact($user1->id, $user4->id);
2069 // Retrieve the contacts.
2070 $contacts = \core_message\api::get_contacts($user1->id);
2072 // Confirm the data is correct.
2073 $this->assertEquals(3, count($contacts));
2074 usort($contacts, ['static', 'sort_contacts']);
2076 $contact1 = $contacts[0];
2077 $contact2 = $contacts[1];
2078 $contact3 = $contacts[2];
2080 $this->assertEquals($user2->id, $contact1->userid);
2081 $this->assertEmpty($contact1->useridfrom);
2082 $this->assertFalse($contact1->ismessaging);
2083 $this->assertNull($contact1->lastmessage);
2084 $this->assertNull($contact1->messageid);
2085 $this->assertNull($contact1->isonline);
2086 $this->assertFalse($contact1->isread);
2087 $this->assertFalse($contact1->isblocked);
2088 $this->assertNull($contact1->unreadcount);
2090 $this->assertEquals($user3->id, $contact2->userid);
2091 $this->assertEmpty($contact2->useridfrom);
2092 $this->assertFalse($contact2->ismessaging);
2093 $this->assertNull($contact2->lastmessage);
2094 $this->assertNull($contact2->messageid);
2095 $this->assertNull($contact2->isonline);
2096 $this->assertFalse($contact2->isread);
2097 $this->assertFalse($contact2->isblocked);
2098 $this->assertNull($contact2->unreadcount);
2100 $this->assertEquals($user4->id, $contact3->userid);
2101 $this->assertEmpty($contact3->useridfrom);
2102 $this->assertFalse($contact3->ismessaging);
2103 $this->assertNull($contact3->lastmessage);
2104 $this->assertNull($contact3->messageid);
2105 $this->assertNull($contact3->isonline);
2106 $this->assertFalse($contact3->isread);
2107 $this->assertFalse($contact3->isblocked);
2108 $this->assertNull($contact3->unreadcount);
2112 * Tests retrieving user contacts.
2114 public function test_get_user_contacts() {
2115 // Create some users.
2116 $user1 = self::getDataGenerator()->create_user();
2119 $this->setUser($user1);
2121 $user2 = new stdClass();
2122 $user2->firstname = 'User';
2123 $user2->lastname = 'A';
2124 $user2 = self::getDataGenerator()->create_user($user2);
2126 $user3 = new stdClass();
2127 $user3->firstname = 'User';
2128 $user3->lastname = 'B';
2129 $user3 = self::getDataGenerator()->create_user($user3);
2131 $user4 = new stdClass();
2132 $user4->firstname = 'User';
2133 $user4->lastname = 'C';
2134 $user4 = self::getDataGenerator()->create_user($user4);
2136 $user5 = new stdClass();
2137 $user5->firstname = 'User';
2138 $user5->lastname = 'D';
2139 $user5 = self::getDataGenerator()->create_user($user5);
2141 // Add some users as contacts.
2142 \core_message\api::add_contact($user1->id, $user2->id);
2143 \core_message\api::add_contact($user1->id, $user3->id);
2144 \core_message\api::add_contact($user1->id, $user4->id);
2146 // Retrieve the contacts.
2147 $contacts = \core_message\api::get_user_contacts($user1->id);
2149 // Confirm the data is correct.
2150 $this->assertEquals(3, count($contacts));
2154 $contact1 = array_shift($contacts);
2155 $contact2 = array_shift($contacts);
2156 $contact3 = array_shift($contacts);
2158 $this->assertEquals($user2->id, $contact1->id);
2159 $this->assertEquals(fullname($user2), $contact1->fullname);
2160 $this->assertTrue($contact1->iscontact);
2162 $this->assertEquals($user3->id, $contact2->id);
2163 $this->assertEquals(fullname($user3), $contact2->fullname);
2164 $this->assertTrue($contact2->iscontact);
2166 $this->assertEquals($user4->id, $contact3->id);
2167 $this->assertEquals(fullname($user4), $contact3->fullname);
2168 $this->assertTrue($contact3->iscontact);
2172 * Tests retrieving messages.
2174 public function test_get_messages() {
2175 // Create some users.
2176 $user1 = self::getDataGenerator()->create_user();
2177 $user2 = self::getDataGenerator()->create_user();
2179 // The person doing the search.
2180 $this->setUser($user1);
2182 // Send some messages back and forth.
2184 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2185 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2186 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2187 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2189 // Retrieve the messages.
2190 $messages = \core_message\api::get_messages($user1->id, $user2->id);
2192 // Confirm the message data is correct.
2193 $this->assertEquals(4, count($messages));
2195 $message1 = $messages[0];
2196 $message2 = $messages[1];
2197 $message3 = $messages[2];
2198 $message4 = $messages[3];
2200 $this->assertEquals($user1->id, $message1->useridfrom);
2201 $this->assertEquals($user2->id, $message1->useridto);
2202 $this->assertTrue($message1->displayblocktime);
2203 $this->assertContains('Yo!', $message1->text);
2205 $this->assertEquals($user2->id, $message2->useridfrom);
2206 $this->assertEquals($user1->id, $message2->useridto);
2207 $this->assertFalse($message2->displayblocktime);
2208 $this->assertContains('Sup mang?', $message2->text);
2210 $this->assertEquals($user1->id, $message3->useridfrom);
2211 $this->assertEquals($user2->id, $message3->useridto);
2212 $this->assertFalse($message3->displayblocktime);
2213 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2215 $this->assertEquals($user2->id, $message4->useridfrom);
2216 $this->assertEquals($user1->id, $message4->useridto);
2217 $this->assertFalse($message4->displayblocktime);
2218 $this->assertContains('Word.', $message4->text);
2222 * Tests retrieving conversation messages.
2224 public function test_get_conversation_messages() {
2225 // Create some users.
2226 $user1 = self::getDataGenerator()->create_user();
2227 $user2 = self::getDataGenerator()->create_user();
2229 // Create conversation.
2230 $conversation = \core_message\api::create_conversation(
2231 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2232 [$user1->id, $user2->id]
2235 // The person doing the search.
2236 $this->setUser($user1);
2238 // Send some messages back and forth.
2240 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2241 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2242 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2243 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2245 // Retrieve the messages.
2246 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2248 // Confirm the conversation id is correct.
2249 $this->assertEquals($conversation->id, $convmessages['id']);
2251 // Confirm the message data is correct.
2252 $messages = $convmessages['messages'];
2253 $this->assertEquals(4, count($messages));
2254 $message1 = $messages[0];
2255 $message2 = $messages[1];
2256 $message3 = $messages[2];
2257 $message4 = $messages[3];
2259 $this->assertEquals($user1->id, $message1->useridfrom);
2260 $this->assertContains('Yo!', $message1->text);
2262 $this->assertEquals($user2->id, $message2->useridfrom);
2263 $this->assertContains('Sup mang?', $message2->text);
2265 $this->assertEquals($user1->id, $message3->useridfrom);
2266 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2268 $this->assertEquals($user1->id, $message4->useridfrom);
2269 $this->assertContains('Word.', $message4->text);
2271 // Confirm the members data is correct.
2272 $members = $convmessages['members'];
2273 $this->assertEquals(2, count($members));
2277 * Tests retrieving group conversation messages.
2279 public function test_get_group_conversation_messages() {
2280 // Create some users.
2281 $user1 = self::getDataGenerator()->create_user();
2282 $user2 = self::getDataGenerator()->create_user();
2283 $user3 = self::getDataGenerator()->create_user();
2284 $user4 = self::getDataGenerator()->create_user();
2286 // Create group conversation.
2287 $conversation = \core_message\api::create_conversation(
2288 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2289 [$user1->id, $user2->id, $user3->id, $user4->id]
2292 // The person doing the search.
2293 $this->setUser($user1);
2295 // Send some messages back and forth.
2297 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2298 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2299 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2300 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2301 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
2303 // Retrieve the messages.
2304 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2306 // Confirm the conversation id is correct.
2307 $this->assertEquals($conversation->id, $convmessages['id']);
2309 // Confirm the message data is correct.
2310 $messages = $convmessages['messages'];
2311 $this->assertEquals(5, count($messages));
2313 $message1 = $messages[0];
2314 $message2 = $messages[1];
2315 $message3 = $messages[2];
2316 $message4 = $messages[3];
2317 $message5 = $messages[4];
2319 $this->assertEquals($user1->id, $message1->useridfrom);
2320 $this->assertContains('Yo!', $message1->text);
2322 $this->assertEquals($user2->id, $message2->useridfrom);
2323 $this->assertContains('Sup mang?', $message2->text);
2325 $this->assertEquals($user3->id, $message3->useridfrom);
2326 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2328 $this->assertEquals($user1->id, $message4->useridfrom);
2329 $this->assertContains('Word.', $message4->text);
2331 $this->assertEquals($user2->id, $message5->useridfrom);
2332 $this->assertContains('Yeah!', $message5->text);
2334 // Confirm the members data is correct.
2335 $members = $convmessages['members'];
2336 $this->assertEquals(3, count($members));
2340 * Test verifying the sorting param for get_conversation_messages is respected().
2342 public function test_get_conversation_messages_sorting() {
2343 // Create some users.
2344 $user1 = self::getDataGenerator()->create_user();
2345 $user2 = self::getDataGenerator()->create_user();
2346 $user3 = self::getDataGenerator()->create_user();
2348 // Create conversations - 1 group and 1 individual.
2349 $conversation = \core_message\api::create_conversation(
2350 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2351 [$user1->id, $user2->id]
2353 $conversation2 = \core_message\api::create_conversation(
2354 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2355 [$user1->id, $user2->id, $user3->id]
2358 // Send some messages back and forth.
2360 $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2361 $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2362 $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2363 $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2365 $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
2366 $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
2367 $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
2368 $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
2370 // The person doing the search.
2371 $this->setUser($user1);
2373 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2374 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2375 $messages = $convmessages['messages'];
2376 $this->assertEquals($m1id, $messages[0]->id);
2377 $this->assertEquals($m2id, $messages[1]->id);
2378 $this->assertEquals($m3id, $messages[2]->id);
2379 $this->assertEquals($m4id, $messages[3]->id);
2381 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2382 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
2383 $messages = $convmessages['messages'];
2384 $this->assertEquals($m1id, $messages[3]->id);
2385 $this->assertEquals($m2id, $messages[2]->id);
2386 $this->assertEquals($m3id, $messages[1]->id);
2387 $this->assertEquals($m4id, $messages[0]->id);
2389 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2390 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
2391 $messages = $convmessages['messages'];
2392 $this->assertEquals($gm1id, $messages[0]->id);
2393 $this->assertEquals($gm2id, $messages[1]->id);
2394 $this->assertEquals($gm3id, $messages[2]->id);
2395 $this->assertEquals($gm4id, $messages[3]->id);
2397 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2398 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
2399 $messages = $convmessages['messages'];
2400 $this->assertEquals($gm1id, $messages[3]->id);
2401 $this->assertEquals($gm2id, $messages[2]->id);
2402 $this->assertEquals($gm3id, $messages[1]->id);
2403 $this->assertEquals($gm4id, $messages[0]->id);
2407 * Test retrieving conversation messages by providing a minimum timecreated value.
2409 public function test_get_conversation_messages_time_from_only() {
2410 // Create some users.
2411 $user1 = self::getDataGenerator()->create_user();
2412 $user2 = self::getDataGenerator()->create_user();
2413 $user3 = self::getDataGenerator()->create_user();
2414 $user4 = self::getDataGenerator()->create_user();
2416 // Create group conversation.
2417 $conversation = \core_message\api::create_conversation(
2418 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2419 [$user1->id, $user2->id, $user3->id, $user4->id]
2422 // The person doing the search.
2423 $this->setUser($user1);
2425 // Send some messages back and forth.
2427 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2428 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2429 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2430 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2432 // Retrieve the messages from $time, which should be all of them.
2433 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
2435 // Confirm the conversation id is correct.
2436 $this->assertEquals($conversation->id, $convmessages['id']);
2438 // Confirm the message data is correct.
2439 $messages = $convmessages['messages'];
2440 $this->assertEquals(4, count($messages));
2442 $message1 = $messages[0];
2443 $message2 = $messages[1];
2444 $message3 = $messages[2];
2445 $message4 = $messages[3];
2447 $this->assertContains('Message 1', $message1->text);
2448 $this->assertContains('Message 2', $message2->text);
2449 $this->assertContains('Message 3', $message3->text);
2450 $this->assertContains('Message 4', $message4->text);
2452 // Confirm the members data is correct.
2453 $members = $convmessages['members'];
2454 $this->assertEquals(3, count($members));
2456 // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2457 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2458 'timecreated ASC', $time + 3);
2460 // Confirm the conversation id is correct.
2461 $this->assertEquals($conversation->id, $convmessages['id']);
2463 // Confirm the message data is correct.
2464 $messages = $convmessages['messages'];
2465 $this->assertEquals(2, count($messages));
2467 $message1 = $messages[0];
2468 $message2 = $messages[1];
2470 $this->assertContains('Message 3', $message1->text);
2471 $this->assertContains('Message 4', $message2->text);
2473 // Confirm the members data is correct.
2474 $members = $convmessages['members'];
2475 $this->assertEquals(2, count($members));
2479 * Test retrieving conversation messages by providing a maximum timecreated value.
2481 public function test_get_conversation_messages_time_to_only() {
2482 // Create some users.
2483 $user1 = self::getDataGenerator()->create_user();
2484 $user2 = self::getDataGenerator()->create_user();
2485 $user3 = self::getDataGenerator()->create_user();
2486 $user4 = self::getDataGenerator()->create_user();
2488 // Create group conversation.
2489 $conversation = \core_message\api::create_conversation(
2490 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2491 [$user1->id, $user2->id, $user3->id, $user4->id]
2494 // The person doing the search.
2495 $this->setUser($user1);
2497 // Send some messages back and forth.
2499 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2500 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2501 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2502 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2504 // Retrieve the messages up until $time + 4, which should be all of them.
2505 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2508 // Confirm the conversation id is correct.
2509 $this->assertEquals($conversation->id, $convmessages['id']);
2511 // Confirm the message data is correct.
2512 $messages = $convmessages['messages'];
2513 $this->assertEquals(4, count($messages));
2515 $message1 = $messages[0];
2516 $message2 = $messages[1];
2517 $message3 = $messages[2];
2518 $message4 = $messages[3];
2520 $this->assertContains('Message 1', $message1->text);
2521 $this->assertContains('Message 2', $message2->text);
2522 $this->assertContains('Message 3', $message3->text);
2523 $this->assertContains('Message 4', $message4->text);
2525 // Confirm the members data is correct.
2526 $members = $convmessages['members'];
2527 $this->assertEquals(3, count($members));
2529 // Retrieve the messages up until $time + 2, which should be the first two.
2530 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2533 // Confirm the conversation id is correct.
2534 $this->assertEquals($conversation->id, $convmessages['id']);
2536 // Confirm the message data is correct.
2537 $messages = $convmessages['messages'];
2538 $this->assertEquals(2, count($messages));
2540 $message1 = $messages[0];
2541 $message2 = $messages[1];
2543 $this->assertContains('Message 1', $message1->text);
2544 $this->assertContains('Message 2', $message2->text);
2546 // Confirm the members data is correct.
2547 $members = $convmessages['members'];
2548 $this->assertEquals(2, count($members));
2552 * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
2554 public function test_get_conversation_messages_time_from_and_to() {
2555 // Create some users.
2556 $user1 = self::getDataGenerator()->create_user();
2557 $user2 = self::getDataGenerator()->create_user();
2558 $user3 = self::getDataGenerator()->create_user();
2559 $user4 = self::getDataGenerator()->create_user();
2561 // Create group conversation.
2562 $conversation = \core_message\api::create_conversation(
2563 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2564 [$user1->id, $user2->id, $user3->id, $user4->id]
2567 // The person doing the search.
2568 $this->setUser($user1);
2570 // Send some messages back and forth.
2572 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2573 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2574 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2575 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2577 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2578 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2579 'timecreated ASC', $time + 2, $time + 3);
2581 // Confirm the conversation id is correct.
2582 $this->assertEquals($conversation->id, $convmessages['id']);
2584 // Confirm the message data is correct.
2585 $messages = $convmessages['messages'];
2586 $this->assertEquals(2, count($messages));
2588 $message1 = $messages[0];
2589 $message2 = $messages[1];
2591 $this->assertContains('Message 2', $message1->text);
2592 $this->assertContains('Message 3', $message2->text);
2594 // Confirm the members data is correct.
2595 $members = $convmessages['members'];
2596 $this->assertEquals(2, count($members));
2601 * Test retrieving conversation messages by providing a limitfrom value.
2603 public function test_get_conversation_messages_limitfrom_only() {
2604 // Create some users.
2605 $user1 = self::getDataGenerator()->create_user();
2606 $user2 = self::getDataGenerator()->create_user();
2607 $user3 = self::getDataGenerator()->create_user();
2608 $user4 = self::getDataGenerator()->create_user();
2610 // Create group conversation.
2611 $conversation = \core_message\api::create_conversation(
2612 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2613 [$user1->id, $user2->id, $user3->id, $user4->id]
2616 // The person doing the search.
2617 $this->setUser($user1);
2619 // Send some messages back and forth.
2621 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2622 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2623 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2624 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2626 // Retrieve the messages from $time, which should be all of them.
2627 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
2629 // Confirm the conversation id is correct.
2630 $messages = $convmessages['messages'];
2631 $this->assertEquals($conversation->id, $convmessages['id']);
2633 // Confirm the message data is correct.
2634 $this->assertEquals(2, count($messages));
2636 $message1 = $messages[0];
2637 $message2 = $messages[1];
2639 $this->assertContains('Message 3', $message1->text);
2640 $this->assertContains('Message 4', $message2->text);
2642 // Confirm the members data is correct.
2643 $members = $convmessages['members'];
2644 $this->assertEquals(2, count($members));
2648 * Test retrieving conversation messages by providing a limitnum value.
2650 public function test_get_conversation_messages_limitnum() {
2651 // Create some users.
2652 $user1 = self::getDataGenerator()->create_user();
2653 $user2 = self::getDataGenerator()->create_user();
2654 $user3 = self::getDataGenerator()->create_user();
2655 $user4 = self::getDataGenerator()->create_user();
2657 // Create group conversation.
2658 $conversation = \core_message\api::create_conversation(
2659 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2660 [$user1->id, $user2->id, $user3->id, $user4->id]
2663 // The person doing the search.
2664 $this->setUser($user1);
2666 // Send some messages back and forth.
2668 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2669 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2670 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2671 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2673 // Retrieve the messages from $time, which should be all of them.
2674 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
2676 // Confirm the conversation id is correct.
2677 $messages = $convmessages['messages'];
2678 $this->assertEquals($conversation->id, $convmessages['id']);
2680 // Confirm the message data is correct.
2681 $messages = $convmessages['messages'];
2682 $this->assertEquals(1, count($messages));
2684 $message1 = $messages[0];
2686 $this->assertContains('Message 3', $message1->text);
2688 // Confirm the members data is correct.
2689 $members = $convmessages['members'];
2690 $this->assertEquals(1, count($members));
2694 * Tests retrieving most recent message.
2696 public function test_get_most_recent_message() {
2697 // Create some users.
2698 $user1 = self::getDataGenerator()->create_user();
2699 $user2 = self::getDataGenerator()->create_user();
2701 // The person doing the search.
2702 $this->setUser($user1);
2704 // Send some messages back and forth.
2706 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2707 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2708 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2709 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2711 // Retrieve the most recent messages.
2712 $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
2714 // Check the results are correct.
2715 $this->assertEquals($user2->id, $message->useridfrom);
2716 $this->assertEquals($user1->id, $message->useridto);
2717 $this->assertContains('Word.', $message->text);
2721 * Tests retrieving most recent conversation message.
2723 public function test_get_most_recent_conversation_message() {
2724 // Create some users.
2725 $user1 = self::getDataGenerator()->create_user();
2726 $user2 = self::getDataGenerator()->create_user();
2727 $user3 = self::getDataGenerator()->create_user();
2729 // Create group conversation.
2730 $conversation = \core_message\api::create_conversation(
2731 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2732 [$user1->id, $user2->id, $user3->id]
2735 // The person getting the most recent conversation message.
2736 $this->setUser($user1);
2738 // Send some messages back and forth.
2740 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2741 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2742 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2743 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2745 // Retrieve the most recent messages.
2746 $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
2748 // Check the results are correct.
2749 $this->assertEquals($user2->id, $message->useridfrom);
2750 $this->assertContains('Word.', $message->text);
2754 * Tests retrieving a user's profile.
2756 public function test_get_profile() {
2757 // Create some users.
2758 $user1 = self::getDataGenerator()->create_user();
2760 $user2 = new stdClass();
2761 $user2->country = 'AU';
2762 $user2->city = 'Perth';
2763 $user2 = self::getDataGenerator()->create_user($user2);
2765 // The person doing the search.
2766 $this->setUser($user1);
2769 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2771 $this->assertEquals($user2->id, $profile->userid);
2772 $this->assertEmpty($profile->email);
2773 $this->assertEmpty($profile->country);
2774 $this->assertEmpty($profile->city);
2775 $this->assertEquals(fullname($user2), $profile->fullname);
2776 $this->assertNull($profile->isonline);
2777 $this->assertFalse($profile->isblocked);
2778 $this->assertFalse($profile->iscontact);
2782 * Tests retrieving a user's profile.
2784 public function test_get_profile_as_admin() {
2785 // The person doing the search.
2786 $this->setAdminUser();
2788 // Create some users.
2789 $user1 = self::getDataGenerator()->create_user();
2791 $user2 = new stdClass();
2792 $user2->country = 'AU';
2793 $user2->city = 'Perth';
2794 $user2 = self::getDataGenerator()->create_user($user2);
2797 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2799 $this->assertEquals($user2->id, $profile->userid);
2800 $this->assertEquals($user2->email, $profile->email);
2801 $this->assertEquals($user2->country, $profile->country);
2802 $this->assertEquals($user2->city, $profile->city);
2803 $this->assertEquals(fullname($user2), $profile->fullname);
2804 $this->assertFalse($profile->isonline);
2805 $this->assertFalse($profile->isblocked);
2806 $this->assertFalse($profile->iscontact);
2810 * Tests checking if a user can mark all messages as read.
2812 public function test_can_mark_all_messages_as_read() {
2813 // Set as the admin.
2814 $this->setAdminUser();
2816 // Create some users.
2817 $user1 = self::getDataGenerator()->create_user();
2818 $user2 = self::getDataGenerator()->create_user();
2819 $user3 = self::getDataGenerator()->create_user();
2821 // Send some messages back and forth.
2823 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2824 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2825 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2826 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2828 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2830 // The admin can do anything.
2831 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2833 // Set as the user 1.
2834 $this->setUser($user1);
2836 // The user can mark the messages as he is in the conversation.
2837 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2839 // User 1 can not mark the messages read for user 2.
2840 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
2842 // This user is not a part of the conversation.
2843 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
2847 * Tests checking if a user can delete a conversation.
2849 public function test_can_delete_conversation() {
2850 // Set as the admin.
2851 $this->setAdminUser();
2853 // Create some users.
2854 $user1 = self::getDataGenerator()->create_user();
2855 $user2 = self::getDataGenerator()->create_user();
2857 // Send some messages back and forth.
2859 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2860 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2861 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2862 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2864 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2866 // The admin can do anything.
2867 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2869 // Set as the user 1.
2870 $this->setUser($user1);
2872 // They can delete their own messages.
2873 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2875 // They can't delete someone elses.
2876 $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
2880 * Tests deleting a conversation.
2882 public function test_delete_conversation() {
2885 // Create some users.
2886 $user1 = self::getDataGenerator()->create_user();
2887 $user2 = self::getDataGenerator()->create_user();
2889 // The person doing the search.
2890 $this->setUser($user1);
2892 // Send some messages back and forth.
2894 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2895 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2896 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2897 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2899 // Delete the conversation as user 1.
2900 \core_message\api::delete_conversation($user1->id, $user2->id);
2901 $this->assertDebuggingCalled();
2903 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2904 $this->assertCount(4, $muas);
2908 $mua1 = array_shift($muas);
2909 $mua2 = array_shift($muas);
2910 $mua3 = array_shift($muas);
2911 $mua4 = array_shift($muas);
2913 $this->assertEquals($user1->id, $mua1->userid);
2914 $this->assertEquals($m1id, $mua1->messageid);
2915 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2917 $this->assertEquals($user1->id, $mua2->userid);
2918 $this->assertEquals($m2id, $mua2->messageid);
2919 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2921 $this->assertEquals($user1->id, $mua3->userid);
2922 $this->assertEquals($m3id, $mua3->messageid);
2923 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2925 $this->assertEquals($user1->id, $mua4->userid);
2926 $this->assertEquals($m4id, $mua4->messageid);
2927 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2931 * Tests deleting a conversation by conversation id.
2933 public function test_delete_conversation_by_id() {
2936 // Create some users.
2937 $user1 = self::getDataGenerator()->create_user();
2938 $user2 = self::getDataGenerator()->create_user();
2940 // The person doing the search.
2941 $this->setUser($user1);
2943 // Send some messages back and forth.
2945 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2946 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2947 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2948 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2950 // Delete the conversation as user 1.
2951 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2952 \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2954 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2955 $this->assertCount(4, $muas);
2959 $mua1 = array_shift($muas);
2960 $mua2 = array_shift($muas);
2961 $mua3 = array_shift($muas);
2962 $mua4 = array_shift($muas);
2964 $this->assertEquals($user1->id, $mua1->userid);
2965 $this->assertEquals($m1id, $mua1->messageid);
2966 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2968 $this->assertEquals($user1->id, $mua2->userid);
2969 $this->assertEquals($m2id, $mua2->messageid);
2970 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2972 $this->assertEquals($user1->id, $mua3->userid);
2973 $this->assertEquals($m3id, $mua3->messageid);
2974 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2976 $this->assertEquals($user1->id, $mua4->userid);
2977 $this->assertEquals($m4id, $mua4->messageid);
2978 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2982 * Tests counting unread conversations.
2984 public function test_count_unread_conversations() {
2985 $this->resetAfterTest(true);
2987 // Create some users.
2988 $user1 = self::getDataGenerator()->create_user();
2989 $user2 = self::getDataGenerator()->create_user();
2990 $user3 = self::getDataGenerator()->create_user();
2991 $user4 = self::getDataGenerator()->create_user();
2993 // The person wanting the conversation count.
2994 $this->setUser($user1);
2996 // Send some messages back and forth, have some different conversations with different users.
2997 $this->send_fake_message($user1, $user2, 'Yo!');
2998 $this->send_fake_message($user2, $user1, 'Sup mang?');
2999 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
3000 $this->send_fake_message($user2, $user1, 'Word.');
3002 $this->send_fake_message($user1, $user3, 'Booyah');
3003 $this->send_fake_message($user3, $user1, 'Whaaat?');
3004 $this->send_fake_message($user1, $user3, 'Nothing.');
3005 $this->send_fake_message($user3, $user1, 'Cool.');
3007 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
3008 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
3009 $this->send_fake_message($user1, $user4, 'Dope.');
3011 // Check the amount for the current user.
3012 $this->assertEquals(3, core_message\api::count_unread_conversations());
3014 // Check the amount for the second user.
3015 $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
3019 * Tests deleting a conversation.
3021 public function test_get_all_message_preferences() {
3022 $user = self::getDataGenerator()->create_user();
3023 $this->setUser($user);
3025 // Set a couple of preferences to test.
3026 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
3027 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
3029 $processors = get_message_processors();
3030 $providers = message_get_providers_for_user($user->id);
3031 $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
3033 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
3034 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
3038 * Tests the user can post a message.
3040 public function test_can_post_message() {
3041 // Create some users.
3042 $user1 = self::getDataGenerator()->create_user();
3043 $user2 = self::getDataGenerator()->create_user();
3045 // Set as the first user.
3046 $this->setUser($user1);
3048 // With the default privacy setting, users can't message them.
3049 $this->assertFalse(\core_message\api::can_post_message($user2));
3051 // Enrol users to the same course.
3052 $course = $this->getDataGenerator()->create_course();
3053 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3054 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3055 // After enrolling users to the course, they should be able to message them with the default privacy setting.
3056 $this->assertTrue(\core_message\api::can_post_message($user2));
3060 * Tests the user can't post a message without proper capability.
3062 public function test_can_post_message_without_sendmessage_cap() {
3065 // Create some users.
3066 $user1 = self::getDataGenerator()->create_user();
3067 $user2 = self::getDataGenerator()->create_user();
3069 // Set as the user 1.
3070 $this->setUser($user1);
3072 // Remove the capability to send a message.
3073 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3074 unassign_capability('moodle/site:sendmessage', $roleids['user'],
3075 context_system::instance());
3077 // Check that we can not post a message without the capability.
3078 $this->assertFalse(\core_message\api::can_post_message($user2));
3082 * Tests the user can post a message when they are contact.
3084 public function test_can_post_message_when_contact() {
3085 // Create some users.
3086 $user1 = self::getDataGenerator()->create_user();
3087 $user2 = self::getDataGenerator()->create_user();
3089 // Set as the first user.
3090 $this->setUser($user1);
3092 // Check that we can not send user2 a message.
3093 $this->assertFalse(\core_message\api::can_post_message($user2));
3095 // Add users as contacts.
3096 \core_message\api::add_contact($user1->id, $user2->id);
3098 // Check that the return result is now true.
3099 $this->assertTrue(\core_message\api::can_post_message($user2));
3103 * Tests the user can't post a message if they are not a contact and the user
3104 * has requested messages only from contacts.
3106 public function test_can_post_message_when_not_contact() {
3107 // Create some users.
3108 $user1 = self::getDataGenerator()->create_user();
3109 $user2 = self::getDataGenerator()->create_user();
3111 // Set as the first user.
3112 $this->setUser($user1);
3114 // Set the second user's preference to not receive messages from non-contacts.
3115 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3117 // Check that we can not send user 2 a message.
3118 $this->assertFalse(\core_message\api::can_post_message($user2));
3122 * Tests the user can't post a message if they are blocked.
3124 public function test_can_post_message_when_blocked() {
3125 // Create some users.
3126 $user1 = self::getDataGenerator()->create_user();
3127 $user2 = self::getDataGenerator()->create_user();
3130 $this->setUser($user1);
3132 // Block the second user.
3133 \core_message\api::block_user($user1->id, $user2->id);
3135 // Check that the second user can no longer send the first user a message.
3136 $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
3140 * Tests the user can post a message when site-wide messaging setting is enabled,
3141 * even if they are not a contact and are not members of the same course.
3143 public function test_can_post_message_site_messaging_setting() {
3144 // Create some users.
3145 $user1 = self::getDataGenerator()->create_user();
3146 $user2 = self::getDataGenerator()->create_user();
3148 // Set as the first user.
3149 $this->setUser($user1);
3151 // By default, user only can be messaged by contacts and members of any of his/her courses.
3152 $this->assertFalse(\core_message\api::can_post_message($user2));
3154 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3155 set_config('messagingallusers', true);
3157 // Set the second user's preference to receive messages from everybody.
3158 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
3160 // Check that we can send user2 a message.
3161 $this->assertTrue(\core_message\api::can_post_message($user2));
3163 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3164 // and members sharing a course with her.
3165 set_config('messagingallusers', false);
3167 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3168 $this->assertFalse(\core_message\api::can_post_message($user2));
3170 // Enrol users to the same course.
3171 $course = $this->getDataGenerator()->create_course();
3172 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3173 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3174 // Check that we can send user2 a message because they are sharing a course.
3175 $this->assertTrue(\core_message\api::can_post_message($user2));
3177 // Set the second user's preference to receive messages only from contacts.
3178 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3179 // Check that now the user2 can't be contacted because user1 is not their contact.
3180 $this->assertFalse(\core_message\api::can_post_message($user2));
3182 // Make contacts user1 and user2.
3183 \core_message\api::add_contact($user2->id, $user1->id);
3184 // Check that we can send user2 a message because they are contacts.
3185 $this->assertTrue(\core_message\api::can_post_message($user2));
3189 * Tests the user with the messageanyuser capability can post a message.
3191 public function test_can_post_message_with_messageanyuser_cap() {
3194 // Create some users.
3195 $teacher1 = self::getDataGenerator()->create_user();
3196 $student1 = self::getDataGenerator()->create_user();
3197 $student2 = self::getDataGenerator()->create_user();
3199 // Create users not enrolled in any course.
3200 $user1 = self::getDataGenerator()->create_user();
3203 $course1 = $this->getDataGenerator()->create_course();
3205 // Enrol the users in the course.
3206 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
3207 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
3208 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
3210 // Set some student preferences to not receive messages from non-contacts.
3211 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
3213 // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
3214 $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
3215 // Check that the teacher can't contact user1 because it's not his teacher.
3216 $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
3218 // Remove the messageanyuser capability from the course1 for teachers.
3219 $coursecontext = context_course::instance($course1->id);
3220 $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
3221 assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
3222 $coursecontext->mark_dirty();
3224 // Check that we can't send user1 a message because they are not contacts.
3225 $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
3226 // However, teacher can message student2 because they are sharing a course.
3227 $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
3231 * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings.
3233 public function test_can_send_message_to_conversation_basic() {
3234 // Create some users.
3235 $user1 = self::getDataGenerator()->create_user();
3236 $user2 = self::getDataGenerator()->create_user();
3237 $user3 = self::getDataGenerator()->create_user();
3239 // Create an individual conversation between user1 and user2.
3240 $ic1 = \core_message\api::create_conversation(
3241 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3248 // Create a group conversation between and users 1, 2 and 3.
3249 $gc1 = \core_message\api::create_conversation(
3250 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3258 // For group conversations, there are no user privacy checks, so only membership in the conversation is needed.
3259 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3261 // For individual conversations, the default privacy setting of 'only contacts and course members' applies.
3262 // Users are not in the same course, nor are they contacts, so messages cannot be sent.
3263 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3265 // Enrol the users into the same course.
3266 $course = $this->getDataGenerator()->create_course();
3267 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3268 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3270 // After enrolling users to the course, they should be able to message them with the default privacy setting.
3271 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3275 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability.
3277 public function test_can_send_message_to_conversation_sendmessage_cap() {
3280 $user1 = self::getDataGenerator()->create_user();
3281 $user2 = self::getDataGenerator()->create_user();
3282 $user3 = self::getDataGenerator()->create_user();
3284 // Enrol the users into the same course.
3285 $course = $this->getDataGenerator()->create_course();
3286 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3287 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3288 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3290 // Create an individual conversation between user1 and user2.
3291 $ic1 = \core_message\api::create_conversation(
3292 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,